Merge
This commit is contained in:
commit
7a2be4b65b
@ -363,3 +363,4 @@ e882bcdbdac436523f3d5681611d3118a3804ea7 jdk-9+117
|
|||||||
047f95de8f918d8ff5e8cd2636a2abb5c3c8adb8 jdk-9+118
|
047f95de8f918d8ff5e8cd2636a2abb5c3c8adb8 jdk-9+118
|
||||||
3463a3f14f0f0e8a68f29ac6405454f2fa2f598a jdk-9+119
|
3463a3f14f0f0e8a68f29ac6405454f2fa2f598a jdk-9+119
|
||||||
647e0142a5a52749db572b5e6638d561def6479e jdk-9+120
|
647e0142a5a52749db572b5e6638d561def6479e jdk-9+120
|
||||||
|
cae471d3b87783e0a3deea658e1e1c84b2485b6c jdk-9+121
|
||||||
|
6
LICENSE
6
LICENSE
@ -3,7 +3,7 @@ The GNU General Public License (GPL)
|
|||||||
Version 2, June 1991
|
Version 2, June 1991
|
||||||
|
|
||||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||||
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
Everyone is permitted to copy and distribute verbatim copies of this license
|
Everyone is permitted to copy and distribute verbatim copies of this license
|
||||||
document, but changing it is not allowed.
|
document, but changing it is not allowed.
|
||||||
@ -287,8 +287,8 @@ pointer to where the full notice is found.
|
|||||||
more details.
|
more details.
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License along
|
You should have received a copy of the GNU General Public License along
|
||||||
with this program; if not, write to the Free Software Foundation, Inc., 59
|
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
|
||||||
Also add information on how to contact you by electronic and paper mail.
|
Also add information on how to contact you by electronic and paper mail.
|
||||||
|
|
||||||
|
@ -318,7 +318,8 @@ var getJibProfilesProfiles = function (input, common) {
|
|||||||
},
|
},
|
||||||
|
|
||||||
"linux-x86-open": {
|
"linux-x86-open": {
|
||||||
default_make_targets: "profiles"
|
default_make_targets: "profiles",
|
||||||
|
configure_args: "--with-jvm-variants=client,server"
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
var openOnlyProfiles = concatObjects(openOnlyProfiles, openOnlyProfilesExtra);
|
var openOnlyProfiles = concatObjects(openOnlyProfiles, openOnlyProfilesExtra);
|
||||||
|
@ -363,3 +363,4 @@ cc30faa2da498c478e89ab062ff160653ca1b170 jdk-9+113
|
|||||||
8c2c2d17f7ce92a31c9ccb44a122ec62f5a85ace jdk-9+118
|
8c2c2d17f7ce92a31c9ccb44a122ec62f5a85ace jdk-9+118
|
||||||
daf533920b1266603b5cbdab31908d2a931c5361 jdk-9+119
|
daf533920b1266603b5cbdab31908d2a931c5361 jdk-9+119
|
||||||
5943b791e131e79b969d4cea053aecda34801723 jdk-9+120
|
5943b791e131e79b969d4cea053aecda34801723 jdk-9+120
|
||||||
|
9a5fc5a27560ac272c1341f8f3838338fba49059 jdk-9+121
|
||||||
|
@ -3,7 +3,7 @@ The GNU General Public License (GPL)
|
|||||||
Version 2, June 1991
|
Version 2, June 1991
|
||||||
|
|
||||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||||
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
Everyone is permitted to copy and distribute verbatim copies of this license
|
Everyone is permitted to copy and distribute verbatim copies of this license
|
||||||
document, but changing it is not allowed.
|
document, but changing it is not allowed.
|
||||||
@ -287,8 +287,8 @@ pointer to where the full notice is found.
|
|||||||
more details.
|
more details.
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License along
|
You should have received a copy of the GNU General Public License along
|
||||||
with this program; if not, write to the Free Software Foundation, Inc., 59
|
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
|
||||||
Also add information on how to contact you by electronic and paper mail.
|
Also add information on how to contact you by electronic and paper mail.
|
||||||
|
|
||||||
|
@ -523,3 +523,4 @@ b64432bae5271735fd53300b2005b713e98ef411 jdk-9+114
|
|||||||
9b1075cac08dc836ec32e7b368415cbe3aceaf8c jdk-9+118
|
9b1075cac08dc836ec32e7b368415cbe3aceaf8c jdk-9+118
|
||||||
15f3fe264872766bcb205696198f0c1502420e17 jdk-9+119
|
15f3fe264872766bcb205696198f0c1502420e17 jdk-9+119
|
||||||
0be6f4f5d18671184e62583668cb1d783dffa128 jdk-9+120
|
0be6f4f5d18671184e62583668cb1d783dffa128 jdk-9+120
|
||||||
|
7e293105dbb0789a468655f81320c891f491f371 jdk-9+121
|
||||||
|
@ -144,42 +144,6 @@ def isJVMCIEnabled(vm):
|
|||||||
assert vm in _jdkJvmVariants
|
assert vm in _jdkJvmVariants
|
||||||
return True
|
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():
|
def _makehelp():
|
||||||
return subprocess.check_output([mx.gmake_cmd(), 'help'], cwd=_jdkSourceRoot)
|
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
|
# JDK9 must be bootstrapped with a JDK8
|
||||||
compliance = mx.JavaCompliance('8')
|
compliance = mx.JavaCompliance('8')
|
||||||
jdk8 = mx.get_jdk(compliance.exactMatch, versionDescription=compliance.value)
|
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]
|
'--with-jvm-variants=' + _vm.jvmVariant, '--disable-warnings-as-errors', '--with-boot-jdk=' + jdk8.home]
|
||||||
mx.run(cmd, cwd=_jdkSourceRoot)
|
mx.run(cmd, cwd=_jdkSourceRoot)
|
||||||
cmd = [mx.gmake_cmd(), 'CONF=' + _vm.debugLevel]
|
cmd = [mx.gmake_cmd(), 'CONF=' + _vm.debugLevel]
|
||||||
@ -217,6 +181,9 @@ 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 OpenJDK build creates an empty cacerts file so copy one from
|
||||||
# the default JDK (which is assumed to be an OracleJDK)
|
# the default JDK (which is assumed to be an OracleJDK)
|
||||||
|
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')
|
srcCerts = join(mx.get_jdk(tag='default').home, 'jre', 'lib', 'security', 'cacerts')
|
||||||
dstCerts = join(jdkImageDir, 'lib', 'security', 'cacerts')
|
dstCerts = join(jdkImageDir, 'lib', 'security', 'cacerts')
|
||||||
shutil.copyfile(srcCerts, dstCerts)
|
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)
|
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():
|
def _get_openjdk_os():
|
||||||
# See: common/autoconf/platform.m4
|
# See: common/autoconf/platform.m4
|
||||||
os = mx.get_os()
|
os = mx.get_os()
|
||||||
@ -744,10 +693,6 @@ def _get_hotspot_build_dir(jvmVariant=None, debugLevel=None):
|
|||||||
name = '{}_{}_{}'.format(os, arch, buildname)
|
name = '{}_{}_{}'.format(os, arch, buildname)
|
||||||
return join(_get_jdk_build_dir(debugLevel=debugLevel), 'hotspot', name)
|
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):
|
class JVMCI9JDKConfig(mx.JDKConfig):
|
||||||
def __init__(self, debugLevel):
|
def __init__(self, debugLevel):
|
||||||
self.debugLevel = 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])
|
cp = os.pathsep.join([e for e in cp.split(os.pathsep) if e not in excluded])
|
||||||
args[cpIndex] = cp
|
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:
|
if '-version' in args:
|
||||||
ignoredArgs = args[args.index('-version') + 1:]
|
ignoredArgs = args[args.index('-version') + 1:]
|
||||||
if len(ignoredArgs) > 0:
|
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 + '"')
|
mx.warn('Ignoring "--jvmci-mode" option as "--jdk" tag is not "' + _JVMCI_JDK_TAG + '"')
|
||||||
|
|
||||||
_vm.update(jvmVariant, debugLevel, jvmciMode)
|
_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()
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
suite = {
|
suite = {
|
||||||
"mxversion" : "5.6.16",
|
"mxversion" : "5.23.1",
|
||||||
"name" : "jvmci",
|
"name" : "jvmci",
|
||||||
"url" : "http://openjdk.java.net/projects/graal",
|
"url" : "http://openjdk.java.net/projects/graal",
|
||||||
"developer" : {
|
"developer" : {
|
||||||
@ -36,13 +36,6 @@ suite = {
|
|||||||
"urls" : ["http://central.maven.org/maven2/org/testng/testng/6.9.10/testng-6.9.10.jar"],
|
"urls" : ["http://central.maven.org/maven2/org/testng/testng/6.9.10/testng-6.9.10.jar"],
|
||||||
"sha1" : "6feb3e964aeb7097aff30c372aac3ec0f8d87ede",
|
"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" : {
|
"projects" : {
|
||||||
@ -52,7 +45,7 @@ suite = {
|
|||||||
"jdk.vm.ci.services" : {
|
"jdk.vm.ci.services" : {
|
||||||
"subDir" : "src/jdk.vm.ci/share/classes",
|
"subDir" : "src/jdk.vm.ci/share/classes",
|
||||||
"sourceDirs" : ["src"],
|
"sourceDirs" : ["src"],
|
||||||
"javaCompliance" : "1.8",
|
"javaCompliance" : "9",
|
||||||
"workingSets" : "API,JVMCI",
|
"workingSets" : "API,JVMCI",
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -62,7 +55,7 @@ suite = {
|
|||||||
"subDir" : "src/jdk.vm.ci/share/classes",
|
"subDir" : "src/jdk.vm.ci/share/classes",
|
||||||
"sourceDirs" : ["src"],
|
"sourceDirs" : ["src"],
|
||||||
"checkstyle" : "jdk.vm.ci.services",
|
"checkstyle" : "jdk.vm.ci.services",
|
||||||
"javaCompliance" : "1.8",
|
"javaCompliance" : "9",
|
||||||
"workingSets" : "API,JVMCI",
|
"workingSets" : "API,JVMCI",
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -70,7 +63,7 @@ suite = {
|
|||||||
"subDir" : "src/jdk.vm.ci/share/classes",
|
"subDir" : "src/jdk.vm.ci/share/classes",
|
||||||
"sourceDirs" : ["src"],
|
"sourceDirs" : ["src"],
|
||||||
"checkstyle" : "jdk.vm.ci.services",
|
"checkstyle" : "jdk.vm.ci.services",
|
||||||
"javaCompliance" : "1.8",
|
"javaCompliance" : "9",
|
||||||
"workingSets" : "API,JVMCI",
|
"workingSets" : "API,JVMCI",
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -79,7 +72,7 @@ suite = {
|
|||||||
"sourceDirs" : ["src"],
|
"sourceDirs" : ["src"],
|
||||||
"dependencies" : ["jdk.vm.ci.meta"],
|
"dependencies" : ["jdk.vm.ci.meta"],
|
||||||
"checkstyle" : "jdk.vm.ci.services",
|
"checkstyle" : "jdk.vm.ci.services",
|
||||||
"javaCompliance" : "1.8",
|
"javaCompliance" : "9",
|
||||||
"workingSets" : "API,JVMCI",
|
"workingSets" : "API,JVMCI",
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -94,7 +87,7 @@ suite = {
|
|||||||
"jdk.vm.ci.hotspot",
|
"jdk.vm.ci.hotspot",
|
||||||
],
|
],
|
||||||
"checkstyle" : "jdk.vm.ci.services",
|
"checkstyle" : "jdk.vm.ci.services",
|
||||||
"javaCompliance" : "1.8",
|
"javaCompliance" : "9",
|
||||||
"workingSets" : "API,JVMCI",
|
"workingSets" : "API,JVMCI",
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -103,9 +96,10 @@ suite = {
|
|||||||
"sourceDirs" : ["src"],
|
"sourceDirs" : ["src"],
|
||||||
"dependencies" : [
|
"dependencies" : [
|
||||||
"jdk.vm.ci.code",
|
"jdk.vm.ci.code",
|
||||||
|
"jdk.vm.ci.services",
|
||||||
],
|
],
|
||||||
"checkstyle" : "jdk.vm.ci.services",
|
"checkstyle" : "jdk.vm.ci.services",
|
||||||
"javaCompliance" : "1.8",
|
"javaCompliance" : "9",
|
||||||
"workingSets" : "API,JVMCI",
|
"workingSets" : "API,JVMCI",
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -118,18 +112,10 @@ suite = {
|
|||||||
"jdk.vm.ci.runtime",
|
"jdk.vm.ci.runtime",
|
||||||
],
|
],
|
||||||
"checkstyle" : "jdk.vm.ci.services",
|
"checkstyle" : "jdk.vm.ci.services",
|
||||||
"javaCompliance" : "1.8",
|
"javaCompliance" : "9",
|
||||||
"workingSets" : "API,JVMCI",
|
"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 -------------
|
# ------------- JVMCI:HotSpot -------------
|
||||||
|
|
||||||
"jdk.vm.ci.aarch64" : {
|
"jdk.vm.ci.aarch64" : {
|
||||||
@ -137,7 +123,7 @@ suite = {
|
|||||||
"sourceDirs" : ["src"],
|
"sourceDirs" : ["src"],
|
||||||
"dependencies" : ["jdk.vm.ci.code"],
|
"dependencies" : ["jdk.vm.ci.code"],
|
||||||
"checkstyle" : "jdk.vm.ci.services",
|
"checkstyle" : "jdk.vm.ci.services",
|
||||||
"javaCompliance" : "1.8",
|
"javaCompliance" : "9",
|
||||||
"workingSets" : "JVMCI,AArch64",
|
"workingSets" : "JVMCI,AArch64",
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -146,7 +132,7 @@ suite = {
|
|||||||
"sourceDirs" : ["src"],
|
"sourceDirs" : ["src"],
|
||||||
"dependencies" : ["jdk.vm.ci.code"],
|
"dependencies" : ["jdk.vm.ci.code"],
|
||||||
"checkstyle" : "jdk.vm.ci.services",
|
"checkstyle" : "jdk.vm.ci.services",
|
||||||
"javaCompliance" : "1.8",
|
"javaCompliance" : "9",
|
||||||
"workingSets" : "JVMCI,AMD64",
|
"workingSets" : "JVMCI,AMD64",
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -155,7 +141,7 @@ suite = {
|
|||||||
"sourceDirs" : ["src"],
|
"sourceDirs" : ["src"],
|
||||||
"dependencies" : ["jdk.vm.ci.code"],
|
"dependencies" : ["jdk.vm.ci.code"],
|
||||||
"checkstyle" : "jdk.vm.ci.services",
|
"checkstyle" : "jdk.vm.ci.services",
|
||||||
"javaCompliance" : "1.8",
|
"javaCompliance" : "9",
|
||||||
"workingSets" : "JVMCI,SPARC",
|
"workingSets" : "JVMCI,SPARC",
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -165,13 +151,15 @@ suite = {
|
|||||||
"dependencies" : [
|
"dependencies" : [
|
||||||
"jdk.vm.ci.hotspotvmconfig",
|
"jdk.vm.ci.hotspotvmconfig",
|
||||||
"jdk.vm.ci.common",
|
"jdk.vm.ci.common",
|
||||||
"jdk.vm.ci.inittimer",
|
|
||||||
"jdk.vm.ci.runtime",
|
"jdk.vm.ci.runtime",
|
||||||
"jdk.vm.ci.services",
|
"jdk.vm.ci.services",
|
||||||
"JDK9_STUBS",
|
],
|
||||||
|
"imports" : [
|
||||||
|
"jdk.internal.misc",
|
||||||
|
"jdk.internal.org.objectweb.asm",
|
||||||
],
|
],
|
||||||
"checkstyle" : "jdk.vm.ci.services",
|
"checkstyle" : "jdk.vm.ci.services",
|
||||||
"javaCompliance" : "1.8",
|
"javaCompliance" : "9",
|
||||||
"workingSets" : "JVMCI",
|
"workingSets" : "JVMCI",
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -183,7 +171,7 @@ suite = {
|
|||||||
"jdk.vm.ci.hotspot",
|
"jdk.vm.ci.hotspot",
|
||||||
],
|
],
|
||||||
"checkstyle" : "jdk.vm.ci.services",
|
"checkstyle" : "jdk.vm.ci.services",
|
||||||
"javaCompliance" : "1.8",
|
"javaCompliance" : "9",
|
||||||
"workingSets" : "API,JVMCI",
|
"workingSets" : "API,JVMCI",
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -191,7 +179,7 @@ suite = {
|
|||||||
"subDir" : "src/jdk.vm.ci/share/classes",
|
"subDir" : "src/jdk.vm.ci/share/classes",
|
||||||
"sourceDirs" : ["src"],
|
"sourceDirs" : ["src"],
|
||||||
"checkstyle" : "jdk.vm.ci.services",
|
"checkstyle" : "jdk.vm.ci.services",
|
||||||
"javaCompliance" : "1.8",
|
"javaCompliance" : "9",
|
||||||
"workingSets" : "JVMCI,HotSpot",
|
"workingSets" : "JVMCI,HotSpot",
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -203,7 +191,7 @@ suite = {
|
|||||||
"jdk.vm.ci.hotspot",
|
"jdk.vm.ci.hotspot",
|
||||||
],
|
],
|
||||||
"checkstyle" : "jdk.vm.ci.services",
|
"checkstyle" : "jdk.vm.ci.services",
|
||||||
"javaCompliance" : "1.8",
|
"javaCompliance" : "9",
|
||||||
"workingSets" : "JVMCI,HotSpot,AArch64",
|
"workingSets" : "JVMCI,HotSpot,AArch64",
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -215,7 +203,7 @@ suite = {
|
|||||||
"jdk.vm.ci.hotspot",
|
"jdk.vm.ci.hotspot",
|
||||||
],
|
],
|
||||||
"checkstyle" : "jdk.vm.ci.services",
|
"checkstyle" : "jdk.vm.ci.services",
|
||||||
"javaCompliance" : "1.8",
|
"javaCompliance" : "9",
|
||||||
"workingSets" : "JVMCI,HotSpot,AMD64",
|
"workingSets" : "JVMCI,HotSpot,AMD64",
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -227,7 +215,7 @@ suite = {
|
|||||||
"jdk.vm.ci.hotspot",
|
"jdk.vm.ci.hotspot",
|
||||||
],
|
],
|
||||||
"checkstyle" : "jdk.vm.ci.services",
|
"checkstyle" : "jdk.vm.ci.services",
|
||||||
"javaCompliance" : "1.8",
|
"javaCompliance" : "9",
|
||||||
"workingSets" : "JVMCI,HotSpot,SPARC",
|
"workingSets" : "JVMCI,HotSpot,SPARC",
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -249,7 +237,6 @@ suite = {
|
|||||||
"JVMCI_API" : {
|
"JVMCI_API" : {
|
||||||
"subDir" : "src/jdk.vm.ci/share/classes",
|
"subDir" : "src/jdk.vm.ci/share/classes",
|
||||||
"dependencies" : [
|
"dependencies" : [
|
||||||
"jdk.vm.ci.inittimer",
|
|
||||||
"jdk.vm.ci.runtime",
|
"jdk.vm.ci.runtime",
|
||||||
"jdk.vm.ci.common",
|
"jdk.vm.ci.common",
|
||||||
"jdk.vm.ci.aarch64",
|
"jdk.vm.ci.aarch64",
|
||||||
@ -292,31 +279,5 @@ suite = {
|
|||||||
],
|
],
|
||||||
"exclude" : ["mx:JUNIT"],
|
"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"]
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@ The GNU General Public License (GPL)
|
|||||||
Version 2, June 1991
|
Version 2, June 1991
|
||||||
|
|
||||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||||
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
Everyone is permitted to copy and distribute verbatim copies of this license
|
Everyone is permitted to copy and distribute verbatim copies of this license
|
||||||
document, but changing it is not allowed.
|
document, but changing it is not allowed.
|
||||||
@ -287,8 +287,8 @@ pointer to where the full notice is found.
|
|||||||
more details.
|
more details.
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License along
|
You should have received a copy of the GNU General Public License along
|
||||||
with this program; if not, write to the Free Software Foundation, Inc., 59
|
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
|
||||||
Also add information on how to contact you by electronic and paper mail.
|
Also add information on how to contact you by electronic and paper mail.
|
||||||
|
|
||||||
|
@ -36,9 +36,6 @@ endif
|
|||||||
|
|
||||||
################################################################################
|
################################################################################
|
||||||
|
|
||||||
GTEST_TEST_SRC_FILES := $(shell $(FIND) $(HOTSPOT_TOPDIR)/test/native -name \
|
|
||||||
"test*.cpp" -type f)
|
|
||||||
|
|
||||||
ifeq ($(OPENJDK_TARGET_OS), windows)
|
ifeq ($(OPENJDK_TARGET_OS), windows)
|
||||||
GTEST_JVM_MAPFILE := $(JVM_MAPFILE)
|
GTEST_JVM_MAPFILE := $(JVM_MAPFILE)
|
||||||
else
|
else
|
||||||
@ -58,10 +55,12 @@ $(eval $(call SetupNativeCompilation, BUILD_GTEST_LIBJVM, \
|
|||||||
TOOLCHAIN := $(JVM_TOOLCHAIN), \
|
TOOLCHAIN := $(JVM_TOOLCHAIN), \
|
||||||
LIBRARY := jvm, \
|
LIBRARY := jvm, \
|
||||||
OUTPUT_DIR := $(JVM_OUTPUTDIR)/gtest, \
|
OUTPUT_DIR := $(JVM_OUTPUTDIR)/gtest, \
|
||||||
EXTRA_FILES := $(GTEST_TEST_SRC_FILES) \
|
|
||||||
$(GTEST_FRAMEWORK_SRC)/src/gtest-all.cc \
|
|
||||||
$(GTEST_TEST_SRC)/gtestMain.cpp, \
|
|
||||||
OBJECT_DIR := $(JVM_OUTPUTDIR)/gtest/objs, \
|
OBJECT_DIR := $(JVM_OUTPUTDIR)/gtest/objs, \
|
||||||
|
SRC := $(GTEST_TEST_SRC), \
|
||||||
|
EXCLUDES := $(JVM_EXCLUDES), \
|
||||||
|
EXCLUDE_FILES := gtestLauncher.cpp, \
|
||||||
|
EXCLUDE_PATTERNS := $(JVM_EXCLUDE_PATTERNS), \
|
||||||
|
EXTRA_FILES := $(GTEST_FRAMEWORK_SRC)/src/gtest-all.cc, \
|
||||||
EXTRA_OBJECT_FILES := $(filter-out %/operator_new$(OBJ_SUFFIX), \
|
EXTRA_OBJECT_FILES := $(filter-out %/operator_new$(OBJ_SUFFIX), \
|
||||||
$(BUILD_LIBJVM_ALL_OBJS)), \
|
$(BUILD_LIBJVM_ALL_OBJS)), \
|
||||||
CFLAGS := $(JVM_CFLAGS) -I$(GTEST_FRAMEWORK_SRC) \
|
CFLAGS := $(JVM_CFLAGS) -I$(GTEST_FRAMEWORK_SRC) \
|
||||||
|
@ -3331,7 +3331,6 @@ const bool Matcher::match_rule_supported(int opcode) {
|
|||||||
|
|
||||||
switch (opcode) {
|
switch (opcode) {
|
||||||
case Op_StrComp:
|
case Op_StrComp:
|
||||||
case Op_StrIndexOf:
|
|
||||||
if (CompactStrings) return false;
|
if (CompactStrings) return false;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -4744,6 +4743,7 @@ encode %{
|
|||||||
__ br(Assembler::EQ, cont);
|
__ br(Assembler::EQ, cont);
|
||||||
} else {
|
} else {
|
||||||
Label retry_load;
|
Label retry_load;
|
||||||
|
if ((VM_Version::features() & VM_Version::CPU_STXR_PREFETCH))
|
||||||
__ prfm(Address(oop), PSTL1STRM);
|
__ prfm(Address(oop), PSTL1STRM);
|
||||||
__ bind(retry_load);
|
__ bind(retry_load);
|
||||||
__ ldaxr(tmp, oop);
|
__ ldaxr(tmp, oop);
|
||||||
@ -4799,6 +4799,7 @@ encode %{
|
|||||||
__ cmp(rscratch1, disp_hdr);
|
__ cmp(rscratch1, disp_hdr);
|
||||||
} else {
|
} else {
|
||||||
Label retry_load, fail;
|
Label retry_load, fail;
|
||||||
|
if ((VM_Version::features() & VM_Version::CPU_STXR_PREFETCH))
|
||||||
__ prfm(Address(tmp), PSTL1STRM);
|
__ prfm(Address(tmp), PSTL1STRM);
|
||||||
__ bind(retry_load);
|
__ bind(retry_load);
|
||||||
__ ldaxr(rscratch1, tmp);
|
__ ldaxr(rscratch1, tmp);
|
||||||
@ -4893,6 +4894,7 @@ encode %{
|
|||||||
__ cmp(tmp, box);
|
__ cmp(tmp, box);
|
||||||
} else {
|
} else {
|
||||||
Label retry_load;
|
Label retry_load;
|
||||||
|
if ((VM_Version::features() & VM_Version::CPU_STXR_PREFETCH))
|
||||||
__ prfm(Address(oop), PSTL1STRM);
|
__ prfm(Address(oop), PSTL1STRM);
|
||||||
__ bind(retry_load);
|
__ bind(retry_load);
|
||||||
__ ldxr(tmp, oop);
|
__ ldxr(tmp, oop);
|
||||||
@ -14953,26 +14955,83 @@ instruct string_compareU(iRegP_R1 str1, iRegI_R2 cnt1, iRegP_R3 str2, iRegI_R4 c
|
|||||||
ins_pipe(pipe_class_memory);
|
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)
|
iRegI_R0 result, iRegI tmp1, iRegI tmp2, iRegI tmp3, iRegI tmp4, rFlagsReg cr)
|
||||||
%{
|
%{
|
||||||
predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU);
|
predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU);
|
||||||
match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2)));
|
match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2)));
|
||||||
effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2,
|
effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2,
|
||||||
TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr);
|
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 %{
|
ins_encode %{
|
||||||
__ string_indexof($str1$$Register, $str2$$Register,
|
__ string_indexof($str1$$Register, $str2$$Register,
|
||||||
$cnt1$$Register, $cnt2$$Register,
|
$cnt1$$Register, $cnt2$$Register,
|
||||||
$tmp1$$Register, $tmp2$$Register,
|
$tmp1$$Register, $tmp2$$Register,
|
||||||
$tmp3$$Register, $tmp4$$Register,
|
$tmp3$$Register, $tmp4$$Register,
|
||||||
-1, $result$$Register);
|
-1, $result$$Register, StrIntrinsicNode::UU);
|
||||||
%}
|
%}
|
||||||
ins_pipe(pipe_class_memory);
|
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,
|
immI_le_4 int_cnt2, iRegI_R0 result, iRegI tmp1, iRegI tmp2,
|
||||||
iRegI tmp3, iRegI tmp4, rFlagsReg cr)
|
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)));
|
match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2)));
|
||||||
effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1,
|
effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1,
|
||||||
TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr);
|
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 %{
|
ins_encode %{
|
||||||
int icnt2 = (int)$int_cnt2$$constant;
|
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,
|
$cnt1$$Register, zr,
|
||||||
$tmp1$$Register, $tmp2$$Register,
|
$tmp1$$Register, $tmp2$$Register,
|
||||||
$tmp3$$Register, $tmp4$$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);
|
ins_pipe(pipe_class_memory);
|
||||||
%}
|
%}
|
||||||
|
@ -23,8 +23,8 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef CPU_X86_VM_C1_LIRASSEMBLER_X86_HPP
|
#ifndef CPU_AARCH64_VM_C1_LIRASSEMBLER_AARCH64_HPP
|
||||||
#define CPU_X86_VM_C1_LIRASSEMBLER_X86_HPP
|
#define CPU_AARCH64_VM_C1_LIRASSEMBLER_AARCH64_HPP
|
||||||
|
|
||||||
// ArrayCopyStub needs access to bailout
|
// ArrayCopyStub needs access to bailout
|
||||||
friend class ArrayCopyStub;
|
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),
|
exception_handler_size = DEBUG_ONLY(1*K) NOT_DEBUG(175),
|
||||||
deopt_handler_size = 7 * NativeInstruction::instruction_size };
|
deopt_handler_size = 7 * NativeInstruction::instruction_size };
|
||||||
|
|
||||||
#endif // CPU_X86_VM_C1_LIRASSEMBLER_X86_HPP
|
#endif // CPU_AARCH64_VM_C1_LIRASSEMBLER_AARCH64_HPP
|
||||||
|
@ -92,9 +92,11 @@ void CompiledStaticCall::set_to_interpreted(methodHandle callee, address entry)
|
|||||||
#ifndef PRODUCT
|
#ifndef PRODUCT
|
||||||
NativeGeneralJump* jump = nativeGeneralJump_at(method_holder->next_instruction_address());
|
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");
|
"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");
|
"b) MT-unsafe modification of inline cache");
|
||||||
#endif
|
#endif
|
||||||
// Update stub.
|
// Update stub.
|
||||||
|
@ -1643,6 +1643,7 @@ void MacroAssembler::atomic_incw(Register counter_addr, Register tmp, Register t
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Label retry_load;
|
Label retry_load;
|
||||||
|
if ((VM_Version::features() & VM_Version::CPU_STXR_PREFETCH))
|
||||||
prfm(Address(counter_addr), PSTL1STRM);
|
prfm(Address(counter_addr), PSTL1STRM);
|
||||||
bind(retry_load);
|
bind(retry_load);
|
||||||
// flush and load exclusive from the memory location
|
// flush and load exclusive from the memory location
|
||||||
@ -2084,6 +2085,7 @@ void MacroAssembler::cmpxchgptr(Register oldv, Register newv, Register addr, Reg
|
|||||||
membar(AnyAny);
|
membar(AnyAny);
|
||||||
} else {
|
} else {
|
||||||
Label retry_load, nope;
|
Label retry_load, nope;
|
||||||
|
if ((VM_Version::features() & VM_Version::CPU_STXR_PREFETCH))
|
||||||
prfm(Address(addr), PSTL1STRM);
|
prfm(Address(addr), PSTL1STRM);
|
||||||
bind(retry_load);
|
bind(retry_load);
|
||||||
// flush and load exclusive from the memory location
|
// flush and load exclusive from the memory location
|
||||||
@ -2120,6 +2122,7 @@ void MacroAssembler::cmpxchgw(Register oldv, Register newv, Register addr, Regis
|
|||||||
membar(AnyAny);
|
membar(AnyAny);
|
||||||
} else {
|
} else {
|
||||||
Label retry_load, nope;
|
Label retry_load, nope;
|
||||||
|
if ((VM_Version::features() & VM_Version::CPU_STXR_PREFETCH))
|
||||||
prfm(Address(addr), PSTL1STRM);
|
prfm(Address(addr), PSTL1STRM);
|
||||||
bind(retry_load);
|
bind(retry_load);
|
||||||
// flush and load exclusive from the memory location
|
// flush and load exclusive from the memory location
|
||||||
@ -2155,6 +2158,7 @@ void MacroAssembler::cmpxchg(Register addr, Register expected,
|
|||||||
} else {
|
} else {
|
||||||
BLOCK_COMMENT("cmpxchg {");
|
BLOCK_COMMENT("cmpxchg {");
|
||||||
Label retry_load, done;
|
Label retry_load, done;
|
||||||
|
if ((VM_Version::features() & VM_Version::CPU_STXR_PREFETCH))
|
||||||
prfm(Address(addr), PSTL1STRM);
|
prfm(Address(addr), PSTL1STRM);
|
||||||
bind(retry_load);
|
bind(retry_load);
|
||||||
load_exclusive(tmp, addr, size, acquire);
|
load_exclusive(tmp, addr, size, acquire);
|
||||||
@ -2194,6 +2198,7 @@ void MacroAssembler::atomic_##NAME(Register prev, RegisterOrConstant incr, Regis
|
|||||||
result = different(prev, incr, addr) ? prev : rscratch2; \
|
result = different(prev, incr, addr) ? prev : rscratch2; \
|
||||||
\
|
\
|
||||||
Label retry_load; \
|
Label retry_load; \
|
||||||
|
if ((VM_Version::features() & VM_Version::CPU_STXR_PREFETCH)) \
|
||||||
prfm(Address(addr), PSTL1STRM); \
|
prfm(Address(addr), PSTL1STRM); \
|
||||||
bind(retry_load); \
|
bind(retry_load); \
|
||||||
LDXR(result, addr); \
|
LDXR(result, addr); \
|
||||||
@ -2224,6 +2229,7 @@ void MacroAssembler::atomic_##OP(Register prev, Register newv, Register addr) {
|
|||||||
result = different(prev, newv, addr) ? prev : rscratch2; \
|
result = different(prev, newv, addr) ? prev : rscratch2; \
|
||||||
\
|
\
|
||||||
Label retry_load; \
|
Label retry_load; \
|
||||||
|
if ((VM_Version::features() & VM_Version::CPU_STXR_PREFETCH)) \
|
||||||
prfm(Address(addr), PSTL1STRM); \
|
prfm(Address(addr), PSTL1STRM); \
|
||||||
bind(retry_load); \
|
bind(retry_load); \
|
||||||
LDXR(result, addr); \
|
LDXR(result, 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
|
// Search for str1 in str2 and return index or -1
|
||||||
void MacroAssembler::string_indexof(Register str2, Register str1,
|
void MacroAssembler::string_indexof(Register str2, Register str1,
|
||||||
Register cnt2, Register cnt1,
|
Register cnt2, Register cnt1,
|
||||||
Register tmp1, Register tmp2,
|
Register tmp1, Register tmp2,
|
||||||
Register tmp3, Register tmp4,
|
Register tmp3, Register tmp4,
|
||||||
int icnt1, Register result) {
|
int icnt1, Register result, int ae) {
|
||||||
Label BM, LINEARSEARCH, DONE, NOMATCH, MATCH;
|
Label BM, LINEARSEARCH, DONE, NOMATCH, MATCH;
|
||||||
|
|
||||||
Register ch1 = rscratch1;
|
Register ch1 = rscratch1;
|
||||||
@ -4153,6 +4160,21 @@ void MacroAssembler::string_indexof(Register str2, Register str1,
|
|||||||
Register cnt2_neg = cnt2;
|
Register cnt2_neg = cnt2;
|
||||||
Register result_tmp = tmp4;
|
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:
|
// Note, inline_string_indexOf() generates checks:
|
||||||
// if (substr.count > string.count) return -1;
|
// if (substr.count > string.count) return -1;
|
||||||
// if (substr.count == 0) return 0;
|
// if (substr.count == 0) return 0;
|
||||||
@ -4242,7 +4264,7 @@ void MacroAssembler::string_indexof(Register str2, Register str1,
|
|||||||
mov(cnt1tmp, 0);
|
mov(cnt1tmp, 0);
|
||||||
sub(cnt1end, cnt1, 1);
|
sub(cnt1end, cnt1, 1);
|
||||||
BIND(BCLOOP);
|
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);
|
cmp(ch1, 128);
|
||||||
add(cnt1tmp, cnt1tmp, 1);
|
add(cnt1tmp, cnt1tmp, 1);
|
||||||
br(HS, BCSKIP);
|
br(HS, BCSKIP);
|
||||||
@ -4254,36 +4276,36 @@ void MacroAssembler::string_indexof(Register str2, Register str1,
|
|||||||
mov(result_tmp, str2);
|
mov(result_tmp, str2);
|
||||||
|
|
||||||
sub(cnt2, cnt2, cnt1);
|
sub(cnt2, cnt2, cnt1);
|
||||||
add(str2end, str2, cnt2, LSL, 1);
|
add(str2end, str2, cnt2, LSL, str2_chr_shift);
|
||||||
BIND(BMLOOPSTR2);
|
BIND(BMLOOPSTR2);
|
||||||
sub(cnt1tmp, cnt1, 1);
|
sub(cnt1tmp, cnt1, 1);
|
||||||
ldrh(ch1, Address(str1, cnt1tmp, Address::lsl(1)));
|
(this->*str1_load_1chr)(ch1, Address(str1, cnt1tmp, Address::lsl(str1_chr_shift)));
|
||||||
ldrh(skipch, Address(str2, cnt1tmp, Address::lsl(1)));
|
(this->*str2_load_1chr)(skipch, Address(str2, cnt1tmp, Address::lsl(str2_chr_shift)));
|
||||||
cmp(ch1, skipch);
|
cmp(ch1, skipch);
|
||||||
br(NE, BMSKIP);
|
br(NE, BMSKIP);
|
||||||
subs(cnt1tmp, cnt1tmp, 1);
|
subs(cnt1tmp, cnt1tmp, 1);
|
||||||
br(LT, BMMATCH);
|
br(LT, BMMATCH);
|
||||||
BIND(BMLOOPSTR1);
|
BIND(BMLOOPSTR1);
|
||||||
ldrh(ch1, Address(str1, cnt1tmp, Address::lsl(1)));
|
(this->*str1_load_1chr)(ch1, Address(str1, cnt1tmp, Address::lsl(str1_chr_shift)));
|
||||||
ldrh(ch2, Address(str2, cnt1tmp, Address::lsl(1)));
|
(this->*str2_load_1chr)(ch2, Address(str2, cnt1tmp, Address::lsl(str2_chr_shift)));
|
||||||
cmp(ch1, ch2);
|
cmp(ch1, ch2);
|
||||||
br(NE, BMSKIP);
|
br(NE, BMSKIP);
|
||||||
subs(cnt1tmp, cnt1tmp, 1);
|
subs(cnt1tmp, cnt1tmp, 1);
|
||||||
br(GE, BMLOOPSTR1);
|
br(GE, BMLOOPSTR1);
|
||||||
BIND(BMMATCH);
|
BIND(BMMATCH);
|
||||||
sub(result_tmp, str2, result_tmp);
|
sub(result, str2, result_tmp);
|
||||||
lsr(result, result_tmp, 1);
|
if (!str2_isL) lsr(result, result, 1);
|
||||||
add(sp, sp, 128);
|
add(sp, sp, 128);
|
||||||
b(DONE);
|
b(DONE);
|
||||||
BIND(BMADV);
|
BIND(BMADV);
|
||||||
add(str2, str2, 2);
|
add(str2, str2, str2_chr_size);
|
||||||
b(BMCHECKEND);
|
b(BMCHECKEND);
|
||||||
BIND(BMSKIP);
|
BIND(BMSKIP);
|
||||||
cmp(skipch, 128);
|
cmp(skipch, 128);
|
||||||
br(HS, BMADV);
|
br(HS, BMADV);
|
||||||
ldrb(ch2, Address(sp, skipch));
|
ldrb(ch2, Address(sp, skipch));
|
||||||
add(str2, str2, cnt1, LSL, 1);
|
add(str2, str2, cnt1, LSL, str2_chr_shift);
|
||||||
sub(str2, str2, ch2, LSL, 1);
|
sub(str2, str2, ch2, LSL, str2_chr_shift);
|
||||||
BIND(BMCHECKEND);
|
BIND(BMCHECKEND);
|
||||||
cmp(str2, str2end);
|
cmp(str2, str2end);
|
||||||
br(LE, BMLOOPSTR2);
|
br(LE, BMLOOPSTR2);
|
||||||
@ -4300,119 +4322,113 @@ void MacroAssembler::string_indexof(Register str2, Register str1,
|
|||||||
|
|
||||||
if (icnt1 == -1)
|
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);
|
br(LT, DOSHORT);
|
||||||
|
|
||||||
sub(cnt2, cnt2, cnt1);
|
sub(cnt2, cnt2, cnt1);
|
||||||
sub(cnt1, cnt1, 4);
|
|
||||||
mov(result_tmp, cnt2);
|
mov(result_tmp, cnt2);
|
||||||
|
|
||||||
lea(str1, Address(str1, cnt1, Address::uxtw(1)));
|
lea(str1, Address(str1, cnt1, Address::lsl(str1_chr_shift)));
|
||||||
lea(str2, Address(str2, cnt2, Address::uxtw(1)));
|
lea(str2, Address(str2, cnt2, Address::lsl(str2_chr_shift)));
|
||||||
sub(cnt1_neg, zr, cnt1, LSL, 1);
|
sub(cnt1_neg, zr, cnt1, LSL, str1_chr_shift);
|
||||||
sub(cnt2_neg, zr, cnt2, LSL, 1);
|
sub(cnt2_neg, zr, cnt2, LSL, str2_chr_shift);
|
||||||
ldr(first, Address(str1, cnt1_neg));
|
(this->*str1_load_1chr)(first, Address(str1, cnt1_neg));
|
||||||
|
|
||||||
BIND(FIRST_LOOP);
|
BIND(FIRST_LOOP);
|
||||||
ldr(ch2, Address(str2, cnt2_neg));
|
(this->*str2_load_1chr)(ch2, Address(str2, cnt2_neg));
|
||||||
cmp(first, ch2);
|
cmp(first, ch2);
|
||||||
br(EQ, STR1_LOOP);
|
br(EQ, STR1_LOOP);
|
||||||
BIND(STR2_NEXT);
|
BIND(STR2_NEXT);
|
||||||
adds(cnt2_neg, cnt2_neg, 2);
|
adds(cnt2_neg, cnt2_neg, str2_chr_size);
|
||||||
br(LE, FIRST_LOOP);
|
br(LE, FIRST_LOOP);
|
||||||
b(NOMATCH);
|
b(NOMATCH);
|
||||||
|
|
||||||
BIND(STR1_LOOP);
|
BIND(STR1_LOOP);
|
||||||
adds(cnt1tmp, cnt1_neg, 8);
|
adds(cnt1tmp, cnt1_neg, str1_chr_size);
|
||||||
add(cnt2tmp, cnt2_neg, 8);
|
add(cnt2tmp, cnt2_neg, str2_chr_size);
|
||||||
br(GE, LAST_WORD);
|
br(GE, MATCH);
|
||||||
|
|
||||||
BIND(STR1_NEXT);
|
BIND(STR1_NEXT);
|
||||||
ldr(ch1, Address(str1, cnt1tmp));
|
(this->*str1_load_1chr)(ch1, Address(str1, cnt1tmp));
|
||||||
ldr(ch2, Address(str2, cnt2tmp));
|
(this->*str2_load_1chr)(ch2, Address(str2, cnt2tmp));
|
||||||
cmp(ch1, ch2);
|
cmp(ch1, ch2);
|
||||||
br(NE, STR2_NEXT);
|
br(NE, STR2_NEXT);
|
||||||
adds(cnt1tmp, cnt1tmp, 8);
|
adds(cnt1tmp, cnt1tmp, str1_chr_size);
|
||||||
add(cnt2tmp, cnt2tmp, 8);
|
add(cnt2tmp, cnt2tmp, str2_chr_size);
|
||||||
br(LT, STR1_NEXT);
|
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);
|
b(MATCH);
|
||||||
|
|
||||||
BIND(DOSHORT);
|
BIND(DOSHORT);
|
||||||
|
if (str1_isL == str2_isL) {
|
||||||
cmp(cnt1, 2);
|
cmp(cnt1, 2);
|
||||||
br(LT, DO1);
|
br(LT, DO1);
|
||||||
br(GT, DO3);
|
br(GT, DO3);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (icnt1 == 4) {
|
if (icnt1 == 4) {
|
||||||
Label CH1_LOOP;
|
Label CH1_LOOP;
|
||||||
|
|
||||||
ldr(ch1, str1);
|
(this->*load_4chr)(ch1, str1);
|
||||||
sub(cnt2, cnt2, 4);
|
sub(cnt2, cnt2, 4);
|
||||||
mov(result_tmp, cnt2);
|
mov(result_tmp, cnt2);
|
||||||
lea(str2, Address(str2, cnt2, Address::uxtw(1)));
|
lea(str2, Address(str2, cnt2, Address::lsl(str2_chr_shift)));
|
||||||
sub(cnt2_neg, zr, cnt2, LSL, 1);
|
sub(cnt2_neg, zr, cnt2, LSL, str2_chr_shift);
|
||||||
|
|
||||||
BIND(CH1_LOOP);
|
BIND(CH1_LOOP);
|
||||||
ldr(ch2, Address(str2, cnt2_neg));
|
(this->*load_4chr)(ch2, Address(str2, cnt2_neg));
|
||||||
cmp(ch1, ch2);
|
cmp(ch1, ch2);
|
||||||
br(EQ, MATCH);
|
br(EQ, MATCH);
|
||||||
adds(cnt2_neg, cnt2_neg, 2);
|
adds(cnt2_neg, cnt2_neg, str2_chr_size);
|
||||||
br(LE, CH1_LOOP);
|
br(LE, CH1_LOOP);
|
||||||
b(NOMATCH);
|
b(NOMATCH);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (icnt1 == -1 || icnt1 == 2) {
|
if ((icnt1 == -1 && str1_isL == str2_isL) || icnt1 == 2) {
|
||||||
Label CH1_LOOP;
|
Label CH1_LOOP;
|
||||||
|
|
||||||
BIND(DO2);
|
BIND(DO2);
|
||||||
ldrw(ch1, str1);
|
(this->*load_2chr)(ch1, str1);
|
||||||
sub(cnt2, cnt2, 2);
|
sub(cnt2, cnt2, 2);
|
||||||
mov(result_tmp, cnt2);
|
mov(result_tmp, cnt2);
|
||||||
lea(str2, Address(str2, cnt2, Address::uxtw(1)));
|
lea(str2, Address(str2, cnt2, Address::lsl(str2_chr_shift)));
|
||||||
sub(cnt2_neg, zr, cnt2, LSL, 1);
|
sub(cnt2_neg, zr, cnt2, LSL, str2_chr_shift);
|
||||||
|
|
||||||
BIND(CH1_LOOP);
|
BIND(CH1_LOOP);
|
||||||
ldrw(ch2, Address(str2, cnt2_neg));
|
(this->*load_2chr)(ch2, Address(str2, cnt2_neg));
|
||||||
cmp(ch1, ch2);
|
cmp(ch1, ch2);
|
||||||
br(EQ, MATCH);
|
br(EQ, MATCH);
|
||||||
adds(cnt2_neg, cnt2_neg, 2);
|
adds(cnt2_neg, cnt2_neg, str2_chr_size);
|
||||||
br(LE, CH1_LOOP);
|
br(LE, CH1_LOOP);
|
||||||
b(NOMATCH);
|
b(NOMATCH);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (icnt1 == -1 || icnt1 == 3) {
|
if ((icnt1 == -1 && str1_isL == str2_isL) || icnt1 == 3) {
|
||||||
Label FIRST_LOOP, STR2_NEXT, STR1_LOOP;
|
Label FIRST_LOOP, STR2_NEXT, STR1_LOOP;
|
||||||
|
|
||||||
BIND(DO3);
|
BIND(DO3);
|
||||||
ldrw(first, str1);
|
(this->*load_2chr)(first, str1);
|
||||||
ldrh(ch1, Address(str1, 4));
|
(this->*str1_load_1chr)(ch1, Address(str1, 2*str1_chr_size));
|
||||||
|
|
||||||
sub(cnt2, cnt2, 3);
|
sub(cnt2, cnt2, 3);
|
||||||
mov(result_tmp, cnt2);
|
mov(result_tmp, cnt2);
|
||||||
lea(str2, Address(str2, cnt2, Address::uxtw(1)));
|
lea(str2, Address(str2, cnt2, Address::lsl(str2_chr_shift)));
|
||||||
sub(cnt2_neg, zr, cnt2, LSL, 1);
|
sub(cnt2_neg, zr, cnt2, LSL, str2_chr_shift);
|
||||||
|
|
||||||
BIND(FIRST_LOOP);
|
BIND(FIRST_LOOP);
|
||||||
ldrw(ch2, Address(str2, cnt2_neg));
|
(this->*load_2chr)(ch2, Address(str2, cnt2_neg));
|
||||||
cmpw(first, ch2);
|
cmpw(first, ch2);
|
||||||
br(EQ, STR1_LOOP);
|
br(EQ, STR1_LOOP);
|
||||||
BIND(STR2_NEXT);
|
BIND(STR2_NEXT);
|
||||||
adds(cnt2_neg, cnt2_neg, 2);
|
adds(cnt2_neg, cnt2_neg, str2_chr_size);
|
||||||
br(LE, FIRST_LOOP);
|
br(LE, FIRST_LOOP);
|
||||||
b(NOMATCH);
|
b(NOMATCH);
|
||||||
|
|
||||||
BIND(STR1_LOOP);
|
BIND(STR1_LOOP);
|
||||||
add(cnt2tmp, cnt2_neg, 4);
|
add(cnt2tmp, cnt2_neg, 2*str2_chr_size);
|
||||||
ldrh(ch2, Address(str2, cnt2tmp));
|
(this->*str2_load_1chr)(ch2, Address(str2, cnt2tmp));
|
||||||
cmp(ch1, ch2);
|
cmp(ch1, ch2);
|
||||||
br(NE, STR2_NEXT);
|
br(NE, STR2_NEXT);
|
||||||
b(MATCH);
|
b(MATCH);
|
||||||
@ -4423,24 +4439,31 @@ void MacroAssembler::string_indexof(Register str2, Register str1,
|
|||||||
Label DO1_SHORT, DO1_LOOP;
|
Label DO1_SHORT, DO1_LOOP;
|
||||||
|
|
||||||
BIND(DO1);
|
BIND(DO1);
|
||||||
ldrh(ch1, str1);
|
(this->*str1_load_1chr)(ch1, str1);
|
||||||
cmp(cnt2, 4);
|
cmp(cnt2, 8);
|
||||||
br(LT, DO1_SHORT);
|
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, 16);
|
||||||
orr(ch1, ch1, ch1, LSL, 32);
|
orr(ch1, ch1, ch1, LSL, 32);
|
||||||
|
|
||||||
sub(cnt2, cnt2, 4);
|
sub(cnt2, cnt2, 8/str2_chr_size);
|
||||||
mov(result_tmp, cnt2);
|
mov(result_tmp, cnt2);
|
||||||
lea(str2, Address(str2, cnt2, Address::uxtw(1)));
|
lea(str2, Address(str2, cnt2, Address::lsl(str2_chr_shift)));
|
||||||
sub(cnt2_neg, zr, cnt2, LSL, 1);
|
sub(cnt2_neg, zr, cnt2, LSL, str2_chr_shift);
|
||||||
|
|
||||||
mov(tmp3, 0x0001000100010001);
|
mov(tmp3, str2_isL ? 0x0101010101010101 : 0x0001000100010001);
|
||||||
BIND(CH1_LOOP);
|
BIND(CH1_LOOP);
|
||||||
ldr(ch2, Address(str2, cnt2_neg));
|
ldr(ch2, Address(str2, cnt2_neg));
|
||||||
eor(ch2, ch1, ch2);
|
eor(ch2, ch1, ch2);
|
||||||
sub(tmp1, ch2, tmp3);
|
sub(tmp1, ch2, tmp3);
|
||||||
orr(tmp2, ch2, 0x7fff7fff7fff7fff);
|
orr(tmp2, ch2, str2_isL ? 0x7f7f7f7f7f7f7f7f : 0x7fff7fff7fff7fff);
|
||||||
bics(tmp1, tmp1, tmp2);
|
bics(tmp1, tmp1, tmp2);
|
||||||
br(NE, HAS_ZERO);
|
br(NE, HAS_ZERO);
|
||||||
adds(cnt2_neg, cnt2_neg, 8);
|
adds(cnt2_neg, cnt2_neg, 8);
|
||||||
@ -4459,13 +4482,13 @@ void MacroAssembler::string_indexof(Register str2, Register str1,
|
|||||||
|
|
||||||
BIND(DO1_SHORT);
|
BIND(DO1_SHORT);
|
||||||
mov(result_tmp, cnt2);
|
mov(result_tmp, cnt2);
|
||||||
lea(str2, Address(str2, cnt2, Address::uxtw(1)));
|
lea(str2, Address(str2, cnt2, Address::lsl(str2_chr_shift)));
|
||||||
sub(cnt2_neg, zr, cnt2, LSL, 1);
|
sub(cnt2_neg, zr, cnt2, LSL, str2_chr_shift);
|
||||||
BIND(DO1_LOOP);
|
BIND(DO1_LOOP);
|
||||||
ldrh(ch2, Address(str2, cnt2_neg));
|
(this->*str2_load_1chr)(ch2, Address(str2, cnt2_neg));
|
||||||
cmpw(ch1, ch2);
|
cmpw(ch1, ch2);
|
||||||
br(EQ, MATCH);
|
br(EQ, MATCH);
|
||||||
adds(cnt2_neg, cnt2_neg, 2);
|
adds(cnt2_neg, cnt2_neg, str2_chr_size);
|
||||||
br(LT, DO1_LOOP);
|
br(LT, DO1_LOOP);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -4473,7 +4496,7 @@ void MacroAssembler::string_indexof(Register str2, Register str1,
|
|||||||
mov(result, -1);
|
mov(result, -1);
|
||||||
b(DONE);
|
b(DONE);
|
||||||
BIND(MATCH);
|
BIND(MATCH);
|
||||||
add(result, result_tmp, cnt2_neg, ASR, 1);
|
add(result, result_tmp, cnt2_neg, ASR, str2_chr_shift);
|
||||||
BIND(DONE);
|
BIND(DONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -545,6 +545,15 @@ public:
|
|||||||
mrs(0b011, 0b0000, 0b0000, 0b111, reg);
|
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
|
// idiv variant which deals with MINLONG as dividend and -1 as divisor
|
||||||
int corrected_idivl(Register result, Register ra, Register rb,
|
int corrected_idivl(Register result, Register ra, Register rb,
|
||||||
bool want_remainder, Register tmp = rscratch1);
|
bool want_remainder, Register tmp = rscratch1);
|
||||||
@ -1217,7 +1226,7 @@ public:
|
|||||||
Register cnt1, Register cnt2,
|
Register cnt1, Register cnt2,
|
||||||
Register tmp1, Register tmp2,
|
Register tmp1, Register tmp2,
|
||||||
Register tmp3, Register tmp4,
|
Register tmp3, Register tmp4,
|
||||||
int int_cnt1, Register result);
|
int int_cnt1, Register result, int ae);
|
||||||
private:
|
private:
|
||||||
void add2_with_carry(Register final_dest_hi, Register dest_hi, Register dest_lo,
|
void add2_with_carry(Register final_dest_hi, Register dest_hi, Register dest_lo,
|
||||||
Register src1, Register src2);
|
Register src1, Register src2);
|
||||||
|
@ -105,6 +105,9 @@ class VM_Version_StubGenerator: public StubCodeGenerator {
|
|||||||
__ get_dczid_el0(rscratch1);
|
__ get_dczid_el0(rscratch1);
|
||||||
__ strw(rscratch1, Address(c_rarg0, in_bytes(VM_Version::dczid_el0_offset())));
|
__ 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();
|
__ leave();
|
||||||
__ ret(lr);
|
__ ret(lr);
|
||||||
|
|
||||||
@ -124,16 +127,20 @@ void VM_Version::get_processor_features() {
|
|||||||
|
|
||||||
getPsrInfo_stub(&_psr_info);
|
getPsrInfo_stub(&_psr_info);
|
||||||
|
|
||||||
|
int dcache_line = VM_Version::dcache_line_size();
|
||||||
|
|
||||||
if (FLAG_IS_DEFAULT(AllocatePrefetchDistance))
|
if (FLAG_IS_DEFAULT(AllocatePrefetchDistance))
|
||||||
FLAG_SET_DEFAULT(AllocatePrefetchDistance, 256);
|
FLAG_SET_DEFAULT(AllocatePrefetchDistance, 3*dcache_line);
|
||||||
if (FLAG_IS_DEFAULT(AllocatePrefetchStepSize))
|
if (FLAG_IS_DEFAULT(AllocatePrefetchStepSize))
|
||||||
FLAG_SET_DEFAULT(AllocatePrefetchStepSize, 64);
|
FLAG_SET_DEFAULT(AllocatePrefetchStepSize, dcache_line);
|
||||||
FLAG_SET_DEFAULT(PrefetchScanIntervalInBytes, 256);
|
if (FLAG_IS_DEFAULT(PrefetchScanIntervalInBytes))
|
||||||
FLAG_SET_DEFAULT(PrefetchFieldsAhead, 256);
|
FLAG_SET_DEFAULT(PrefetchScanIntervalInBytes, 3*dcache_line);
|
||||||
if (FLAG_IS_DEFAULT(PrefetchCopyIntervalInBytes))
|
if (FLAG_IS_DEFAULT(PrefetchCopyIntervalInBytes))
|
||||||
FLAG_SET_DEFAULT(PrefetchCopyIntervalInBytes, 256);
|
FLAG_SET_DEFAULT(PrefetchCopyIntervalInBytes, 3*dcache_line);
|
||||||
if ((PrefetchCopyIntervalInBytes & 7) || (PrefetchCopyIntervalInBytes >= 32768)) {
|
|
||||||
warning("PrefetchCopyIntervalInBytes must be a multiple of 8 and < 32768");
|
if (PrefetchCopyIntervalInBytes != -1 &&
|
||||||
|
((PrefetchCopyIntervalInBytes & 7) || (PrefetchCopyIntervalInBytes >= 32768))) {
|
||||||
|
warning("PrefetchCopyIntervalInBytes must be -1, or a multiple of 8 and < 32768");
|
||||||
PrefetchCopyIntervalInBytes &= ~7;
|
PrefetchCopyIntervalInBytes &= ~7;
|
||||||
if (PrefetchCopyIntervalInBytes >= 32768)
|
if (PrefetchCopyIntervalInBytes >= 32768)
|
||||||
PrefetchCopyIntervalInBytes = 32760;
|
PrefetchCopyIntervalInBytes = 32760;
|
||||||
@ -170,6 +177,7 @@ void VM_Version::get_processor_features() {
|
|||||||
// Enable vendor specific features
|
// Enable vendor specific features
|
||||||
if (_cpu == CPU_CAVIUM && _variant == 0) _features |= CPU_DMB_ATOMICS;
|
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 == 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)
|
// 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
|
// 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
|
// undisclosed A53 cores which we could be swapped to at any stage
|
||||||
|
@ -42,6 +42,7 @@ protected:
|
|||||||
|
|
||||||
struct PsrInfo {
|
struct PsrInfo {
|
||||||
uint32_t dczid_el0;
|
uint32_t dczid_el0;
|
||||||
|
uint32_t ctr_el0;
|
||||||
};
|
};
|
||||||
static PsrInfo _psr_info;
|
static PsrInfo _psr_info;
|
||||||
static void get_processor_features();
|
static void get_processor_features();
|
||||||
@ -78,6 +79,7 @@ public:
|
|||||||
CPU_SHA2 = (1<<6),
|
CPU_SHA2 = (1<<6),
|
||||||
CPU_CRC32 = (1<<7),
|
CPU_CRC32 = (1<<7),
|
||||||
CPU_LSE = (1<<8),
|
CPU_LSE = (1<<8),
|
||||||
|
CPU_STXR_PREFETCH= (1 << 29),
|
||||||
CPU_A53MAC = (1 << 30),
|
CPU_A53MAC = (1 << 30),
|
||||||
CPU_DMB_ATOMICS = (1 << 31),
|
CPU_DMB_ATOMICS = (1 << 31),
|
||||||
};
|
};
|
||||||
@ -88,6 +90,7 @@ public:
|
|||||||
static int cpu_variant() { return _variant; }
|
static int cpu_variant() { return _variant; }
|
||||||
static int cpu_revision() { return _revision; }
|
static int cpu_revision() { return _revision; }
|
||||||
static ByteSize dczid_el0_offset() { return byte_offset_of(PsrInfo, dczid_el0); }
|
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() {
|
static bool is_zva_enabled() {
|
||||||
// Check the DZP bit (bit 4) of dczid_el0 is zero
|
// Check the DZP bit (bit 4) of dczid_el0 is zero
|
||||||
// and block size (bit 0~3) is not zero.
|
// and block size (bit 0~3) is not zero.
|
||||||
@ -98,6 +101,12 @@ public:
|
|||||||
assert(is_zva_enabled(), "ZVA not available");
|
assert(is_zva_enabled(), "ZVA not available");
|
||||||
return 4 << (_psr_info.dczid_el0 & 0xf);
|
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
|
#endif // CPU_AARCH64_VM_VM_VERSION_AARCH64_HPP
|
||||||
|
@ -2563,15 +2563,21 @@ void LIR_Assembler::emit_compare_and_swap(LIR_OpCompareAndSwap* op) {
|
|||||||
|
|
||||||
if (is_64bit) {
|
if (is_64bit) {
|
||||||
__ cmpxchgd(BOOL_RESULT, /*current_value=*/R0, cmp_value, new_value, addr,
|
__ cmpxchgd(BOOL_RESULT, /*current_value=*/R0, cmp_value, new_value, addr,
|
||||||
MacroAssembler::MemBarFenceAfter,
|
MacroAssembler::MemBarNone,
|
||||||
MacroAssembler::cmpxchgx_hint_atomic_update(),
|
MacroAssembler::cmpxchgx_hint_atomic_update(),
|
||||||
noreg, NULL, /*check without ldarx first*/true);
|
noreg, NULL, /*check without ldarx first*/true);
|
||||||
} else {
|
} else {
|
||||||
__ cmpxchgw(BOOL_RESULT, /*current_value=*/R0, cmp_value, new_value, addr,
|
__ cmpxchgw(BOOL_RESULT, /*current_value=*/R0, cmp_value, new_value, addr,
|
||||||
MacroAssembler::MemBarFenceAfter,
|
MacroAssembler::MemBarNone,
|
||||||
MacroAssembler::cmpxchgx_hint_atomic_update(),
|
MacroAssembler::cmpxchgx_hint_atomic_update(),
|
||||||
noreg, /*check without ldarx first*/true);
|
noreg, /*check without ldarx first*/true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
|
||||||
|
__ isync();
|
||||||
|
} else {
|
||||||
|
__ sync();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1353,7 +1353,11 @@ void LIRGenerator::do_UnsafeGetAndSetObject(UnsafeGetAndSetObject* x) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
|
||||||
|
__ membar_acquire();
|
||||||
|
} else {
|
||||||
__ membar();
|
__ membar();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -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);
|
NativeMovConstReg* method_holder = nativeMovConstReg_at(stub + IC_pos_in_java_to_interp_stub);
|
||||||
NativeJump* jump = nativeJump_at(method_holder->next_instruction_address());
|
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");
|
"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");
|
"b) MT-unsafe modification of inline cache");
|
||||||
|
#endif
|
||||||
|
|
||||||
// Update stub.
|
// Update stub.
|
||||||
method_holder->set_data((intptr_t)callee());
|
method_holder->set_data((intptr_t)callee());
|
||||||
|
@ -1404,7 +1404,7 @@ address MacroAssembler::get_stack_bang_address(int instruction, void *ucontext)
|
|||||||
void MacroAssembler::cmpxchgw(ConditionRegister flag, Register dest_current_value,
|
void MacroAssembler::cmpxchgw(ConditionRegister flag, Register dest_current_value,
|
||||||
Register compare_value, Register exchange_value,
|
Register compare_value, Register exchange_value,
|
||||||
Register addr_base, int semantics, bool cmpxchgx_hint,
|
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 retry;
|
||||||
Label failed;
|
Label failed;
|
||||||
Label done;
|
Label done;
|
||||||
@ -1414,6 +1414,7 @@ void MacroAssembler::cmpxchgw(ConditionRegister flag, Register dest_current_valu
|
|||||||
bool use_result_reg = (int_flag_success != noreg);
|
bool use_result_reg = (int_flag_success != noreg);
|
||||||
bool preset_result_reg = (int_flag_success != dest_current_value && int_flag_success != compare_value &&
|
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);
|
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) {
|
if (use_result_reg && preset_result_reg) {
|
||||||
li(int_flag_success, 0); // preset (assume cas failed)
|
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)
|
// fall through => (flag == eq), (dest_current_value == compare_value)
|
||||||
|
|
||||||
stwcx_(exchange_value, addr_base);
|
stwcx_(exchange_value, addr_base);
|
||||||
|
if (!weak || use_result_reg) {
|
||||||
if (UseStaticBranchPredictionInCompareAndSwapPPC64) {
|
if (UseStaticBranchPredictionInCompareAndSwapPPC64) {
|
||||||
bne_predict_not_taken(CCR0, retry); // StXcx_ sets CCR0.
|
bne_predict_not_taken(CCR0, weak ? failed : retry); // StXcx_ sets CCR0.
|
||||||
} else {
|
} else {
|
||||||
bne( CCR0, retry); // StXcx_ sets CCR0.
|
bne( CCR0, weak ? failed : retry); // StXcx_ sets CCR0.
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// fall through => (flag == eq), (dest_current_value == compare_value), (swapped)
|
// 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,
|
void MacroAssembler::cmpxchgd(ConditionRegister flag,
|
||||||
Register dest_current_value, RegisterOrConstant compare_value, Register exchange_value,
|
Register dest_current_value, RegisterOrConstant compare_value, Register exchange_value,
|
||||||
Register addr_base, int semantics, bool cmpxchgx_hint,
|
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 retry;
|
||||||
Label failed_int;
|
Label failed_int;
|
||||||
Label& failed = (failed_ext != NULL) ? *failed_ext : 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 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() &&
|
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);
|
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");
|
assert(int_flag_success == noreg || failed_ext == NULL, "cannot have both");
|
||||||
|
|
||||||
if (use_result_reg && preset_result_reg) {
|
if (use_result_reg && preset_result_reg) {
|
||||||
@ -1538,10 +1542,12 @@ void MacroAssembler::cmpxchgd(ConditionRegister flag,
|
|||||||
}
|
}
|
||||||
|
|
||||||
stdcx_(exchange_value, addr_base);
|
stdcx_(exchange_value, addr_base);
|
||||||
|
if (!weak || use_result_reg || failed_ext) {
|
||||||
if (UseStaticBranchPredictionInCompareAndSwapPPC64) {
|
if (UseStaticBranchPredictionInCompareAndSwapPPC64) {
|
||||||
bne_predict_not_taken(CCR0, retry); // stXcx_ sets CCR0
|
bne_predict_not_taken(CCR0, weak ? failed : retry); // stXcx_ sets CCR0
|
||||||
} else {
|
} else {
|
||||||
bne( CCR0, retry); // stXcx_ sets CCR0
|
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)
|
// result in register (must do this at the end because int_flag_success can be the same register as one above)
|
||||||
|
@ -430,11 +430,11 @@ class MacroAssembler: public Assembler {
|
|||||||
void cmpxchgw(ConditionRegister flag,
|
void cmpxchgw(ConditionRegister flag,
|
||||||
Register dest_current_value, Register compare_value, Register exchange_value, Register addr_base,
|
Register dest_current_value, Register compare_value, Register exchange_value, Register addr_base,
|
||||||
int semantics, bool cmpxchgx_hint = false,
|
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,
|
void cmpxchgd(ConditionRegister flag,
|
||||||
Register dest_current_value, RegisterOrConstant compare_value, Register exchange_value,
|
Register dest_current_value, RegisterOrConstant compare_value, Register exchange_value,
|
||||||
Register addr_base, int semantics, bool cmpxchgx_hint = false,
|
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
|
// interface method calling
|
||||||
void lookup_interface_method(Register recv_klass,
|
void lookup_interface_method(Register recv_klass,
|
||||||
|
@ -3083,7 +3083,11 @@ encode %{
|
|||||||
__ bne( CCR0, Lretry);
|
__ bne( CCR0, Lretry);
|
||||||
}
|
}
|
||||||
if (RegCollision) __ subf(Rres, Rsrc, Rtmp);
|
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) %{
|
enc_class enc_GetAndAddL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src) %{
|
||||||
@ -3108,7 +3112,11 @@ encode %{
|
|||||||
__ bne( CCR0, Lretry);
|
__ bne( CCR0, Lretry);
|
||||||
}
|
}
|
||||||
if (RegCollision) __ subf(Rres, Rsrc, Rtmp);
|
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) %{
|
enc_class enc_GetAndSetI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src) %{
|
||||||
@ -3132,7 +3140,11 @@ encode %{
|
|||||||
__ bne( CCR0, Lretry);
|
__ bne( CCR0, Lretry);
|
||||||
}
|
}
|
||||||
if (RegCollision) __ mr(Rres, Rtmp);
|
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) %{
|
enc_class enc_GetAndSetL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src) %{
|
||||||
@ -3156,7 +3168,11 @@ encode %{
|
|||||||
__ bne( CCR0, Lretry);
|
__ bne( CCR0, Lretry);
|
||||||
}
|
}
|
||||||
if (RegCollision) __ mr(Rres, Rtmp);
|
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
|
// 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
|
// (CompareAndSwap ...)" or "If (CmpI (CompareAndSwap ..))" cannot be
|
||||||
// matched.
|
// matched.
|
||||||
|
|
||||||
|
// Strong versions:
|
||||||
|
|
||||||
instruct compareAndSwapI_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
|
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)));
|
match(Set res (CompareAndSwapI mem_ptr (Binary src1 src2)));
|
||||||
effect(TEMP cr0);
|
effect(TEMP cr0);
|
||||||
@ -7562,8 +7580,13 @@ instruct compareAndSwapI_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc
|
|||||||
// TODO: PPC port $archOpcode(ppc64Opcode_compound);
|
// TODO: PPC port $archOpcode(ppc64Opcode_compound);
|
||||||
// CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
|
// CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
|
||||||
__ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
|
__ 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);
|
$res$$Register, true);
|
||||||
|
if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
|
||||||
|
__ isync();
|
||||||
|
} else {
|
||||||
|
__ sync();
|
||||||
|
}
|
||||||
%}
|
%}
|
||||||
ins_pipe(pipe_class_default);
|
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);
|
// TODO: PPC port $archOpcode(ppc64Opcode_compound);
|
||||||
// CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
|
// CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
|
||||||
__ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
|
__ 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);
|
$res$$Register, true);
|
||||||
|
if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
|
||||||
|
__ isync();
|
||||||
|
} else {
|
||||||
|
__ sync();
|
||||||
|
}
|
||||||
%}
|
%}
|
||||||
ins_pipe(pipe_class_default);
|
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);
|
// TODO: PPC port $archOpcode(ppc64Opcode_compound);
|
||||||
// CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
|
// CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
|
||||||
__ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
|
__ 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);
|
$res$$Register, NULL, true);
|
||||||
|
if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
|
||||||
|
__ isync();
|
||||||
|
} else {
|
||||||
|
__ sync();
|
||||||
|
}
|
||||||
%}
|
%}
|
||||||
ins_pipe(pipe_class_default);
|
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);
|
// TODO: PPC port $archOpcode(ppc64Opcode_compound);
|
||||||
// CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
|
// CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
|
||||||
__ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
|
__ 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);
|
$res$$Register, NULL, true);
|
||||||
|
if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
|
||||||
|
__ isync();
|
||||||
|
} else {
|
||||||
|
__ sync();
|
||||||
|
}
|
||||||
%}
|
%}
|
||||||
ins_pipe(pipe_class_default);
|
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) %{
|
instruct getAndAddI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{
|
||||||
match(Set res (GetAndAddI mem_ptr src));
|
match(Set res (GetAndAddI mem_ptr src));
|
||||||
effect(TEMP cr0);
|
effect(TEMP cr0);
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
|
* 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.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -562,10 +562,16 @@ address TemplateInterpreterGenerator::generate_Reference_get_entry(void) {
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Actually we should never reach here since we do stack overflow checks before pushing any frame.
|
|
||||||
address TemplateInterpreterGenerator::generate_StackOverflowError_handler() {
|
address TemplateInterpreterGenerator::generate_StackOverflowError_handler() {
|
||||||
address entry = __ pc();
|
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;
|
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,
|
// 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
|
// 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
|
// 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
|
// 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
|
// 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.
|
// 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.
|
// 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.
|
// Enlarge by locals-parameters (not in case of native_call), shrink by ESP-SP-ABI48.
|
||||||
|
|
||||||
{
|
if (!native_call) {
|
||||||
// --------------------------------------------------------------------------
|
// --------------------------------------------------------------------------
|
||||||
// Stack overflow check
|
// 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(R26_monitor, R1_SP, - frame::ijava_state_size);
|
||||||
__ addi(R15_esp, R26_monitor, - Interpreter::stackElementSize);
|
__ 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);
|
__ load_mirror(R12_scratch2, R19_method);
|
||||||
|
|
||||||
// Store values.
|
// Store values.
|
||||||
@ -1133,6 +1139,29 @@ address TemplateInterpreterGenerator::generate_math_entry(AbstractInterpreter::M
|
|||||||
return entry;
|
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)
|
// Interpreter stub for calling a native method. (asm interpreter)
|
||||||
// This sets up a somewhat different looking stack for calling the
|
// This sets up a somewhat different looking stack for calling the
|
||||||
// native method than the typical interpreter frame setup.
|
// 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
|
// This is not a full-blown interpreter frame, but in particular, the
|
||||||
// following registers are valid after this:
|
// following registers are valid after this:
|
||||||
// - R19_method
|
// - 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)
|
// abstract stack (grows up)
|
||||||
// [ IJava (caller of JNI callee) ] <-- ASP
|
// [ 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);
|
generate_counter_incr(&invocation_counter_overflow, NULL, NULL);
|
||||||
|
|
||||||
BIND(continue_after_compile);
|
BIND(continue_after_compile);
|
||||||
|
}
|
||||||
|
|
||||||
|
bang_stack_shadow_pages(true);
|
||||||
|
|
||||||
|
if (inc_counter) {
|
||||||
// Reset the _do_not_unlock_if_synchronized flag.
|
// Reset the _do_not_unlock_if_synchronized flag.
|
||||||
if (synchronized) {
|
if (synchronized) {
|
||||||
__ li(R0, 0);
|
__ 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.
|
Register Rsize_of_parameters = R4_ARG2, // Written by generate_fixed_frame.
|
||||||
Rsize_of_locals = R5_ARG3; // 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);
|
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);
|
__ bind(profile_method_continue);
|
||||||
|
}
|
||||||
|
|
||||||
|
bang_stack_shadow_pages(false);
|
||||||
|
|
||||||
|
if (inc_counter || ProfileInterpreter) {
|
||||||
// Reset the _do_not_unlock_if_synchronized flag.
|
// Reset the _do_not_unlock_if_synchronized flag.
|
||||||
if (synchronized) {
|
if (synchronized) {
|
||||||
__ li(R0, 0);
|
__ li(R0, 0);
|
||||||
|
@ -101,10 +101,15 @@ void CompiledStaticCall::set_to_interpreted(methodHandle callee, address entry)
|
|||||||
NativeMovConstReg* method_holder = nativeMovConstReg_at(stub);
|
NativeMovConstReg* method_holder = nativeMovConstReg_at(stub);
|
||||||
NativeJump* jump = nativeJump_at(method_holder->next_instruction_address());
|
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");
|
"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");
|
"b) MT-unsafe modification of inline cache");
|
||||||
|
#endif
|
||||||
|
|
||||||
// Update stub.
|
// Update stub.
|
||||||
method_holder->set_data((intptr_t)callee());
|
method_holder->set_data((intptr_t)callee());
|
||||||
|
@ -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) {
|
void MacroAssembler::call_VM_leaf(address entry_point, int number_of_arguments) {
|
||||||
call_VM_leaf_base(entry_point, number_of_arguments);
|
call_VM_leaf_base(entry_point, number_of_arguments);
|
||||||
}
|
}
|
||||||
@ -5629,235 +5634,6 @@ void MacroAssembler::incr_allocated_bytes(Register thread,
|
|||||||
#endif
|
#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.
|
// Look up the method for a megamorphic invokeinterface call.
|
||||||
// The target method is determined by <intf_klass, itable_index>.
|
// The target method is determined by <intf_klass, itable_index>.
|
||||||
// The receiver klass is in recv_klass.
|
// The receiver klass is in recv_klass.
|
||||||
|
@ -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, 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 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,
|
void call_VM_leaf(address entry_point,
|
||||||
int number_of_arguments = 0);
|
int number_of_arguments = 0);
|
||||||
void call_VM_leaf(address entry_point,
|
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 cmpss2int(XMMRegister opr1, XMMRegister opr2, Register dst, bool unordered_is_less);
|
||||||
void cmpsd2int(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
|
// branch to L if FPU flag C2 is set/not set
|
||||||
// tmp is a temporary register, if none is available use noreg
|
// tmp is a temporary register, if none is available use noreg
|
||||||
void jC2 (Register tmp, Label& L);
|
void jC2 (Register tmp, Label& L);
|
||||||
@ -1036,9 +1028,6 @@ class MacroAssembler: public Assembler {
|
|||||||
|
|
||||||
private:
|
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
|
// these are private because users should be doing movflt/movdbl
|
||||||
|
|
||||||
void movss(Address dst, XMMRegister src) { Assembler::movss(dst, src); }
|
void movss(Address dst, XMMRegister src) { Assembler::movss(dst, src); }
|
||||||
|
@ -3858,23 +3858,48 @@ class StubGenerator: public StubCodeGenerator {
|
|||||||
StubRoutines::_updateBytesCRC32C = generate_updateBytesCRC32C(supports_clmul);
|
StubRoutines::_updateBytesCRC32C = generate_updateBytesCRC32C(supports_clmul);
|
||||||
}
|
}
|
||||||
if (VM_Version::supports_sse2() && UseLibmIntrinsic) {
|
if (VM_Version::supports_sse2() && UseLibmIntrinsic) {
|
||||||
|
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::_L_2il0floatpacket_0_adr = (address)StubRoutines::x86::_L_2il0floatpacket_0;
|
||||||
StubRoutines::x86::_Pi4Inv_adr = (address)StubRoutines::x86::_Pi4Inv;
|
StubRoutines::x86::_Pi4Inv_adr = (address)StubRoutines::x86::_Pi4Inv;
|
||||||
StubRoutines::x86::_Pi4x3_adr = (address)StubRoutines::x86::_Pi4x3;
|
StubRoutines::x86::_Pi4x3_adr = (address)StubRoutines::x86::_Pi4x3;
|
||||||
StubRoutines::x86::_Pi4x4_adr = (address)StubRoutines::x86::_Pi4x4;
|
StubRoutines::x86::_Pi4x4_adr = (address)StubRoutines::x86::_Pi4x4;
|
||||||
StubRoutines::x86::_ones_adr = (address)StubRoutines::x86::_ones;
|
StubRoutines::x86::_ones_adr = (address)StubRoutines::x86::_ones;
|
||||||
|
}
|
||||||
|
if (vmIntrinsics::is_intrinsic_available(vmIntrinsics::_dexp)) {
|
||||||
StubRoutines::_dexp = generate_libmExp();
|
StubRoutines::_dexp = generate_libmExp();
|
||||||
|
}
|
||||||
|
if (vmIntrinsics::is_intrinsic_available(vmIntrinsics::_dlog)) {
|
||||||
StubRoutines::_dlog = generate_libmLog();
|
StubRoutines::_dlog = generate_libmLog();
|
||||||
|
}
|
||||||
|
if (vmIntrinsics::is_intrinsic_available(vmIntrinsics::_dlog10)) {
|
||||||
StubRoutines::_dlog10 = generate_libmLog10();
|
StubRoutines::_dlog10 = generate_libmLog10();
|
||||||
|
}
|
||||||
|
if (vmIntrinsics::is_intrinsic_available(vmIntrinsics::_dpow)) {
|
||||||
StubRoutines::_dpow = generate_libmPow();
|
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();
|
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();
|
StubRoutines::_dlibm_sin_cos_huge = generate_libm_sin_cos_huge();
|
||||||
|
}
|
||||||
|
if (vmIntrinsics::is_intrinsic_available(vmIntrinsics::_dsin)) {
|
||||||
StubRoutines::_dsin = generate_libmSin();
|
StubRoutines::_dsin = generate_libmSin();
|
||||||
|
}
|
||||||
|
if (vmIntrinsics::is_intrinsic_available(vmIntrinsics::_dcos)) {
|
||||||
StubRoutines::_dcos = generate_libmCos();
|
StubRoutines::_dcos = generate_libmCos();
|
||||||
|
}
|
||||||
|
if (vmIntrinsics::is_intrinsic_available(vmIntrinsics::_dtan)) {
|
||||||
StubRoutines::_dlibm_tan_cot_huge = generate_libm_tan_cot_huge();
|
StubRoutines::_dlibm_tan_cot_huge = generate_libm_tan_cot_huge();
|
||||||
StubRoutines::_dtan = generate_libmTan();
|
StubRoutines::_dtan = generate_libmTan();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void generate_all() {
|
void generate_all() {
|
||||||
// Generates all stubs and initializes the entry points
|
// Generates all stubs and initializes the entry points
|
||||||
|
@ -5128,6 +5128,9 @@ class StubGenerator: public StubCodeGenerator {
|
|||||||
StubRoutines::_updateBytesCRC32C = generate_updateBytesCRC32C(supports_clmul);
|
StubRoutines::_updateBytesCRC32C = generate_updateBytesCRC32C(supports_clmul);
|
||||||
}
|
}
|
||||||
if (VM_Version::supports_sse2() && UseLibmIntrinsic) {
|
if (VM_Version::supports_sse2() && UseLibmIntrinsic) {
|
||||||
|
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::_ONEHALF_adr = (address)StubRoutines::x86::_ONEHALF;
|
||||||
StubRoutines::x86::_P_2_adr = (address)StubRoutines::x86::_P_2;
|
StubRoutines::x86::_P_2_adr = (address)StubRoutines::x86::_P_2;
|
||||||
StubRoutines::x86::_SC_4_adr = (address)StubRoutines::x86::_SC_4;
|
StubRoutines::x86::_SC_4_adr = (address)StubRoutines::x86::_SC_4;
|
||||||
@ -5142,14 +5145,29 @@ class StubGenerator: public StubCodeGenerator {
|
|||||||
StubRoutines::x86::_P_1_adr = (address)StubRoutines::x86::_P_1;
|
StubRoutines::x86::_P_1_adr = (address)StubRoutines::x86::_P_1;
|
||||||
StubRoutines::x86::_P_3_adr = (address)StubRoutines::x86::_P_3;
|
StubRoutines::x86::_P_3_adr = (address)StubRoutines::x86::_P_3;
|
||||||
StubRoutines::x86::_NEG_ZERO_adr = (address)StubRoutines::x86::_NEG_ZERO;
|
StubRoutines::x86::_NEG_ZERO_adr = (address)StubRoutines::x86::_NEG_ZERO;
|
||||||
|
}
|
||||||
|
if (vmIntrinsics::is_intrinsic_available(vmIntrinsics::_dexp)) {
|
||||||
StubRoutines::_dexp = generate_libmExp();
|
StubRoutines::_dexp = generate_libmExp();
|
||||||
|
}
|
||||||
|
if (vmIntrinsics::is_intrinsic_available(vmIntrinsics::_dlog)) {
|
||||||
StubRoutines::_dlog = generate_libmLog();
|
StubRoutines::_dlog = generate_libmLog();
|
||||||
|
}
|
||||||
|
if (vmIntrinsics::is_intrinsic_available(vmIntrinsics::_dlog10)) {
|
||||||
StubRoutines::_dlog10 = generate_libmLog10();
|
StubRoutines::_dlog10 = generate_libmLog10();
|
||||||
|
}
|
||||||
|
if (vmIntrinsics::is_intrinsic_available(vmIntrinsics::_dpow)) {
|
||||||
StubRoutines::_dpow = generate_libmPow();
|
StubRoutines::_dpow = generate_libmPow();
|
||||||
StubRoutines::_dtan = generate_libmTan();
|
}
|
||||||
|
if (vmIntrinsics::is_intrinsic_available(vmIntrinsics::_dsin)) {
|
||||||
StubRoutines::_dsin = generate_libmSin();
|
StubRoutines::_dsin = generate_libmSin();
|
||||||
|
}
|
||||||
|
if (vmIntrinsics::is_intrinsic_available(vmIntrinsics::_dcos)) {
|
||||||
StubRoutines::_dcos = generate_libmCos();
|
StubRoutines::_dcos = generate_libmCos();
|
||||||
}
|
}
|
||||||
|
if (vmIntrinsics::is_intrinsic_available(vmIntrinsics::_dtan)) {
|
||||||
|
StubRoutines::_dtan = generate_libmTan();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void generate_all() {
|
void generate_all() {
|
||||||
|
@ -350,7 +350,7 @@ address TemplateInterpreterGenerator::generate_math_entry(AbstractInterpreter::M
|
|||||||
if (VM_Version::supports_sse2() && StubRoutines::dsin() != NULL) {
|
if (VM_Version::supports_sse2() && StubRoutines::dsin() != NULL) {
|
||||||
__ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::dsin())));
|
__ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::dsin())));
|
||||||
} else {
|
} else {
|
||||||
__ call(RuntimeAddress(CAST_FROM_FN_PTR(address, SharedRuntime::dsin)));
|
__ call_VM_leaf0(CAST_FROM_FN_PTR(address, SharedRuntime::dsin));
|
||||||
}
|
}
|
||||||
__ addptr(rsp, 2 * wordSize);
|
__ addptr(rsp, 2 * wordSize);
|
||||||
break;
|
break;
|
||||||
@ -360,7 +360,7 @@ address TemplateInterpreterGenerator::generate_math_entry(AbstractInterpreter::M
|
|||||||
if (VM_Version::supports_sse2() && StubRoutines::dcos() != NULL) {
|
if (VM_Version::supports_sse2() && StubRoutines::dcos() != NULL) {
|
||||||
__ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::dcos())));
|
__ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::dcos())));
|
||||||
} else {
|
} else {
|
||||||
__ call(RuntimeAddress(CAST_FROM_FN_PTR(address, SharedRuntime::dcos)));
|
__ call_VM_leaf0(CAST_FROM_FN_PTR(address, SharedRuntime::dcos));
|
||||||
}
|
}
|
||||||
__ addptr(rsp, 2 * wordSize);
|
__ addptr(rsp, 2 * wordSize);
|
||||||
break;
|
break;
|
||||||
@ -370,7 +370,7 @@ address TemplateInterpreterGenerator::generate_math_entry(AbstractInterpreter::M
|
|||||||
if (StubRoutines::dtan() != NULL) {
|
if (StubRoutines::dtan() != NULL) {
|
||||||
__ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::dtan())));
|
__ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::dtan())));
|
||||||
} else {
|
} else {
|
||||||
__ call(RuntimeAddress(CAST_FROM_FN_PTR(address, SharedRuntime::dtan)));
|
__ call_VM_leaf0(CAST_FROM_FN_PTR(address, SharedRuntime::dtan));
|
||||||
}
|
}
|
||||||
__ addptr(rsp, 2 * wordSize);
|
__ addptr(rsp, 2 * wordSize);
|
||||||
break;
|
break;
|
||||||
@ -386,7 +386,7 @@ address TemplateInterpreterGenerator::generate_math_entry(AbstractInterpreter::M
|
|||||||
if (StubRoutines::dlog() != NULL) {
|
if (StubRoutines::dlog() != NULL) {
|
||||||
__ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::dlog())));
|
__ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::dlog())));
|
||||||
} else {
|
} else {
|
||||||
__ call(RuntimeAddress(CAST_FROM_FN_PTR(address, SharedRuntime::dlog)));
|
__ call_VM_leaf0(CAST_FROM_FN_PTR(address, SharedRuntime::dlog));
|
||||||
}
|
}
|
||||||
__ addptr(rsp, 2 * wordSize);
|
__ addptr(rsp, 2 * wordSize);
|
||||||
break;
|
break;
|
||||||
@ -396,7 +396,7 @@ address TemplateInterpreterGenerator::generate_math_entry(AbstractInterpreter::M
|
|||||||
if (StubRoutines::dlog10() != NULL) {
|
if (StubRoutines::dlog10() != NULL) {
|
||||||
__ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::dlog10())));
|
__ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::dlog10())));
|
||||||
} else {
|
} else {
|
||||||
__ call(RuntimeAddress(CAST_FROM_FN_PTR(address, SharedRuntime::dlog10)));
|
__ call_VM_leaf0(CAST_FROM_FN_PTR(address, SharedRuntime::dlog10));
|
||||||
}
|
}
|
||||||
__ addptr(rsp, 2 * wordSize);
|
__ addptr(rsp, 2 * wordSize);
|
||||||
break;
|
break;
|
||||||
@ -408,7 +408,7 @@ address TemplateInterpreterGenerator::generate_math_entry(AbstractInterpreter::M
|
|||||||
if (StubRoutines::dpow() != NULL) {
|
if (StubRoutines::dpow() != NULL) {
|
||||||
__ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::dpow())));
|
__ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::dpow())));
|
||||||
} else {
|
} else {
|
||||||
__ call(RuntimeAddress(CAST_FROM_FN_PTR(address, SharedRuntime::dpow)));
|
__ call_VM_leaf0(CAST_FROM_FN_PTR(address, SharedRuntime::dpow));
|
||||||
}
|
}
|
||||||
__ addptr(rsp, 4 * wordSize);
|
__ addptr(rsp, 4 * wordSize);
|
||||||
break;
|
break;
|
||||||
@ -418,7 +418,7 @@ address TemplateInterpreterGenerator::generate_math_entry(AbstractInterpreter::M
|
|||||||
if (StubRoutines::dexp() != NULL) {
|
if (StubRoutines::dexp() != NULL) {
|
||||||
__ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::dexp())));
|
__ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::dexp())));
|
||||||
} else {
|
} else {
|
||||||
__ call(RuntimeAddress(CAST_FROM_FN_PTR(address, SharedRuntime::dexp)));
|
__ call_VM_leaf0(CAST_FROM_FN_PTR(address, SharedRuntime::dexp));
|
||||||
}
|
}
|
||||||
__ addptr(rsp, 2*wordSize);
|
__ addptr(rsp, 2*wordSize);
|
||||||
break;
|
break;
|
||||||
|
@ -377,35 +377,35 @@ address TemplateInterpreterGenerator::generate_math_entry(AbstractInterpreter::M
|
|||||||
if (StubRoutines::dexp() != NULL) {
|
if (StubRoutines::dexp() != NULL) {
|
||||||
__ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::dexp())));
|
__ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::dexp())));
|
||||||
} else {
|
} 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) {
|
} else if (kind == Interpreter::java_lang_math_log) {
|
||||||
__ movdbl(xmm0, Address(rsp, wordSize));
|
__ movdbl(xmm0, Address(rsp, wordSize));
|
||||||
if (StubRoutines::dlog() != NULL) {
|
if (StubRoutines::dlog() != NULL) {
|
||||||
__ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::dlog())));
|
__ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::dlog())));
|
||||||
} else {
|
} 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) {
|
} else if (kind == Interpreter::java_lang_math_log10) {
|
||||||
__ movdbl(xmm0, Address(rsp, wordSize));
|
__ movdbl(xmm0, Address(rsp, wordSize));
|
||||||
if (StubRoutines::dlog10() != NULL) {
|
if (StubRoutines::dlog10() != NULL) {
|
||||||
__ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::dlog10())));
|
__ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::dlog10())));
|
||||||
} else {
|
} 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) {
|
} else if (kind == Interpreter::java_lang_math_sin) {
|
||||||
__ movdbl(xmm0, Address(rsp, wordSize));
|
__ movdbl(xmm0, Address(rsp, wordSize));
|
||||||
if (StubRoutines::dsin() != NULL) {
|
if (StubRoutines::dsin() != NULL) {
|
||||||
__ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::dsin())));
|
__ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::dsin())));
|
||||||
} else {
|
} 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) {
|
} else if (kind == Interpreter::java_lang_math_cos) {
|
||||||
__ movdbl(xmm0, Address(rsp, wordSize));
|
__ movdbl(xmm0, Address(rsp, wordSize));
|
||||||
if (StubRoutines::dcos() != NULL) {
|
if (StubRoutines::dcos() != NULL) {
|
||||||
__ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::dcos())));
|
__ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::dcos())));
|
||||||
} else {
|
} 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) {
|
} else if (kind == Interpreter::java_lang_math_pow) {
|
||||||
__ movdbl(xmm1, Address(rsp, wordSize));
|
__ movdbl(xmm1, Address(rsp, wordSize));
|
||||||
@ -413,14 +413,14 @@ address TemplateInterpreterGenerator::generate_math_entry(AbstractInterpreter::M
|
|||||||
if (StubRoutines::dpow() != NULL) {
|
if (StubRoutines::dpow() != NULL) {
|
||||||
__ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::dpow())));
|
__ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::dpow())));
|
||||||
} else {
|
} 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) {
|
} else if (kind == Interpreter::java_lang_math_tan) {
|
||||||
__ movdbl(xmm0, Address(rsp, wordSize));
|
__ movdbl(xmm0, Address(rsp, wordSize));
|
||||||
if (StubRoutines::dtan() != NULL) {
|
if (StubRoutines::dtan() != NULL) {
|
||||||
__ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::dtan())));
|
__ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::dtan())));
|
||||||
} else {
|
} else {
|
||||||
__ call(RuntimeAddress(CAST_FROM_FN_PTR(address, SharedRuntime::dtan)));
|
__ call_VM_leaf0(CAST_FROM_FN_PTR(address, SharedRuntime::dtan));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
__ fld_d(Address(rsp, wordSize));
|
__ fld_d(Address(rsp, wordSize));
|
||||||
@ -428,7 +428,7 @@ address TemplateInterpreterGenerator::generate_math_entry(AbstractInterpreter::M
|
|||||||
case Interpreter::java_lang_math_abs:
|
case Interpreter::java_lang_math_abs:
|
||||||
__ fabs();
|
__ fabs();
|
||||||
break;
|
break;
|
||||||
default :
|
default:
|
||||||
ShouldNotReachHere();
|
ShouldNotReachHere();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -447,3 +447,4 @@ address TemplateInterpreterGenerator::generate_math_entry(AbstractInterpreter::M
|
|||||||
|
|
||||||
return entry_point;
|
return entry_point;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1712,6 +1712,7 @@ public class CommandProcessor {
|
|||||||
// called after debuggee attach
|
// called after debuggee attach
|
||||||
private void postAttach() {
|
private void postAttach() {
|
||||||
// create JavaScript engine and start it
|
// create JavaScript engine and start it
|
||||||
|
try {
|
||||||
jsengine = new JSJavaScriptEngine() {
|
jsengine = new JSJavaScriptEngine() {
|
||||||
private ObjectReader reader = new ObjectReader();
|
private ObjectReader reader = new ObjectReader();
|
||||||
private JSJavaFactory factory = new JSJavaFactoryImpl();
|
private JSJavaFactory factory = new JSJavaFactoryImpl();
|
||||||
@ -1747,6 +1748,13 @@ public class CommandProcessor {
|
|||||||
}
|
}
|
||||||
jsengine.start();
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void registerCommand(String cmd, String usage, final String func) {
|
public void registerCommand(String cmd, String usage, final String func) {
|
||||||
commands.put(cmd, new Command(cmd, usage, false) {
|
commands.put(cmd, new Command(cmd, usage, false) {
|
||||||
|
@ -45,12 +45,7 @@ public enum AArch64Kind implements PlatformKind {
|
|||||||
V128_DWORD(16, DWORD),
|
V128_DWORD(16, DWORD),
|
||||||
V128_QWORD(16, QWORD),
|
V128_QWORD(16, QWORD),
|
||||||
V128_SINGLE(16, SINGLE),
|
V128_SINGLE(16, SINGLE),
|
||||||
V128_DOUBLE(16, DOUBLE),
|
V128_DOUBLE(16, DOUBLE);
|
||||||
|
|
||||||
MASK8(1),
|
|
||||||
MASK16(2),
|
|
||||||
MASK32(4),
|
|
||||||
MASK64(8);
|
|
||||||
|
|
||||||
private final int size;
|
private final int size;
|
||||||
private final int vectorLength;
|
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() {
|
public char getTypeChar() {
|
||||||
switch (this) {
|
switch (this) {
|
||||||
case BYTE:
|
case BYTE:
|
||||||
@ -159,11 +142,6 @@ public enum AArch64Kind implements PlatformKind {
|
|||||||
case V128_SINGLE:
|
case V128_SINGLE:
|
||||||
case V128_DOUBLE:
|
case V128_DOUBLE:
|
||||||
return 'v';
|
return 'v';
|
||||||
case MASK8:
|
|
||||||
case MASK16:
|
|
||||||
case MASK32:
|
|
||||||
case MASK64:
|
|
||||||
return 'k';
|
|
||||||
default:
|
default:
|
||||||
return '-';
|
return '-';
|
||||||
}
|
}
|
||||||
|
@ -98,6 +98,11 @@ public class BytecodeFrame extends BytecodePosition {
|
|||||||
*/
|
*/
|
||||||
public final boolean rethrowException;
|
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;
|
public final boolean duringCall;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -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.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -417,7 +417,7 @@ public class CodeUtil {
|
|||||||
/**
|
/**
|
||||||
* Create a calling convention from a {@link ResolvedJavaMethod}.
|
* 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();
|
Signature sig = method.getSignature();
|
||||||
JavaType retType = sig.getReturnType(null);
|
JavaType retType = sig.getReturnType(null);
|
||||||
int sigCount = sig.getParameterCount(false);
|
int sigCount = sig.getParameterCount(false);
|
||||||
@ -434,6 +434,6 @@ public class CodeUtil {
|
|||||||
}
|
}
|
||||||
|
|
||||||
RegisterConfig registerConfig = codeCache.getRegisterConfig();
|
RegisterConfig registerConfig = codeCache.getRegisterConfig();
|
||||||
return registerConfig.getCallingConvention(type, retType, argTypes, codeCache.getTarget());
|
return registerConfig.getCallingConvention(type, retType, argTypes, valueKindFactory);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -23,49 +23,15 @@
|
|||||||
package jdk.vm.ci.code;
|
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;
|
Object getFailure();
|
||||||
|
|
||||||
/**
|
|
||||||
* 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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -23,7 +23,9 @@
|
|||||||
package jdk.vm.ci.code;
|
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 {
|
public interface CompiledCode {
|
||||||
}
|
}
|
||||||
|
@ -25,8 +25,8 @@ package jdk.vm.ci.code;
|
|||||||
/**
|
/**
|
||||||
* Constants and intrinsic definition for memory barriers.
|
* Constants and intrinsic definition for memory barriers.
|
||||||
*
|
*
|
||||||
* The documentation for each constant is taken from Doug Lea's <a
|
* The documentation for each constant is taken from Doug Lea's
|
||||||
* href="http://gee.cs.oswego.edu/dl/jmm/cookbook.html">The JSR-133 Cookbook for Compiler
|
* <a href="http://gee.cs.oswego.edu/dl/jmm/cookbook.html">The JSR-133 Cookbook for Compiler
|
||||||
* Writers</a>.
|
* Writers</a>.
|
||||||
* <p>
|
* <p>
|
||||||
* The {@code JMM_*} constants capture the memory barriers necessary to implement the Java Memory
|
* The {@code JMM_*} constants capture the memory barriers necessary to implement the Java Memory
|
||||||
|
@ -22,5 +22,10 @@
|
|||||||
*/
|
*/
|
||||||
package jdk.vm.ci.code;
|
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 {
|
public abstract class ReferenceMap {
|
||||||
}
|
}
|
||||||
|
@ -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.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -22,8 +22,7 @@
|
|||||||
*/
|
*/
|
||||||
package jdk.vm.ci.code;
|
package jdk.vm.ci.code;
|
||||||
|
|
||||||
import jdk.vm.ci.meta.JavaKind;
|
import jdk.vm.ci.meta.ValueKind;
|
||||||
import jdk.vm.ci.meta.LIRKind;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a target machine register.
|
* 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);
|
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
|
* 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;
|
public final int number;
|
||||||
|
|
||||||
@ -144,17 +135,17 @@ public final class Register implements Comparable<Register> {
|
|||||||
* @param kind the specified kind
|
* @param kind the specified kind
|
||||||
* @return the {@link RegisterValue}
|
* @return the {@link RegisterValue}
|
||||||
*/
|
*/
|
||||||
public RegisterValue asValue(LIRKind kind) {
|
public RegisterValue asValue(ValueKind<?> kind) {
|
||||||
return new RegisterValue(kind, this);
|
return new RegisterValue(kind, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets this register as a {@linkplain RegisterValue value} with no particular kind.
|
* 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() {
|
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;
|
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
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return name;
|
return name;
|
||||||
|
@ -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.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -26,6 +26,7 @@ import jdk.vm.ci.code.CallingConvention.Type;
|
|||||||
import jdk.vm.ci.meta.JavaKind;
|
import jdk.vm.ci.meta.JavaKind;
|
||||||
import jdk.vm.ci.meta.JavaType;
|
import jdk.vm.ci.meta.JavaType;
|
||||||
import jdk.vm.ci.meta.PlatformKind;
|
import jdk.vm.ci.meta.PlatformKind;
|
||||||
|
import jdk.vm.ci.meta.ValueKind;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A register configuration binds roles and {@linkplain RegisterAttributes attributes} to physical
|
* 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();
|
Register getFrameRegister();
|
||||||
|
|
||||||
@ -56,9 +58,9 @@ public interface RegisterConfig {
|
|||||||
* @param type the type of calling convention being requested
|
* @param type the type of calling convention being requested
|
||||||
* @param returnType the return type (can be null for methods returning {@code void})
|
* @param returnType the return type (can be null for methods returning {@code void})
|
||||||
* @param parameterTypes the types of the arguments of the call
|
* @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
|
* 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();
|
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
|
* Determines if all {@link #getAllocatableRegisters() allocatable} registers are
|
||||||
* {@link #getCallerSaveRegisters() caller saved}.
|
* {@link #getCallerSaveRegisters() caller saved}.
|
||||||
|
@ -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.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -23,23 +23,16 @@
|
|||||||
package jdk.vm.ci.code;
|
package jdk.vm.ci.code;
|
||||||
|
|
||||||
import jdk.vm.ci.meta.AllocatableValue;
|
import jdk.vm.ci.meta.AllocatableValue;
|
||||||
import jdk.vm.ci.meta.JavaKind;
|
import jdk.vm.ci.meta.ValueKind;
|
||||||
import jdk.vm.ci.meta.LIRKind;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Denotes a register that stores a value of a fixed kind. There is exactly one (canonical) instance
|
* Denotes a register that stores a value of a fixed kind.
|
||||||
* 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.
|
|
||||||
*/
|
*/
|
||||||
public final class RegisterValue extends AllocatableValue {
|
public final class RegisterValue extends AllocatableValue {
|
||||||
|
|
||||||
private final Register reg;
|
private final Register reg;
|
||||||
|
|
||||||
/**
|
protected RegisterValue(ValueKind<?> kind, Register register) {
|
||||||
* Should only be called from {@link Register#Register} to ensure canonicalization.
|
|
||||||
*/
|
|
||||||
protected RegisterValue(LIRKind kind, Register register) {
|
|
||||||
super(kind);
|
super(kind);
|
||||||
this.reg = register;
|
this.reg = register;
|
||||||
}
|
}
|
||||||
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
@ -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.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -23,7 +23,7 @@
|
|||||||
package jdk.vm.ci.code;
|
package jdk.vm.ci.code;
|
||||||
|
|
||||||
import jdk.vm.ci.meta.AllocatableValue;
|
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
|
* 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
|
* @param addFrameSize Specifies if the offset is relative to the stack pointer, or the
|
||||||
* beginning of the frame (stack pointer + total frame size).
|
* 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;
|
assert addFrameSize || offset >= 0;
|
||||||
return new StackSlot(kind, offset, addFrameSize);
|
return new StackSlot(kind, offset, addFrameSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Private constructor to enforce use of {@link #get(LIRKind, int, boolean)} so that a cache can
|
* Private constructor to enforce use of {@link #get(ValueKind, int, boolean)} so that a cache
|
||||||
* be used.
|
* can be used.
|
||||||
*/
|
*/
|
||||||
private StackSlot(LIRKind kind, int offset, boolean addFrameSize) {
|
private StackSlot(ValueKind<?> kind, int offset, boolean addFrameSize) {
|
||||||
super(kind);
|
super(kind);
|
||||||
this.offset = offset;
|
this.offset = offset;
|
||||||
this.addFrameSize = addFrameSize;
|
this.addFrameSize = addFrameSize;
|
||||||
@ -99,7 +99,7 @@ public final class StackSlot extends AllocatableValue {
|
|||||||
public StackSlot asOutArg() {
|
public StackSlot asOutArg() {
|
||||||
assert offset >= 0;
|
assert offset >= 0;
|
||||||
if (addFrameSize) {
|
if (addFrameSize) {
|
||||||
return get(getLIRKind(), offset, false);
|
return get(getValueKind(), offset, false);
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@ -110,7 +110,7 @@ public final class StackSlot extends AllocatableValue {
|
|||||||
public StackSlot asInArg() {
|
public StackSlot asInArg() {
|
||||||
assert offset >= 0;
|
assert offset >= 0;
|
||||||
if (!addFrameSize) {
|
if (!addFrameSize) {
|
||||||
return get(getLIRKind(), offset, true);
|
return get(getValueKind(), offset, true);
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
@ -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.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -23,9 +23,8 @@
|
|||||||
package jdk.vm.ci.code;
|
package jdk.vm.ci.code;
|
||||||
|
|
||||||
import static jdk.vm.ci.meta.MetaUtil.identityHashCodeString;
|
import static jdk.vm.ci.meta.MetaUtil.identityHashCodeString;
|
||||||
|
|
||||||
import jdk.vm.ci.meta.JavaKind;
|
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
|
* 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;
|
public final JavaKind wordJavaKind;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The stack alignment requirement of the platform. For example, from Appendix D of <a
|
* The stack alignment requirement of the platform. For example, from Appendix D of
|
||||||
* href="http://www.intel.com/Assets/PDF/manual/248966.pdf">Intel 64 and IA-32 Architectures
|
* <a href="http://www.intel.com/Assets/PDF/manual/248966.pdf">Intel 64 and IA-32 Architectures
|
||||||
* Optimization Reference Manual</a>:
|
* Optimization Reference Manual</a>:
|
||||||
*
|
*
|
||||||
* <pre>
|
* <pre>
|
||||||
@ -118,13 +117,4 @@ public class TargetDescription {
|
|||||||
public String toString() {
|
public String toString() {
|
||||||
return identityHashCodeString(this);
|
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,34 @@
|
|||||||
|
/*
|
||||||
|
* 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.code;
|
||||||
|
|
||||||
|
import jdk.vm.ci.meta.JavaKind;
|
||||||
|
import jdk.vm.ci.meta.ValueKind;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Can be implemented by compilers to create custom {@link ValueKind} subclasses.
|
||||||
|
*/
|
||||||
|
public interface ValueKindFactory<K extends ValueKind<K>> {
|
||||||
|
|
||||||
|
K getValueKind(JavaKind javaKind);
|
||||||
|
}
|
@ -22,9 +22,6 @@
|
|||||||
*/
|
*/
|
||||||
package jdk.vm.ci.code;
|
package jdk.vm.ci.code;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import jdk.vm.ci.meta.AllocatableValue;
|
import jdk.vm.ci.meta.AllocatableValue;
|
||||||
import jdk.vm.ci.meta.JavaConstant;
|
import jdk.vm.ci.meta.JavaConstant;
|
||||||
import jdk.vm.ci.meta.JavaValue;
|
import jdk.vm.ci.meta.JavaValue;
|
||||||
@ -111,73 +108,4 @@ public final class ValueUtil {
|
|||||||
return asRegister(value);
|
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -21,10 +21,10 @@
|
|||||||
* questions.
|
* questions.
|
||||||
*/
|
*/
|
||||||
/**
|
/**
|
||||||
* Package that defines the interface between a Java application that wants to install code and the runtime.
|
* Package that defines the interface between a Java application that wants to install code and the
|
||||||
* The runtime provides in implementation of the {@link jdk.vm.ci.code.CodeCacheProvider} interface.
|
* runtime. The runtime provides in implementation of the {@link jdk.vm.ci.code.CodeCacheProvider}
|
||||||
* The method {@link jdk.vm.ci.code.CodeCacheProvider#addCode(jdk.vm.ci.meta.ResolvedJavaMethod, CompiledCode, jdk.vm.ci.meta.SpeculationLog, InstalledCode)}
|
* 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.
|
* can be used to install code.
|
||||||
*/
|
*/
|
||||||
package jdk.vm.ci.code;
|
package jdk.vm.ci.code;
|
||||||
|
|
||||||
|
@ -26,6 +26,10 @@ import java.util.Objects;
|
|||||||
|
|
||||||
import jdk.vm.ci.meta.VMConstant;
|
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 {
|
public final class ConstantReference extends Reference {
|
||||||
|
|
||||||
private final VMConstant constant;
|
private final VMConstant constant;
|
||||||
|
@ -24,12 +24,12 @@ package jdk.vm.ci.code.site;
|
|||||||
|
|
||||||
import java.util.Objects;
|
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
|
* 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 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 {
|
public final class DataPatch extends Site {
|
||||||
|
|
||||||
|
@ -22,6 +22,10 @@
|
|||||||
*/
|
*/
|
||||||
package jdk.vm.ci.code.site;
|
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 {
|
public final class DataSectionReference extends Reference {
|
||||||
|
|
||||||
private boolean initialized;
|
private boolean initialized;
|
||||||
|
@ -30,7 +30,6 @@ public enum InfopointReason {
|
|||||||
SAFEPOINT,
|
SAFEPOINT,
|
||||||
CALL,
|
CALL,
|
||||||
IMPLICIT_EXCEPTION,
|
IMPLICIT_EXCEPTION,
|
||||||
METASPACE_ACCESS,
|
|
||||||
METHOD_START,
|
METHOD_START,
|
||||||
METHOD_END,
|
METHOD_END,
|
||||||
BYTECODE_POSITION;
|
BYTECODE_POSITION;
|
||||||
|
@ -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.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -25,13 +25,23 @@ package jdk.vm.ci.code.site;
|
|||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a mark in the machine code that can be used by the runtime for its own purposes. A
|
* Associates arbitrary information with a position in machine code. For example, HotSpot specific
|
||||||
* mark can reference other marks.
|
* 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 {
|
public final class Mark extends Site {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An object denoting extra semantic information about the machine code position of this mark.
|
||||||
|
*/
|
||||||
public final Object id;
|
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) {
|
public Mark(int pcOffset, Object id) {
|
||||||
super(pcOffset);
|
super(pcOffset);
|
||||||
this.id = id;
|
this.id = id;
|
||||||
@ -40,7 +50,7 @@ public final class Mark extends Site {
|
|||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
if (id == null) {
|
if (id == null) {
|
||||||
return String.format("%d[<mar>]", pcOffset);
|
return String.format("%d[<mark>]", pcOffset);
|
||||||
} else if (id instanceof Integer) {
|
} else if (id instanceof Integer) {
|
||||||
return String.format("%d[<mark with id %s>]", pcOffset, Integer.toHexString((Integer) id));
|
return String.format("%d[<mark with id %s>]", pcOffset, Integer.toHexString((Integer) id));
|
||||||
} else {
|
} else {
|
||||||
|
@ -24,16 +24,19 @@ package jdk.vm.ci.code.stack;
|
|||||||
|
|
||||||
import jdk.vm.ci.meta.ResolvedJavaMethod;
|
import jdk.vm.ci.meta.ResolvedJavaMethod;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Access to the object variables in a stack frame.
|
||||||
|
*/
|
||||||
public interface InspectedFrame {
|
public interface InspectedFrame {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the value of the local at the given index. Currently only works for object values.
|
* Returns the value of the object local at {@code index}. This value is a copy iff
|
||||||
* This value is a copy iff {@link #isVirtual(int)} is true.
|
* {@link #isVirtual(int)} is true.
|
||||||
*/
|
*/
|
||||||
Object getLocal(int index);
|
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.
|
* returned by {@link #getLocal(int)} is a copy.
|
||||||
*/
|
*/
|
||||||
boolean isVirtual(int index);
|
boolean isVirtual(int index);
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
* or visit www.oracle.com if you need additional information or have any
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
* questions.
|
* questions.
|
||||||
*/
|
*/
|
||||||
package jdk.vm.ci.inittimer;
|
package jdk.vm.ci.common;
|
||||||
|
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
@ -31,7 +31,6 @@ import java.util.Locale;
|
|||||||
public class JVMCIError extends Error {
|
public class JVMCIError extends Error {
|
||||||
|
|
||||||
private static final long serialVersionUID = 531632331813456233L;
|
private static final long serialVersionUID = 531632331813456233L;
|
||||||
private final ArrayList<String> context = new ArrayList<>();
|
|
||||||
|
|
||||||
public static RuntimeException unimplemented() {
|
public static RuntimeException unimplemented() {
|
||||||
throw new JVMCIError("unimplemented");
|
throw new JVMCIError("unimplemented");
|
||||||
@ -101,27 +100,6 @@ public class JVMCIError extends Error {
|
|||||||
super(cause);
|
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) {
|
private static String format(String msg, Object... args) {
|
||||||
if (args != null) {
|
if (args != null) {
|
||||||
// expand Iterable parameters into a list representation
|
// expand Iterable parameters into a list representation
|
||||||
@ -137,13 +115,4 @@ public class JVMCIError extends Error {
|
|||||||
}
|
}
|
||||||
return String.format(Locale.ENGLISH, msg, args);
|
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));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -20,15 +20,15 @@
|
|||||||
* or visit www.oracle.com if you need additional information or have any
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
* questions.
|
* questions.
|
||||||
*/
|
*/
|
||||||
package jdk.vm.ci.inittimer;
|
package jdk.vm.ci.common;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used to suppress <a href="http://findbugs.sourceforge.net">FindBugs</a> warnings.
|
* Used to suppress <a href="http://findbugs.sourceforge.net">FindBugs</a> warnings.
|
||||||
*/
|
*/
|
||||||
public @interface SuppressFBWarnings {
|
@interface SuppressFBWarnings {
|
||||||
/**
|
/**
|
||||||
* The set of FindBugs <a
|
* The set of FindBugs
|
||||||
* href="http://findbugs.sourceforge.net/bugDescriptions.html">warnings</a> that are to be
|
* <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.
|
* suppressed in annotated element. The value can be a bug category, kind or pattern.
|
||||||
*/
|
*/
|
||||||
String[] value();
|
String[] value();
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -22,7 +22,7 @@
|
|||||||
*/
|
*/
|
||||||
package jdk.vm.ci.hotspot.aarch64;
|
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;
|
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.RegisterConfig;
|
||||||
import jdk.vm.ci.code.TargetDescription;
|
import jdk.vm.ci.code.TargetDescription;
|
||||||
import jdk.vm.ci.code.stack.StackIntrospection;
|
import jdk.vm.ci.code.stack.StackIntrospection;
|
||||||
|
import jdk.vm.ci.common.InitTimer;
|
||||||
import jdk.vm.ci.hotspot.HotSpotCodeCacheProvider;
|
import jdk.vm.ci.hotspot.HotSpotCodeCacheProvider;
|
||||||
import jdk.vm.ci.hotspot.HotSpotConstantReflectionProvider;
|
import jdk.vm.ci.hotspot.HotSpotConstantReflectionProvider;
|
||||||
import jdk.vm.ci.hotspot.HotSpotJVMCIBackendFactory;
|
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.HotSpotMetaAccessProvider;
|
||||||
import jdk.vm.ci.hotspot.HotSpotStackIntrospection;
|
import jdk.vm.ci.hotspot.HotSpotStackIntrospection;
|
||||||
import jdk.vm.ci.hotspot.HotSpotVMConfig;
|
import jdk.vm.ci.hotspot.HotSpotVMConfig;
|
||||||
import jdk.vm.ci.inittimer.InitTimer;
|
|
||||||
import jdk.vm.ci.meta.ConstantReflectionProvider;
|
import jdk.vm.ci.meta.ConstantReflectionProvider;
|
||||||
import jdk.vm.ci.runtime.JVMCIBackend;
|
import jdk.vm.ci.runtime.JVMCIBackend;
|
||||||
|
|
||||||
@ -68,7 +68,7 @@ public class AArch64HotSpotJVMCIBackendFactory implements HotSpotJVMCIBackendFac
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected RegisterConfig createRegisterConfig(HotSpotJVMCIRuntimeProvider runtime, TargetDescription target) {
|
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) {
|
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);
|
return new JVMCIBackend(metaAccess, codeCache, constantReflection, stackIntrospection);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -64,19 +64,20 @@ import jdk.vm.ci.code.RegisterAttributes;
|
|||||||
import jdk.vm.ci.code.RegisterConfig;
|
import jdk.vm.ci.code.RegisterConfig;
|
||||||
import jdk.vm.ci.code.StackSlot;
|
import jdk.vm.ci.code.StackSlot;
|
||||||
import jdk.vm.ci.code.TargetDescription;
|
import jdk.vm.ci.code.TargetDescription;
|
||||||
|
import jdk.vm.ci.code.ValueKindFactory;
|
||||||
import jdk.vm.ci.common.JVMCIError;
|
import jdk.vm.ci.common.JVMCIError;
|
||||||
import jdk.vm.ci.hotspot.HotSpotCallingConventionType;
|
import jdk.vm.ci.hotspot.HotSpotCallingConventionType;
|
||||||
import jdk.vm.ci.hotspot.HotSpotVMConfig;
|
import jdk.vm.ci.hotspot.HotSpotVMConfig;
|
||||||
import jdk.vm.ci.meta.AllocatableValue;
|
import jdk.vm.ci.meta.AllocatableValue;
|
||||||
import jdk.vm.ci.meta.JavaKind;
|
import jdk.vm.ci.meta.JavaKind;
|
||||||
import jdk.vm.ci.meta.JavaType;
|
import jdk.vm.ci.meta.JavaType;
|
||||||
import jdk.vm.ci.meta.LIRKind;
|
|
||||||
import jdk.vm.ci.meta.PlatformKind;
|
import jdk.vm.ci.meta.PlatformKind;
|
||||||
import jdk.vm.ci.meta.Value;
|
import jdk.vm.ci.meta.Value;
|
||||||
|
import jdk.vm.ci.meta.ValueKind;
|
||||||
|
|
||||||
public class AArch64HotSpotRegisterConfig implements RegisterConfig {
|
public class AArch64HotSpotRegisterConfig implements RegisterConfig {
|
||||||
|
|
||||||
private final Architecture architecture;
|
private final TargetDescription target;
|
||||||
|
|
||||||
private final Register[] allocatable;
|
private final Register[] allocatable;
|
||||||
|
|
||||||
@ -104,7 +105,7 @@ public class AArch64HotSpotRegisterConfig implements RegisterConfig {
|
|||||||
public Register[] filterAllocatableRegisters(PlatformKind kind, Register[] registers) {
|
public Register[] filterAllocatableRegisters(PlatformKind kind, Register[] registers) {
|
||||||
ArrayList<Register> list = new ArrayList<>();
|
ArrayList<Register> list = new ArrayList<>();
|
||||||
for (Register reg : registers) {
|
for (Register reg : registers) {
|
||||||
if (architecture.canStoreValue(reg.getRegisterCategory(), kind)) {
|
if (target.arch.canStoreValue(reg.getRegisterCategory(), kind)) {
|
||||||
list.add(reg);
|
list.add(reg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -159,13 +160,13 @@ public class AArch64HotSpotRegisterConfig implements RegisterConfig {
|
|||||||
return registers;
|
return registers;
|
||||||
}
|
}
|
||||||
|
|
||||||
public AArch64HotSpotRegisterConfig(Architecture architecture, HotSpotVMConfig config) {
|
public AArch64HotSpotRegisterConfig(TargetDescription target, HotSpotVMConfig config) {
|
||||||
this(architecture, config, initAllocatable(architecture, config.useCompressedOops));
|
this(target, config, initAllocatable(target.arch, config.useCompressedOops));
|
||||||
assert callerSaved.length >= allocatable.length;
|
assert callerSaved.length >= allocatable.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
public AArch64HotSpotRegisterConfig(Architecture architecture, HotSpotVMConfig config, Register[] allocatable) {
|
public AArch64HotSpotRegisterConfig(TargetDescription target, HotSpotVMConfig config, Register[] allocatable) {
|
||||||
this.architecture = architecture;
|
this.target = target;
|
||||||
this.maxFrameSize = config.maxFrameSize;
|
this.maxFrameSize = config.maxFrameSize;
|
||||||
|
|
||||||
this.allocatable = allocatable.clone();
|
this.allocatable = allocatable.clone();
|
||||||
@ -195,19 +196,14 @@ public class AArch64HotSpotRegisterConfig implements RegisterConfig {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Register getRegisterForRole(int index) {
|
public CallingConvention getCallingConvention(Type type, JavaType returnType, JavaType[] parameterTypes, ValueKindFactory<?> valueKindFactory) {
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public CallingConvention getCallingConvention(Type type, JavaType returnType, JavaType[] parameterTypes, TargetDescription target) {
|
|
||||||
HotSpotCallingConventionType hotspotType = (HotSpotCallingConventionType) type;
|
HotSpotCallingConventionType hotspotType = (HotSpotCallingConventionType) type;
|
||||||
if (type == HotSpotCallingConventionType.NativeCall) {
|
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
|
// On x64, parameter locations are the same whether viewed
|
||||||
// from the caller or callee perspective
|
// from the caller or callee perspective
|
||||||
return callingConvention(javaGeneralParameterRegisters, returnType, parameterTypes, hotspotType, target);
|
return callingConvention(javaGeneralParameterRegisters, returnType, parameterTypes, hotspotType, valueKindFactory);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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];
|
AllocatableValue[] locations = new AllocatableValue[parameterTypes.length];
|
||||||
|
|
||||||
int currentGeneral = 0;
|
int currentGeneral = 0;
|
||||||
@ -250,14 +247,14 @@ public class AArch64HotSpotRegisterConfig implements RegisterConfig {
|
|||||||
case Object:
|
case Object:
|
||||||
if (currentGeneral < generalParameterRegisters.length) {
|
if (currentGeneral < generalParameterRegisters.length) {
|
||||||
Register register = generalParameterRegisters[currentGeneral++];
|
Register register = generalParameterRegisters[currentGeneral++];
|
||||||
locations[i] = register.asValue(target.getLIRKind(kind));
|
locations[i] = register.asValue(valueKindFactory.getValueKind(kind));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case Float:
|
case Float:
|
||||||
case Double:
|
case Double:
|
||||||
if (currentSIMD < simdParameterRegisters.length) {
|
if (currentSIMD < simdParameterRegisters.length) {
|
||||||
Register register = simdParameterRegisters[currentSIMD++];
|
Register register = simdParameterRegisters[currentSIMD++];
|
||||||
locations[i] = register.asValue(target.getLIRKind(kind));
|
locations[i] = register.asValue(valueKindFactory.getValueKind(kind));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -265,14 +262,14 @@ public class AArch64HotSpotRegisterConfig implements RegisterConfig {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (locations[i] == null) {
|
if (locations[i] == null) {
|
||||||
LIRKind lirKind = target.getLIRKind(kind);
|
ValueKind<?> valueKind = valueKindFactory.getValueKind(kind);
|
||||||
locations[i] = StackSlot.get(lirKind, currentStackOffset, !type.out);
|
locations[i] = StackSlot.get(valueKind, currentStackOffset, !type.out);
|
||||||
currentStackOffset += Math.max(lirKind.getPlatformKind().getSizeInBytes(), target.wordSize);
|
currentStackOffset += Math.max(valueKind.getPlatformKind().getSizeInBytes(), target.wordSize);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
JavaKind returnKind = returnType == null ? JavaKind.Void : returnType.getJavaKind();
|
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);
|
return new CallingConvention(currentStackOffset, returnLocation, locations);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -22,7 +22,7 @@
|
|||||||
*/
|
*/
|
||||||
package jdk.vm.ci.hotspot.amd64;
|
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;
|
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.RegisterConfig;
|
||||||
import jdk.vm.ci.code.TargetDescription;
|
import jdk.vm.ci.code.TargetDescription;
|
||||||
import jdk.vm.ci.code.stack.StackIntrospection;
|
import jdk.vm.ci.code.stack.StackIntrospection;
|
||||||
|
import jdk.vm.ci.common.InitTimer;
|
||||||
import jdk.vm.ci.hotspot.HotSpotCodeCacheProvider;
|
import jdk.vm.ci.hotspot.HotSpotCodeCacheProvider;
|
||||||
import jdk.vm.ci.hotspot.HotSpotConstantReflectionProvider;
|
import jdk.vm.ci.hotspot.HotSpotConstantReflectionProvider;
|
||||||
import jdk.vm.ci.hotspot.HotSpotJVMCIBackendFactory;
|
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.HotSpotMetaAccessProvider;
|
||||||
import jdk.vm.ci.hotspot.HotSpotStackIntrospection;
|
import jdk.vm.ci.hotspot.HotSpotStackIntrospection;
|
||||||
import jdk.vm.ci.hotspot.HotSpotVMConfig;
|
import jdk.vm.ci.hotspot.HotSpotVMConfig;
|
||||||
import jdk.vm.ci.inittimer.InitTimer;
|
|
||||||
import jdk.vm.ci.meta.ConstantReflectionProvider;
|
import jdk.vm.ci.meta.ConstantReflectionProvider;
|
||||||
import jdk.vm.ci.runtime.JVMCIBackend;
|
import jdk.vm.ci.runtime.JVMCIBackend;
|
||||||
|
|
||||||
@ -152,7 +152,7 @@ public class AMD64HotSpotJVMCIBackendFactory implements HotSpotJVMCIBackendFacto
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected RegisterConfig createRegisterConfig(HotSpotJVMCIRuntimeProvider runtime, TargetDescription target) {
|
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) {
|
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);
|
return new JVMCIBackend(metaAccess, codeCache, constantReflection, stackIntrospection);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -56,19 +56,20 @@ import jdk.vm.ci.code.RegisterAttributes;
|
|||||||
import jdk.vm.ci.code.RegisterConfig;
|
import jdk.vm.ci.code.RegisterConfig;
|
||||||
import jdk.vm.ci.code.StackSlot;
|
import jdk.vm.ci.code.StackSlot;
|
||||||
import jdk.vm.ci.code.TargetDescription;
|
import jdk.vm.ci.code.TargetDescription;
|
||||||
|
import jdk.vm.ci.code.ValueKindFactory;
|
||||||
import jdk.vm.ci.common.JVMCIError;
|
import jdk.vm.ci.common.JVMCIError;
|
||||||
import jdk.vm.ci.hotspot.HotSpotCallingConventionType;
|
import jdk.vm.ci.hotspot.HotSpotCallingConventionType;
|
||||||
import jdk.vm.ci.hotspot.HotSpotVMConfig;
|
import jdk.vm.ci.hotspot.HotSpotVMConfig;
|
||||||
import jdk.vm.ci.meta.AllocatableValue;
|
import jdk.vm.ci.meta.AllocatableValue;
|
||||||
import jdk.vm.ci.meta.JavaKind;
|
import jdk.vm.ci.meta.JavaKind;
|
||||||
import jdk.vm.ci.meta.JavaType;
|
import jdk.vm.ci.meta.JavaType;
|
||||||
import jdk.vm.ci.meta.LIRKind;
|
|
||||||
import jdk.vm.ci.meta.PlatformKind;
|
import jdk.vm.ci.meta.PlatformKind;
|
||||||
import jdk.vm.ci.meta.Value;
|
import jdk.vm.ci.meta.Value;
|
||||||
|
import jdk.vm.ci.meta.ValueKind;
|
||||||
|
|
||||||
public class AMD64HotSpotRegisterConfig implements RegisterConfig {
|
public class AMD64HotSpotRegisterConfig implements RegisterConfig {
|
||||||
|
|
||||||
private final Architecture architecture;
|
private final TargetDescription target;
|
||||||
|
|
||||||
private final Register[] allocatable;
|
private final Register[] allocatable;
|
||||||
|
|
||||||
@ -96,7 +97,7 @@ public class AMD64HotSpotRegisterConfig implements RegisterConfig {
|
|||||||
public Register[] filterAllocatableRegisters(PlatformKind kind, Register[] registers) {
|
public Register[] filterAllocatableRegisters(PlatformKind kind, Register[] registers) {
|
||||||
ArrayList<Register> list = new ArrayList<>();
|
ArrayList<Register> list = new ArrayList<>();
|
||||||
for (Register reg : registers) {
|
for (Register reg : registers) {
|
||||||
if (architecture.canStoreValue(reg.getRegisterCategory(), kind)) {
|
if (target.arch.canStoreValue(reg.getRegisterCategory(), kind)) {
|
||||||
list.add(reg);
|
list.add(reg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -145,13 +146,13 @@ public class AMD64HotSpotRegisterConfig implements RegisterConfig {
|
|||||||
return registers;
|
return registers;
|
||||||
}
|
}
|
||||||
|
|
||||||
public AMD64HotSpotRegisterConfig(Architecture architecture, HotSpotVMConfig config) {
|
public AMD64HotSpotRegisterConfig(TargetDescription target, HotSpotVMConfig config) {
|
||||||
this(architecture, config, initAllocatable(architecture, config.useCompressedOops));
|
this(target, config, initAllocatable(target.arch, config.useCompressedOops));
|
||||||
assert callerSaved.length >= allocatable.length;
|
assert callerSaved.length >= allocatable.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
public AMD64HotSpotRegisterConfig(Architecture architecture, HotSpotVMConfig config, Register[] allocatable) {
|
public AMD64HotSpotRegisterConfig(TargetDescription target, HotSpotVMConfig config, Register[] allocatable) {
|
||||||
this.architecture = architecture;
|
this.target = target;
|
||||||
this.maxFrameSize = config.maxFrameSize;
|
this.maxFrameSize = config.maxFrameSize;
|
||||||
|
|
||||||
if (config.windowsOs) {
|
if (config.windowsOs) {
|
||||||
@ -173,7 +174,7 @@ public class AMD64HotSpotRegisterConfig implements RegisterConfig {
|
|||||||
callerSaved = callerSaveSet.toArray(new Register[callerSaveSet.size()]);
|
callerSaved = callerSaveSet.toArray(new Register[callerSaveSet.size()]);
|
||||||
|
|
||||||
allAllocatableAreCallerSaved = true;
|
allAllocatableAreCallerSaved = true;
|
||||||
attributesMap = RegisterAttributes.createMap(this, architecture.getRegisters());
|
attributesMap = RegisterAttributes.createMap(this, target.arch.getRegisters());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -192,19 +193,14 @@ public class AMD64HotSpotRegisterConfig implements RegisterConfig {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Register getRegisterForRole(int index) {
|
public CallingConvention getCallingConvention(Type type, JavaType returnType, JavaType[] parameterTypes, ValueKindFactory<?> valueKindFactory) {
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public CallingConvention getCallingConvention(Type type, JavaType returnType, JavaType[] parameterTypes, TargetDescription target) {
|
|
||||||
HotSpotCallingConventionType hotspotType = (HotSpotCallingConventionType) type;
|
HotSpotCallingConventionType hotspotType = (HotSpotCallingConventionType) type;
|
||||||
if (type == HotSpotCallingConventionType.NativeCall) {
|
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
|
// On x64, parameter locations are the same whether viewed
|
||||||
// from the caller or callee perspective
|
// from the caller or callee perspective
|
||||||
return callingConvention(javaGeneralParameterRegisters, returnType, parameterTypes, hotspotType, target);
|
return callingConvention(javaGeneralParameterRegisters, returnType, parameterTypes, hotspotType, valueKindFactory);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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];
|
AllocatableValue[] locations = new AllocatableValue[parameterTypes.length];
|
||||||
|
|
||||||
int currentGeneral = 0;
|
int currentGeneral = 0;
|
||||||
@ -247,14 +244,14 @@ public class AMD64HotSpotRegisterConfig implements RegisterConfig {
|
|||||||
case Object:
|
case Object:
|
||||||
if (currentGeneral < generalParameterRegisters.length) {
|
if (currentGeneral < generalParameterRegisters.length) {
|
||||||
Register register = generalParameterRegisters[currentGeneral++];
|
Register register = generalParameterRegisters[currentGeneral++];
|
||||||
locations[i] = register.asValue(target.getLIRKind(kind));
|
locations[i] = register.asValue(valueKindFactory.getValueKind(kind));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case Float:
|
case Float:
|
||||||
case Double:
|
case Double:
|
||||||
if (currentXMM < xmmParameterRegisters.length) {
|
if (currentXMM < xmmParameterRegisters.length) {
|
||||||
Register register = xmmParameterRegisters[currentXMM++];
|
Register register = xmmParameterRegisters[currentXMM++];
|
||||||
locations[i] = register.asValue(target.getLIRKind(kind));
|
locations[i] = register.asValue(valueKindFactory.getValueKind(kind));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -262,14 +259,14 @@ public class AMD64HotSpotRegisterConfig implements RegisterConfig {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (locations[i] == null) {
|
if (locations[i] == null) {
|
||||||
LIRKind lirKind = target.getLIRKind(kind);
|
ValueKind<?> valueKind = valueKindFactory.getValueKind(kind);
|
||||||
locations[i] = StackSlot.get(lirKind, currentStackOffset, !type.out);
|
locations[i] = StackSlot.get(valueKind, currentStackOffset, !type.out);
|
||||||
currentStackOffset += Math.max(lirKind.getPlatformKind().getSizeInBytes(), target.wordSize);
|
currentStackOffset += Math.max(valueKind.getPlatformKind().getSizeInBytes(), target.wordSize);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
JavaKind returnKind = returnType == null ? JavaKind.Void : returnType.getJavaKind();
|
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);
|
return new CallingConvention(currentStackOffset, returnLocation, locations);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -22,7 +22,7 @@
|
|||||||
*/
|
*/
|
||||||
package jdk.vm.ci.hotspot.sparc;
|
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;
|
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.RegisterConfig;
|
||||||
import jdk.vm.ci.code.TargetDescription;
|
import jdk.vm.ci.code.TargetDescription;
|
||||||
import jdk.vm.ci.code.stack.StackIntrospection;
|
import jdk.vm.ci.code.stack.StackIntrospection;
|
||||||
|
import jdk.vm.ci.common.InitTimer;
|
||||||
import jdk.vm.ci.hotspot.HotSpotCodeCacheProvider;
|
import jdk.vm.ci.hotspot.HotSpotCodeCacheProvider;
|
||||||
import jdk.vm.ci.hotspot.HotSpotConstantReflectionProvider;
|
import jdk.vm.ci.hotspot.HotSpotConstantReflectionProvider;
|
||||||
import jdk.vm.ci.hotspot.HotSpotJVMCIBackendFactory;
|
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.HotSpotMetaAccessProvider;
|
||||||
import jdk.vm.ci.hotspot.HotSpotStackIntrospection;
|
import jdk.vm.ci.hotspot.HotSpotStackIntrospection;
|
||||||
import jdk.vm.ci.hotspot.HotSpotVMConfig;
|
import jdk.vm.ci.hotspot.HotSpotVMConfig;
|
||||||
import jdk.vm.ci.inittimer.InitTimer;
|
|
||||||
import jdk.vm.ci.runtime.JVMCIBackend;
|
import jdk.vm.ci.runtime.JVMCIBackend;
|
||||||
import jdk.vm.ci.sparc.SPARC;
|
import jdk.vm.ci.sparc.SPARC;
|
||||||
import jdk.vm.ci.sparc.SPARC.CPUFeature;
|
import jdk.vm.ci.sparc.SPARC.CPUFeature;
|
||||||
@ -146,7 +146,7 @@ public class SPARCHotSpotJVMCIBackendFactory implements HotSpotJVMCIBackendFacto
|
|||||||
TargetDescription target = createTarget(runtime.getConfig());
|
TargetDescription target = createTarget(runtime.getConfig());
|
||||||
|
|
||||||
HotSpotMetaAccessProvider metaAccess = new HotSpotMetaAccessProvider(runtime);
|
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);
|
HotSpotCodeCacheProvider codeCache = createCodeCache(runtime, target, regConfig);
|
||||||
HotSpotConstantReflectionProvider constantReflection = new HotSpotConstantReflectionProvider(runtime);
|
HotSpotConstantReflectionProvider constantReflection = new HotSpotConstantReflectionProvider(runtime);
|
||||||
StackIntrospection stackIntrospection = new HotSpotStackIntrospection(runtime);
|
StackIntrospection stackIntrospection = new HotSpotStackIntrospection(runtime);
|
||||||
|
@ -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.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -78,19 +78,20 @@ import jdk.vm.ci.code.RegisterAttributes;
|
|||||||
import jdk.vm.ci.code.RegisterConfig;
|
import jdk.vm.ci.code.RegisterConfig;
|
||||||
import jdk.vm.ci.code.StackSlot;
|
import jdk.vm.ci.code.StackSlot;
|
||||||
import jdk.vm.ci.code.TargetDescription;
|
import jdk.vm.ci.code.TargetDescription;
|
||||||
|
import jdk.vm.ci.code.ValueKindFactory;
|
||||||
import jdk.vm.ci.common.JVMCIError;
|
import jdk.vm.ci.common.JVMCIError;
|
||||||
import jdk.vm.ci.hotspot.HotSpotCallingConventionType;
|
import jdk.vm.ci.hotspot.HotSpotCallingConventionType;
|
||||||
import jdk.vm.ci.hotspot.HotSpotVMConfig;
|
import jdk.vm.ci.hotspot.HotSpotVMConfig;
|
||||||
import jdk.vm.ci.meta.AllocatableValue;
|
import jdk.vm.ci.meta.AllocatableValue;
|
||||||
import jdk.vm.ci.meta.JavaKind;
|
import jdk.vm.ci.meta.JavaKind;
|
||||||
import jdk.vm.ci.meta.JavaType;
|
import jdk.vm.ci.meta.JavaType;
|
||||||
import jdk.vm.ci.meta.LIRKind;
|
|
||||||
import jdk.vm.ci.meta.PlatformKind;
|
import jdk.vm.ci.meta.PlatformKind;
|
||||||
|
import jdk.vm.ci.meta.ValueKind;
|
||||||
import jdk.vm.ci.sparc.SPARC;
|
import jdk.vm.ci.sparc.SPARC;
|
||||||
|
|
||||||
public class SPARCHotSpotRegisterConfig implements RegisterConfig {
|
public class SPARCHotSpotRegisterConfig implements RegisterConfig {
|
||||||
|
|
||||||
private final Architecture architecture;
|
private final TargetDescription target;
|
||||||
|
|
||||||
private final Register[] allocatable;
|
private final Register[] allocatable;
|
||||||
|
|
||||||
@ -110,7 +111,7 @@ public class SPARCHotSpotRegisterConfig implements RegisterConfig {
|
|||||||
public Register[] filterAllocatableRegisters(PlatformKind kind, Register[] registers) {
|
public Register[] filterAllocatableRegisters(PlatformKind kind, Register[] registers) {
|
||||||
ArrayList<Register> list = new ArrayList<>();
|
ArrayList<Register> list = new ArrayList<>();
|
||||||
for (Register reg : registers) {
|
for (Register reg : registers) {
|
||||||
if (architecture.canStoreValue(reg.getRegisterCategory(), kind)) {
|
if (target.arch.canStoreValue(reg.getRegisterCategory(), kind)) {
|
||||||
list.add(reg);
|
list.add(reg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -166,16 +167,16 @@ public class SPARCHotSpotRegisterConfig implements RegisterConfig {
|
|||||||
return registers;
|
return registers;
|
||||||
}
|
}
|
||||||
|
|
||||||
public SPARCHotSpotRegisterConfig(Architecture arch, HotSpotVMConfig config) {
|
public SPARCHotSpotRegisterConfig(TargetDescription target, HotSpotVMConfig config) {
|
||||||
this(arch, initAllocatable(arch, config.useCompressedOops), config);
|
this(target, initAllocatable(target.arch, config.useCompressedOops), config);
|
||||||
}
|
}
|
||||||
|
|
||||||
public SPARCHotSpotRegisterConfig(Architecture arch, Register[] allocatable, HotSpotVMConfig config) {
|
public SPARCHotSpotRegisterConfig(TargetDescription target, Register[] allocatable, HotSpotVMConfig config) {
|
||||||
this.architecture = arch;
|
this.target = target;
|
||||||
this.allocatable = allocatable.clone();
|
this.allocatable = allocatable.clone();
|
||||||
this.addNativeRegisterArgumentSlots = config.linuxOs;
|
this.addNativeRegisterArgumentSlots = config.linuxOs;
|
||||||
HashSet<Register> callerSaveSet = new HashSet<>();
|
HashSet<Register> callerSaveSet = new HashSet<>();
|
||||||
Collections.addAll(callerSaveSet, arch.getAvailableValueRegisters());
|
Collections.addAll(callerSaveSet, target.arch.getAvailableValueRegisters());
|
||||||
for (Register cs : calleeSaveRegisters) {
|
for (Register cs : calleeSaveRegisters) {
|
||||||
callerSaveSet.remove(cs);
|
callerSaveSet.remove(cs);
|
||||||
}
|
}
|
||||||
@ -198,18 +199,13 @@ public class SPARCHotSpotRegisterConfig implements RegisterConfig {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Register getRegisterForRole(int index) {
|
public CallingConvention getCallingConvention(Type type, JavaType returnType, JavaType[] parameterTypes, ValueKindFactory<?> valueKindFactory) {
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public CallingConvention getCallingConvention(Type type, JavaType returnType, JavaType[] parameterTypes, TargetDescription target) {
|
|
||||||
HotSpotCallingConventionType hotspotType = (HotSpotCallingConventionType) type;
|
HotSpotCallingConventionType hotspotType = (HotSpotCallingConventionType) type;
|
||||||
if (type == HotSpotCallingConventionType.JavaCall || type == HotSpotCallingConventionType.NativeCall) {
|
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) {
|
if (type == HotSpotCallingConventionType.JavaCallee) {
|
||||||
return callingConvention(cpuCalleeParameterRegisters, returnType, parameterTypes, hotspotType, target);
|
return callingConvention(cpuCalleeParameterRegisters, returnType, parameterTypes, hotspotType, valueKindFactory);
|
||||||
}
|
}
|
||||||
throw JVMCIError.shouldNotReachHere();
|
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];
|
AllocatableValue[] locations = new AllocatableValue[parameterTypes.length];
|
||||||
|
|
||||||
int currentGeneral = 0;
|
int currentGeneral = 0;
|
||||||
@ -254,7 +251,7 @@ public class SPARCHotSpotRegisterConfig implements RegisterConfig {
|
|||||||
case Object:
|
case Object:
|
||||||
if (currentGeneral < generalParameterRegisters.length) {
|
if (currentGeneral < generalParameterRegisters.length) {
|
||||||
Register register = generalParameterRegisters[currentGeneral++];
|
Register register = generalParameterRegisters[currentGeneral++];
|
||||||
locations[i] = register.asValue(target.getLIRKind(kind));
|
locations[i] = register.asValue(valueKindFactory.getValueKind(kind));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case Double:
|
case Double:
|
||||||
@ -265,13 +262,13 @@ public class SPARCHotSpotRegisterConfig implements RegisterConfig {
|
|||||||
}
|
}
|
||||||
Register register = fpuDoubleParameterRegisters[currentFloating];
|
Register register = fpuDoubleParameterRegisters[currentFloating];
|
||||||
currentFloating += 2; // Only every second is a double register
|
currentFloating += 2; // Only every second is a double register
|
||||||
locations[i] = register.asValue(target.getLIRKind(kind));
|
locations[i] = register.asValue(valueKindFactory.getValueKind(kind));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case Float:
|
case Float:
|
||||||
if (currentFloating < fpuFloatParameterRegisters.length) {
|
if (currentFloating < fpuFloatParameterRegisters.length) {
|
||||||
Register register = fpuFloatParameterRegisters[currentFloating++];
|
Register register = fpuFloatParameterRegisters[currentFloating++];
|
||||||
locations[i] = register.asValue(target.getLIRKind(kind));
|
locations[i] = register.asValue(valueKindFactory.getValueKind(kind));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -279,18 +276,18 @@ public class SPARCHotSpotRegisterConfig implements RegisterConfig {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (locations[i] == null) {
|
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
|
// 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);
|
currentStackOffset = roundUp(currentStackOffset, typeSize);
|
||||||
int slotOffset = currentStackOffset + REGISTER_SAFE_AREA_SIZE;
|
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;
|
currentStackOffset += typeSize;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
JavaKind returnKind = returnType == null ? Void : returnType.getJavaKind();
|
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;
|
int outArgSpillArea;
|
||||||
if (type == HotSpotCallingConventionType.NativeCall && addNativeRegisterArgumentSlots) {
|
if (type == HotSpotCallingConventionType.NativeCall && addNativeRegisterArgumentSlots) {
|
||||||
|
@ -23,8 +23,8 @@
|
|||||||
|
|
||||||
package jdk.vm.ci.hotspot;
|
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.hotspot.HotSpotJVMCIRuntime.runtime;
|
||||||
import static jdk.vm.ci.inittimer.InitTimer.timer;
|
|
||||||
|
|
||||||
import java.lang.reflect.Constructor;
|
import java.lang.reflect.Constructor;
|
||||||
import java.lang.reflect.Method;
|
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.InstalledCode;
|
||||||
import jdk.vm.ci.code.InvalidInstalledCodeException;
|
import jdk.vm.ci.code.InvalidInstalledCodeException;
|
||||||
import jdk.vm.ci.code.TargetDescription;
|
import jdk.vm.ci.code.TargetDescription;
|
||||||
|
import jdk.vm.ci.common.InitTimer;
|
||||||
import jdk.vm.ci.common.JVMCIError;
|
import jdk.vm.ci.common.JVMCIError;
|
||||||
import jdk.vm.ci.hotspotvmconfig.HotSpotVMField;
|
import jdk.vm.ci.hotspotvmconfig.HotSpotVMField;
|
||||||
import jdk.vm.ci.inittimer.InitTimer;
|
|
||||||
import jdk.vm.ci.meta.JavaType;
|
import jdk.vm.ci.meta.JavaType;
|
||||||
import jdk.vm.ci.meta.ResolvedJavaMethod;
|
import jdk.vm.ci.meta.ResolvedJavaMethod;
|
||||||
import jdk.vm.ci.meta.ResolvedJavaType;
|
import jdk.vm.ci.meta.ResolvedJavaType;
|
||||||
@ -79,7 +79,7 @@ final class CompilerToVM {
|
|||||||
native byte[] getBytecode(HotSpotResolvedJavaMethodImpl method);
|
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.
|
* exception handler table.
|
||||||
*/
|
*/
|
||||||
native int getExceptionTableLength(HotSpotResolvedJavaMethodImpl method);
|
native int getExceptionTableLength(HotSpotResolvedJavaMethodImpl method);
|
||||||
@ -246,8 +246,8 @@ final class CompilerToVM {
|
|||||||
native void resolveInvokeDynamicInPool(HotSpotConstantPool constantPool, int cpi);
|
native void resolveInvokeDynamicInPool(HotSpotConstantPool constantPool, int cpi);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Ensures that the type referenced by the entry for a <a
|
* Ensures that the type referenced by the entry for a
|
||||||
* href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-2.html#jvms-2.9">signature
|
* <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
|
* polymorphic</a> method at index {@code cpi} in {@code constantPool} is loaded and
|
||||||
* initialized.
|
* initialized.
|
||||||
*
|
*
|
||||||
@ -315,6 +315,21 @@ final class CompilerToVM {
|
|||||||
*/
|
*/
|
||||||
native int installCode(TargetDescription target, HotSpotCompiledCode compiledCode, InstalledCode code, HotSpotSpeculationLog speculationLog);
|
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);
|
public native int getMetadata(TargetDescription target, HotSpotCompiledCode compiledCode, HotSpotMetaData metaData);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -422,20 +437,6 @@ final class CompilerToVM {
|
|||||||
*/
|
*/
|
||||||
native long getLocalVariableTableStart(HotSpotResolvedJavaMethodImpl method);
|
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.
|
* Determines if {@code method} should not be inlined or compiled.
|
||||||
*/
|
*/
|
||||||
@ -479,11 +480,6 @@ final class CompilerToVM {
|
|||||||
*/
|
*/
|
||||||
native String getSymbol(long metaspaceSymbol);
|
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}.
|
* 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);
|
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
|
* @param invalidate if {@code true}, the compiled method for the stack frame will be
|
||||||
* invalidated.
|
* invalidated
|
||||||
*/
|
*/
|
||||||
native void materializeVirtualObjects(HotSpotStackFrameReference stackFrame, boolean invalidate);
|
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.
|
* Determines if debug info should also be emitted at non-safepoint locations.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
native boolean shouldDebugNonSafepoints();
|
native boolean shouldDebugNonSafepoints();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
@ -25,7 +25,6 @@ package jdk.vm.ci.hotspot;
|
|||||||
import jdk.vm.ci.code.StackSlot;
|
import jdk.vm.ci.code.StackSlot;
|
||||||
import jdk.vm.ci.code.site.DataPatch;
|
import jdk.vm.ci.code.site.DataPatch;
|
||||||
import jdk.vm.ci.code.site.Site;
|
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.Assumptions.Assumption;
|
||||||
import jdk.vm.ci.meta.ResolvedJavaMethod;
|
import jdk.vm.ci.meta.ResolvedJavaMethod;
|
||||||
|
|
||||||
|
@ -42,7 +42,7 @@ import jdk.vm.ci.meta.Signature;
|
|||||||
/**
|
/**
|
||||||
* Implementation of {@link ConstantPool} for HotSpot.
|
* 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}.
|
* Subset of JVM bytecode opcodes used by {@link HotSpotConstantPool}.
|
||||||
|
@ -22,19 +22,15 @@
|
|||||||
*/
|
*/
|
||||||
package jdk.vm.ci.hotspot;
|
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.lang.reflect.Array;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
|
import jdk.internal.vm.annotation.Stable;
|
||||||
import jdk.vm.ci.common.JVMCIError;
|
import jdk.vm.ci.common.JVMCIError;
|
||||||
import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.Option;
|
|
||||||
import jdk.vm.ci.meta.Constant;
|
import jdk.vm.ci.meta.Constant;
|
||||||
import jdk.vm.ci.meta.ConstantReflectionProvider;
|
import jdk.vm.ci.meta.ConstantReflectionProvider;
|
||||||
import jdk.vm.ci.meta.JavaConstant;
|
import jdk.vm.ci.meta.JavaConstant;
|
||||||
import jdk.vm.ci.meta.JavaKind;
|
import jdk.vm.ci.meta.JavaKind;
|
||||||
import jdk.vm.ci.meta.JavaType;
|
|
||||||
import jdk.vm.ci.meta.MemoryAccessProvider;
|
import jdk.vm.ci.meta.MemoryAccessProvider;
|
||||||
import jdk.vm.ci.meta.MethodHandleAccessProvider;
|
import jdk.vm.ci.meta.MethodHandleAccessProvider;
|
||||||
import jdk.vm.ci.meta.ResolvedJavaField;
|
import jdk.vm.ci.meta.ResolvedJavaField;
|
||||||
@ -43,7 +39,7 @@ import jdk.vm.ci.meta.ResolvedJavaType;
|
|||||||
/**
|
/**
|
||||||
* HotSpot implementation of {@link ConstantReflectionProvider}.
|
* HotSpot implementation of {@link ConstantReflectionProvider}.
|
||||||
*/
|
*/
|
||||||
public class HotSpotConstantReflectionProvider implements ConstantReflectionProvider, HotSpotProxified {
|
public class HotSpotConstantReflectionProvider implements ConstantReflectionProvider {
|
||||||
|
|
||||||
protected final HotSpotJVMCIRuntimeProvider runtime;
|
protected final HotSpotJVMCIRuntimeProvider runtime;
|
||||||
protected final HotSpotMethodHandleAccessProvider methodHandleAccess;
|
protected final HotSpotMethodHandleAccessProvider methodHandleAccess;
|
||||||
@ -88,50 +84,6 @@ public class HotSpotConstantReflectionProvider implements ConstantReflectionProv
|
|||||||
return Array.getLength(arrayObject);
|
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
|
@Override
|
||||||
public JavaConstant readArrayElement(JavaConstant array, int index) {
|
public JavaConstant readArrayElement(JavaConstant array, int index) {
|
||||||
if (array == null || array.getJavaKind() != JavaKind.Object || array.isNull()) {
|
if (array == null || array.getJavaKind() != JavaKind.Object || array.isNull()) {
|
||||||
@ -145,11 +97,7 @@ public class HotSpotConstantReflectionProvider implements ConstantReflectionProv
|
|||||||
|
|
||||||
if (a instanceof Object[]) {
|
if (a instanceof Object[]) {
|
||||||
Object element = ((Object[]) a)[index];
|
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 {
|
} else {
|
||||||
return JavaConstant.forBoxedPrimitive(Array.get(a, index));
|
return JavaConstant.forBoxedPrimitive(Array.get(a, index));
|
||||||
}
|
}
|
||||||
@ -227,102 +175,7 @@ public class HotSpotConstantReflectionProvider implements ConstantReflectionProv
|
|||||||
return null;
|
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) {
|
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;
|
HotSpotResolvedJavaField hotspotField = (HotSpotResolvedJavaField) field;
|
||||||
if (hotspotField.isStatic()) {
|
if (hotspotField.isStatic()) {
|
||||||
HotSpotResolvedJavaType holder = (HotSpotResolvedJavaType) hotspotField.getDeclaringClass();
|
HotSpotResolvedJavaType holder = (HotSpotResolvedJavaType) hotspotField.getDeclaringClass();
|
||||||
@ -337,27 +190,6 @@ public class HotSpotConstantReflectionProvider implements ConstantReflectionProv
|
|||||||
return null;
|
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
|
@Override
|
||||||
public JavaConstant asJavaClass(ResolvedJavaType type) {
|
public JavaConstant asJavaClass(ResolvedJavaType type) {
|
||||||
return HotSpotObjectConstantImpl.forObject(((HotSpotResolvedJavaType) type).mirror());
|
return HotSpotObjectConstantImpl.forObject(((HotSpotResolvedJavaType) type).mirror());
|
||||||
|
@ -23,9 +23,9 @@
|
|||||||
package jdk.vm.ci.hotspot;
|
package jdk.vm.ci.hotspot;
|
||||||
|
|
||||||
import static jdk.vm.ci.hotspot.UnsafeAccess.UNSAFE;
|
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.internal.misc.Unsafe;
|
||||||
|
import jdk.vm.ci.code.InstalledCode;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implementation of {@link InstalledCode} for HotSpot.
|
* Implementation of {@link InstalledCode} for HotSpot.
|
||||||
|
@ -22,27 +22,30 @@
|
|||||||
*/
|
*/
|
||||||
package jdk.vm.ci.hotspot;
|
package jdk.vm.ci.hotspot;
|
||||||
|
|
||||||
|
import java.lang.reflect.Module;
|
||||||
|
|
||||||
import jdk.vm.ci.code.CompilationRequest;
|
import jdk.vm.ci.code.CompilationRequest;
|
||||||
import jdk.vm.ci.code.CompilationRequestResult;
|
|
||||||
import jdk.vm.ci.common.JVMCIError;
|
import jdk.vm.ci.common.JVMCIError;
|
||||||
import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.Option;
|
import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.Option;
|
||||||
import jdk.vm.ci.runtime.JVMCICompiler;
|
import jdk.vm.ci.runtime.JVMCICompiler;
|
||||||
import jdk.vm.ci.runtime.JVMCICompilerFactory;
|
|
||||||
import jdk.vm.ci.runtime.JVMCIRuntime;
|
import jdk.vm.ci.runtime.JVMCIRuntime;
|
||||||
|
import jdk.vm.ci.runtime.services.JVMCICompilerFactory;
|
||||||
import jdk.vm.ci.services.Services;
|
import jdk.vm.ci.services.Services;
|
||||||
|
|
||||||
final class HotSpotJVMCICompilerConfig {
|
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");
|
throw new JVMCIError("no JVMCI compiler selected");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public String getCompilerName() {
|
public String getCompilerName() {
|
||||||
return "<none>";
|
return "<none>";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public JVMCICompiler createCompiler(JVMCIRuntime runtime) {
|
public JVMCICompiler createCompiler(JVMCIRuntime runtime) {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@ -65,6 +68,9 @@ final class HotSpotJVMCICompilerConfig {
|
|||||||
if (compilerName != null) {
|
if (compilerName != null) {
|
||||||
for (JVMCICompilerFactory f : Services.load(JVMCICompilerFactory.class)) {
|
for (JVMCICompilerFactory f : Services.load(JVMCICompilerFactory.class)) {
|
||||||
if (f.getCompilerName().equals(compilerName)) {
|
if (f.getCompilerName().equals(compilerName)) {
|
||||||
|
Module jvmciModule = JVMCICompilerFactory.class.getModule();
|
||||||
|
Services.exportJVMCITo(f.getClass());
|
||||||
|
f.onSelection();
|
||||||
factory = f;
|
factory = f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -30,7 +30,6 @@ import java.util.Iterator;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.WeakHashMap;
|
import java.util.WeakHashMap;
|
||||||
|
|
||||||
import jdk.vm.ci.meta.JVMCIMetaAccessContext;
|
|
||||||
import jdk.vm.ci.meta.JavaKind;
|
import jdk.vm.ci.meta.JavaKind;
|
||||||
import jdk.vm.ci.meta.ResolvedJavaType;
|
import jdk.vm.ci.meta.ResolvedJavaType;
|
||||||
|
|
||||||
@ -47,7 +46,7 @@ import jdk.vm.ci.meta.ResolvedJavaType;
|
|||||||
* longer used.
|
* 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
|
* 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<>();
|
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) {
|
public synchronized ResolvedJavaType fromClass(Class<?> javaClass) {
|
||||||
WeakReference<ResolvedJavaType> typeRef = typeMap.get(javaClass);
|
WeakReference<ResolvedJavaType> typeRef = typeMap.get(javaClass);
|
||||||
ResolvedJavaType type = typeRef != null ? typeRef.get() : null;
|
ResolvedJavaType type = typeRef != null ? typeRef.get() : null;
|
||||||
|
@ -22,7 +22,7 @@
|
|||||||
*/
|
*/
|
||||||
package jdk.vm.ci.hotspot;
|
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.IOException;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
@ -37,24 +37,23 @@ import java.util.Map;
|
|||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.TreeMap;
|
import java.util.TreeMap;
|
||||||
|
|
||||||
|
import jdk.internal.misc.VM;
|
||||||
import jdk.vm.ci.code.Architecture;
|
import jdk.vm.ci.code.Architecture;
|
||||||
import jdk.vm.ci.code.CompilationRequestResult;
|
import jdk.vm.ci.code.CompilationRequestResult;
|
||||||
import jdk.vm.ci.code.CompiledCode;
|
import jdk.vm.ci.code.CompiledCode;
|
||||||
import jdk.vm.ci.code.InstalledCode;
|
import jdk.vm.ci.code.InstalledCode;
|
||||||
|
import jdk.vm.ci.common.InitTimer;
|
||||||
import jdk.vm.ci.common.JVMCIError;
|
import jdk.vm.ci.common.JVMCIError;
|
||||||
import jdk.vm.ci.inittimer.InitTimer;
|
import jdk.vm.ci.hotspot.services.HotSpotJVMCICompilerFactory;
|
||||||
import jdk.vm.ci.inittimer.SuppressFBWarnings;
|
import jdk.vm.ci.hotspot.services.HotSpotVMEventListener;
|
||||||
import jdk.vm.ci.meta.JVMCIMetaAccessContext;
|
|
||||||
import jdk.vm.ci.meta.JavaKind;
|
import jdk.vm.ci.meta.JavaKind;
|
||||||
import jdk.vm.ci.meta.JavaType;
|
import jdk.vm.ci.meta.JavaType;
|
||||||
import jdk.vm.ci.meta.ResolvedJavaType;
|
import jdk.vm.ci.meta.ResolvedJavaType;
|
||||||
import jdk.vm.ci.runtime.JVMCI;
|
import jdk.vm.ci.runtime.JVMCI;
|
||||||
import jdk.vm.ci.runtime.JVMCIBackend;
|
import jdk.vm.ci.runtime.JVMCIBackend;
|
||||||
import jdk.vm.ci.runtime.JVMCICompiler;
|
import jdk.vm.ci.runtime.JVMCICompiler;
|
||||||
|
import jdk.vm.ci.runtime.services.JVMCICompilerFactory;
|
||||||
import jdk.vm.ci.services.Services;
|
import jdk.vm.ci.services.Services;
|
||||||
import jdk.internal.misc.VM;
|
|
||||||
|
|
||||||
//JaCoCo Exclude
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* HotSpot implementation of a JVMCI runtime.
|
* 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 #runtime()}. This allows the initialization to funnel back through
|
||||||
* {@link JVMCI#initialize()} without deadlocking.
|
* {@link JVMCI#initialize()} without deadlocking.
|
||||||
*/
|
*/
|
||||||
public final class HotSpotJVMCIRuntime implements HotSpotJVMCIRuntimeProvider, HotSpotProxified {
|
public final class HotSpotJVMCIRuntime implements HotSpotJVMCIRuntimeProvider {
|
||||||
|
|
||||||
@SuppressWarnings("try")
|
@SuppressWarnings("try")
|
||||||
static class DelayedInit {
|
static class DelayedInit {
|
||||||
@ -92,14 +91,12 @@ public final class HotSpotJVMCIRuntime implements HotSpotJVMCIRuntimeProvider, H
|
|||||||
*/
|
*/
|
||||||
public enum Option {
|
public enum Option {
|
||||||
Compiler(String.class, null, "Selects the system compiler."),
|
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).
|
// Note: The following one is not used (see InitTimer.ENABLED).
|
||||||
InitTimer(boolean.class, false, "Specifies if initialization timing is enabled."),
|
InitTimer(boolean.class, false, "Specifies if initialization timing is enabled."),
|
||||||
PrintConfig(boolean.class, false, "Prints all HotSpotVMConfig fields."),
|
PrintConfig(boolean.class, false, "Prints all HotSpotVMConfig fields."),
|
||||||
PrintFlags(boolean.class, false, "Prints all JVMCI flags and exits."),
|
PrintFlags(boolean.class, false, "Prints all JVMCI flags and exits."),
|
||||||
ShowFlags(boolean.class, false, "Prints all JVMCI flags and continues."),
|
ShowFlags(boolean.class, false, "Prints all JVMCI flags and continues."),
|
||||||
TraceMethodDataFilter(String.class, null, ""),
|
TraceMethodDataFilter(String.class, null, "");
|
||||||
TrustFinalDefaultFields(boolean.class, true, "Determines whether to treat final fields with default values as constant.");
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The prefix for system properties that are JVMCI options.
|
* The prefix for system properties that are JVMCI options.
|
||||||
@ -203,13 +200,25 @@ public final class HotSpotJVMCIRuntime implements HotSpotJVMCIRuntimeProvider, H
|
|||||||
protected final HotSpotVMConfig config;
|
protected final HotSpotVMConfig config;
|
||||||
private final JVMCIBackend hostBackend;
|
private final JVMCIBackend hostBackend;
|
||||||
|
|
||||||
|
private final JVMCICompilerFactory compilerFactory;
|
||||||
|
private final HotSpotJVMCICompilerFactory hsCompilerFactory;
|
||||||
private volatile JVMCICompiler compiler;
|
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 Map<Class<? extends Architecture>, JVMCIBackend> backends = new HashMap<>();
|
||||||
|
|
||||||
private final Iterable<HotSpotVMEventListener> vmEventListeners;
|
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("unused") private final String[] trivialPrefixes;
|
||||||
|
|
||||||
@SuppressWarnings("try")
|
@SuppressWarnings("try")
|
||||||
@ -233,17 +242,7 @@ public final class HotSpotJVMCIRuntime implements HotSpotJVMCIRuntimeProvider, H
|
|||||||
|
|
||||||
vmEventListeners = Services.load(HotSpotVMEventListener.class);
|
vmEventListeners = Services.load(HotSpotVMEventListener.class);
|
||||||
|
|
||||||
JVMCIMetaAccessContext context = null;
|
metaAccessContext = new HotSpotJVMCIMetaAccessContext();
|
||||||
for (HotSpotVMEventListener vmEventListener : vmEventListeners) {
|
|
||||||
context = vmEventListener.createMetaAccessContext(this);
|
|
||||||
if (context != null) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (context == null) {
|
|
||||||
context = new HotSpotJVMCIMetaAccessContext();
|
|
||||||
}
|
|
||||||
metaAccessContext = context;
|
|
||||||
|
|
||||||
boolean printFlags = Option.PrintFlags.getBoolean();
|
boolean printFlags = Option.PrintFlags.getBoolean();
|
||||||
boolean showFlags = Option.ShowFlags.getBoolean();
|
boolean showFlags = Option.ShowFlags.getBoolean();
|
||||||
@ -258,7 +257,16 @@ public final class HotSpotJVMCIRuntime implements HotSpotJVMCIRuntimeProvider, H
|
|||||||
printConfig(config, compilerToVm);
|
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) {
|
private JVMCIBackend registerBackend(JVMCIBackend backend) {
|
||||||
@ -280,15 +288,11 @@ public final class HotSpotJVMCIRuntime implements HotSpotJVMCIRuntimeProvider, H
|
|||||||
return compilerToVm;
|
return compilerToVm;
|
||||||
}
|
}
|
||||||
|
|
||||||
public JVMCIMetaAccessContext getMetaAccessContext() {
|
|
||||||
return metaAccessContext;
|
|
||||||
}
|
|
||||||
|
|
||||||
public JVMCICompiler getCompiler() {
|
public JVMCICompiler getCompiler() {
|
||||||
if (compiler == null) {
|
if (compiler == null) {
|
||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
if (compiler == null) {
|
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.
|
* Called from the VM.
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings({"unused"})
|
@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));
|
CompilationRequestResult result = getCompiler().compileMethod(new HotSpotCompilationRequest(method, entryBCI, jvmciEnv, id));
|
||||||
assert result != null : "compileMethod must always return something";
|
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.
|
* Notify on successful install into the CodeCache.
|
||||||
*
|
*
|
||||||
|
@ -24,15 +24,12 @@ package jdk.vm.ci.hotspot;
|
|||||||
|
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
|
|
||||||
|
import jdk.internal.misc.Unsafe;
|
||||||
import jdk.vm.ci.common.JVMCIError;
|
import jdk.vm.ci.common.JVMCIError;
|
||||||
import jdk.vm.ci.meta.JVMCIMetaAccessContext;
|
|
||||||
import jdk.vm.ci.meta.JavaKind;
|
import jdk.vm.ci.meta.JavaKind;
|
||||||
import jdk.vm.ci.meta.JavaType;
|
import jdk.vm.ci.meta.JavaType;
|
||||||
import jdk.vm.ci.meta.ResolvedJavaType;
|
import jdk.vm.ci.meta.ResolvedJavaType;
|
||||||
import jdk.vm.ci.runtime.JVMCIRuntime;
|
import jdk.vm.ci.runtime.JVMCIRuntime;
|
||||||
import jdk.internal.misc.Unsafe;
|
|
||||||
|
|
||||||
//JaCoCo Exclude
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Configuration information for the HotSpot JVMCI runtime.
|
* Configuration information for the HotSpot JVMCI runtime.
|
||||||
@ -70,8 +67,6 @@ public interface HotSpotJVMCIRuntimeProvider extends JVMCIRuntime {
|
|||||||
*/
|
*/
|
||||||
ResolvedJavaType fromClass(Class<?> clazz);
|
ResolvedJavaType fromClass(Class<?> clazz);
|
||||||
|
|
||||||
JVMCIMetaAccessContext getMetaAccessContext();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The offset from the origin of an array to the first element.
|
* The offset from the origin of an array to the first element.
|
||||||
*
|
*
|
||||||
|
@ -39,6 +39,4 @@ public interface HotSpotMemoryAccessProvider extends MemoryAccessProvider {
|
|||||||
Constant readNarrowKlassPointerConstant(Constant base, long displacement, CompressEncoding encoding);
|
Constant readNarrowKlassPointerConstant(Constant base, long displacement, CompressEncoding encoding);
|
||||||
|
|
||||||
Constant readMethodPointerConstant(Constant base, long displacement);
|
Constant readMethodPointerConstant(Constant base, long displacement);
|
||||||
|
|
||||||
Constant readSymbolConstant(Constant base, long displacement);
|
|
||||||
}
|
}
|
||||||
|
@ -33,7 +33,7 @@ import jdk.vm.ci.meta.PrimitiveConstant;
|
|||||||
/**
|
/**
|
||||||
* HotSpot implementation of {@link MemoryAccessProvider}.
|
* HotSpot implementation of {@link MemoryAccessProvider}.
|
||||||
*/
|
*/
|
||||||
class HotSpotMemoryAccessProviderImpl implements HotSpotMemoryAccessProvider, HotSpotProxified {
|
class HotSpotMemoryAccessProviderImpl implements HotSpotMemoryAccessProvider {
|
||||||
|
|
||||||
protected final HotSpotJVMCIRuntimeProvider runtime;
|
protected final HotSpotJVMCIRuntimeProvider runtime;
|
||||||
|
|
||||||
@ -135,7 +135,7 @@ class HotSpotMemoryAccessProviderImpl implements HotSpotMemoryAccessProvider, Ho
|
|||||||
if (base == null) {
|
if (base == null) {
|
||||||
assert !compressed;
|
assert !compressed;
|
||||||
displacement += asRawPointer(baseConstant);
|
displacement += asRawPointer(baseConstant);
|
||||||
ret = runtime.getCompilerToVM().readUncompressedOop(displacement);
|
ret = UNSAFE.getUncompressedObject(displacement);
|
||||||
} else {
|
} else {
|
||||||
assert runtime.getConfig().useCompressedOops == compressed;
|
assert runtime.getConfig().useCompressedOops == compressed;
|
||||||
ret = UNSAFE.getObject(base, displacement);
|
ret = UNSAFE.getObject(base, displacement);
|
||||||
@ -232,16 +232,4 @@ class HotSpotMemoryAccessProviderImpl implements HotSpotMemoryAccessProvider, Ho
|
|||||||
HotSpotResolvedJavaMethodImpl method = runtime.getCompilerToVM().getResolvedJavaMethod(baseObject, displacement);
|
HotSpotResolvedJavaMethodImpl method = runtime.getCompilerToVM().getResolvedJavaMethod(baseObject, displacement);
|
||||||
return HotSpotMetaspaceConstantImpl.forMetaspaceObject(method, false);
|
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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -52,7 +52,7 @@ import jdk.vm.ci.meta.Signature;
|
|||||||
/**
|
/**
|
||||||
* HotSpot implementation of {@link MetaAccessProvider}.
|
* HotSpot implementation of {@link MetaAccessProvider}.
|
||||||
*/
|
*/
|
||||||
public class HotSpotMetaAccessProvider implements MetaAccessProvider, HotSpotProxified {
|
public class HotSpotMetaAccessProvider implements MetaAccessProvider {
|
||||||
|
|
||||||
protected final HotSpotJVMCIRuntimeProvider runtime;
|
protected final HotSpotJVMCIRuntimeProvider runtime;
|
||||||
|
|
||||||
@ -78,15 +78,6 @@ public class HotSpotMetaAccessProvider implements MetaAccessProvider, HotSpotPro
|
|||||||
return new HotSpotSignature(runtime, signature);
|
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}.
|
* {@link Field} object of {@link Method#slot}.
|
||||||
*/
|
*/
|
||||||
@ -152,7 +143,8 @@ public class HotSpotMetaAccessProvider implements MetaAccessProvider, HotSpotPro
|
|||||||
int actionValue = convertDeoptAction(action);
|
int actionValue = convertDeoptAction(action);
|
||||||
int reasonValue = convertDeoptReason(reason);
|
int reasonValue = convertDeoptReason(reason);
|
||||||
int debugValue = debugId & intMaskRight(config.deoptimizationDebugIdBits);
|
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;
|
assert c.asInt() < 0;
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
@ -316,7 +308,6 @@ public class HotSpotMetaAccessProvider implements MetaAccessProvider, HotSpotPro
|
|||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
if (lookupJavaType.isArray()) {
|
if (lookupJavaType.isArray()) {
|
||||||
// TODO(tw): Add compressed pointer support.
|
|
||||||
int length = Array.getLength(((HotSpotObjectConstantImpl) constant).object());
|
int length = Array.getLength(((HotSpotObjectConstantImpl) constant).object());
|
||||||
ResolvedJavaType elementType = lookupJavaType.getComponentType();
|
ResolvedJavaType elementType = lookupJavaType.getComponentType();
|
||||||
JavaKind elementKind = elementType.getJavaKind();
|
JavaKind elementKind = elementType.getJavaKind();
|
||||||
|
@ -22,8 +22,9 @@
|
|||||||
*/
|
*/
|
||||||
package jdk.vm.ci.hotspot;
|
package jdk.vm.ci.hotspot;
|
||||||
|
|
||||||
import jdk.vm.ci.inittimer.SuppressFBWarnings;
|
/**
|
||||||
|
* Encapsulates the VM metadata generated by {@link CompilerToVM#getMetadata}.
|
||||||
|
*/
|
||||||
public class HotSpotMetaData {
|
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[] pcDescBytes;
|
||||||
@SuppressFBWarnings(value = "UWF_UNWRITTEN_FIELD", justification = "field is set by the native part") private byte[] scopesDescBytes;
|
@SuppressFBWarnings(value = "UWF_UNWRITTEN_FIELD", justification = "field is set by the native part") private byte[] scopesDescBytes;
|
||||||
|
@ -29,6 +29,4 @@ public interface HotSpotMetaspaceConstant extends HotSpotConstant, VMConstant {
|
|||||||
HotSpotResolvedObjectType asResolvedJavaType();
|
HotSpotResolvedObjectType asResolvedJavaType();
|
||||||
|
|
||||||
HotSpotResolvedJavaMethod asResolvedJavaMethod();
|
HotSpotResolvedJavaMethod asResolvedJavaMethod();
|
||||||
|
|
||||||
HotSpotSymbol asSymbol();
|
|
||||||
}
|
}
|
||||||
|
@ -27,7 +27,7 @@ import java.util.Objects;
|
|||||||
import jdk.vm.ci.meta.Constant;
|
import jdk.vm.ci.meta.Constant;
|
||||||
import jdk.vm.ci.meta.VMConstant;
|
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) {
|
static HotSpotMetaspaceConstantImpl forMetaspaceObject(MetaspaceWrapperObject metaspaceObject, boolean compressed) {
|
||||||
return new HotSpotMetaspaceConstantImpl(metaspaceObject, compressed);
|
return new HotSpotMetaspaceConstantImpl(metaspaceObject, compressed);
|
||||||
@ -108,11 +108,4 @@ final class HotSpotMetaspaceConstantImpl implements HotSpotMetaspaceConstant, VM
|
|||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public HotSpotSymbol asSymbol() {
|
|
||||||
if (metaspaceObject instanceof HotSpotSymbol) {
|
|
||||||
return (HotSpotSymbol) metaspaceObject;
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -32,7 +32,7 @@ import java.util.Formatter;
|
|||||||
import jdk.vm.ci.meta.JavaMethod;
|
import jdk.vm.ci.meta.JavaMethod;
|
||||||
import jdk.vm.ci.meta.ResolvedJavaMethod;
|
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) {
|
public static String applyFormattingFlagsAndWidth(String s, int flags, int width) {
|
||||||
if (flags == 0 && width < 0) {
|
if (flags == 0 && width < 0) {
|
||||||
|
@ -33,7 +33,7 @@ import jdk.vm.ci.meta.ResolvedJavaField;
|
|||||||
import jdk.vm.ci.meta.ResolvedJavaMethod;
|
import jdk.vm.ci.meta.ResolvedJavaMethod;
|
||||||
import jdk.vm.ci.meta.ResolvedJavaType;
|
import jdk.vm.ci.meta.ResolvedJavaType;
|
||||||
|
|
||||||
public class HotSpotMethodHandleAccessProvider implements MethodHandleAccessProvider, HotSpotProxified {
|
public class HotSpotMethodHandleAccessProvider implements MethodHandleAccessProvider {
|
||||||
|
|
||||||
private final ConstantReflectionProvider constantReflection;
|
private final ConstantReflectionProvider constantReflection;
|
||||||
|
|
||||||
|
@ -28,7 +28,6 @@ import java.lang.invoke.CallSite;
|
|||||||
import java.lang.invoke.ConstantCallSite;
|
import java.lang.invoke.ConstantCallSite;
|
||||||
import java.lang.invoke.MethodHandle;
|
import java.lang.invoke.MethodHandle;
|
||||||
|
|
||||||
import jdk.vm.ci.inittimer.SuppressFBWarnings;
|
|
||||||
import jdk.vm.ci.meta.Assumptions;
|
import jdk.vm.ci.meta.Assumptions;
|
||||||
import jdk.vm.ci.meta.Constant;
|
import jdk.vm.ci.meta.Constant;
|
||||||
import jdk.vm.ci.meta.JavaConstant;
|
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
|
* Represents a constant non-{@code null} object reference, within the compiler and across the
|
||||||
* compiler/runtime interface.
|
* compiler/runtime interface.
|
||||||
*/
|
*/
|
||||||
final class HotSpotObjectConstantImpl implements HotSpotObjectConstant, HotSpotProxified {
|
final class HotSpotObjectConstantImpl implements HotSpotObjectConstant {
|
||||||
|
|
||||||
static JavaConstant forObject(Object object) {
|
static JavaConstant forObject(Object object) {
|
||||||
return forObject(object, false);
|
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) {
|
public static JavaConstant forBoxedValue(JavaKind kind, Object value) {
|
||||||
if (kind == JavaKind.Object) {
|
if (kind == JavaKind.Object) {
|
||||||
return HotSpotObjectConstantImpl.forObject(value);
|
return HotSpotObjectConstantImpl.forObject(value);
|
||||||
@ -82,22 +72,11 @@ final class HotSpotObjectConstantImpl implements HotSpotObjectConstant, HotSpotP
|
|||||||
|
|
||||||
private final Object object;
|
private final Object object;
|
||||||
private final boolean compressed;
|
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) {
|
private HotSpotObjectConstantImpl(Object object, boolean compressed) {
|
||||||
this(object, compressed, 0, false);
|
this.object = object;
|
||||||
|
this.compressed = compressed;
|
||||||
|
assert object != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -118,12 +97,12 @@ final class HotSpotObjectConstantImpl implements HotSpotObjectConstant, HotSpotP
|
|||||||
|
|
||||||
public JavaConstant compress() {
|
public JavaConstant compress() {
|
||||||
assert !compressed;
|
assert !compressed;
|
||||||
return new HotSpotObjectConstantImpl(object, true, stableDimension, isDefaultStable);
|
return new HotSpotObjectConstantImpl(object, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public JavaConstant uncompress() {
|
public JavaConstant uncompress() {
|
||||||
assert compressed;
|
assert compressed;
|
||||||
return new HotSpotObjectConstantImpl(object, false, stableDimension, isDefaultStable);
|
return new HotSpotObjectConstantImpl(object, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public HotSpotResolvedObjectType getType() {
|
public HotSpotResolvedObjectType getType() {
|
||||||
@ -248,7 +227,7 @@ final class HotSpotObjectConstantImpl implements HotSpotObjectConstant, HotSpotP
|
|||||||
return true;
|
return true;
|
||||||
} else if (o instanceof HotSpotObjectConstantImpl) {
|
} else if (o instanceof HotSpotObjectConstantImpl) {
|
||||||
HotSpotObjectConstantImpl other = (HotSpotObjectConstantImpl) o;
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
@ -266,19 +245,4 @@ final class HotSpotObjectConstantImpl implements HotSpotObjectConstant, HotSpotP
|
|||||||
public String toString() {
|
public String toString() {
|
||||||
return (compressed ? "NarrowOop" : getJavaKind().getJavaName()) + "[" + JavaKind.Object.format(object) + "]";
|
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
@ -28,10 +28,7 @@ import jdk.vm.ci.meta.JavaTypeProfile;
|
|||||||
import jdk.vm.ci.meta.ProfilingInfo;
|
import jdk.vm.ci.meta.ProfilingInfo;
|
||||||
import jdk.vm.ci.meta.TriState;
|
import jdk.vm.ci.meta.TriState;
|
||||||
|
|
||||||
public final class HotSpotProfilingInfo implements ProfilingInfo, HotSpotProxified {
|
public final class HotSpotProfilingInfo implements ProfilingInfo {
|
||||||
|
|
||||||
// private static final DebugMetric metricInsufficentSpace =
|
|
||||||
// Debug.metric("InsufficientSpaceForProfilingData");
|
|
||||||
|
|
||||||
private final HotSpotMethodData methodData;
|
private final HotSpotMethodData methodData;
|
||||||
private final HotSpotResolvedJavaMethod method;
|
private final HotSpotResolvedJavaMethod method;
|
||||||
@ -162,7 +159,6 @@ public final class HotSpotProfilingInfo implements ProfilingInfo, HotSpotProxifi
|
|||||||
|
|
||||||
if (!methodData.isWithin(currentPosition)) {
|
if (!methodData.isWithin(currentPosition)) {
|
||||||
exceptionPossiblyNotRecorded = true;
|
exceptionPossiblyNotRecorded = true;
|
||||||
// metricInsufficentSpace.increment();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,7 +53,7 @@ public final class HotSpotReferenceMap extends ReferenceMap {
|
|||||||
}
|
}
|
||||||
if (obj instanceof HotSpotReferenceMap) {
|
if (obj instanceof HotSpotReferenceMap) {
|
||||||
HotSpotReferenceMap that = (HotSpotReferenceMap) obj;
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -43,11 +43,4 @@ public interface HotSpotResolvedJavaField extends ResolvedJavaField {
|
|||||||
* Determines if this field should be treated as a constant.
|
* Determines if this field should be treated as a constant.
|
||||||
*/
|
*/
|
||||||
boolean isStable();
|
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();
|
|
||||||
}
|
}
|
||||||
|
@ -22,16 +22,15 @@
|
|||||||
*/
|
*/
|
||||||
package jdk.vm.ci.hotspot;
|
package jdk.vm.ci.hotspot;
|
||||||
|
|
||||||
import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.runtime;
|
|
||||||
import static jdk.vm.ci.hotspot.HotSpotVMConfig.config;
|
import static jdk.vm.ci.hotspot.HotSpotVMConfig.config;
|
||||||
|
|
||||||
import java.lang.annotation.Annotation;
|
import java.lang.annotation.Annotation;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
|
|
||||||
|
import jdk.internal.vm.annotation.Stable;
|
||||||
import jdk.vm.ci.common.JVMCIError;
|
import jdk.vm.ci.common.JVMCIError;
|
||||||
import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.Option;
|
import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.Option;
|
||||||
import jdk.vm.ci.meta.JavaType;
|
import jdk.vm.ci.meta.JavaType;
|
||||||
import jdk.vm.ci.meta.LocationIdentity;
|
|
||||||
import jdk.vm.ci.meta.MetaAccessProvider;
|
import jdk.vm.ci.meta.MetaAccessProvider;
|
||||||
import jdk.vm.ci.meta.ModifiersProvider;
|
import jdk.vm.ci.meta.ModifiersProvider;
|
||||||
import jdk.vm.ci.meta.ResolvedJavaField;
|
import jdk.vm.ci.meta.ResolvedJavaField;
|
||||||
@ -40,7 +39,7 @@ import jdk.vm.ci.meta.ResolvedJavaType;
|
|||||||
/**
|
/**
|
||||||
* Represents a field in a HotSpot type.
|
* Represents a field in a HotSpot type.
|
||||||
*/
|
*/
|
||||||
class HotSpotResolvedJavaFieldImpl implements HotSpotResolvedJavaField, HotSpotProxified {
|
class HotSpotResolvedJavaFieldImpl implements HotSpotResolvedJavaField {
|
||||||
|
|
||||||
private final HotSpotResolvedObjectTypeImpl holder;
|
private final HotSpotResolvedObjectTypeImpl holder;
|
||||||
private final String name;
|
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.
|
* This value contains all flags as stored in the VM including internal ones.
|
||||||
*/
|
*/
|
||||||
private final int modifiers;
|
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) {
|
HotSpotResolvedJavaFieldImpl(HotSpotResolvedObjectTypeImpl holder, String name, JavaType type, long offset, int modifiers) {
|
||||||
this.holder = holder;
|
this.holder = holder;
|
||||||
@ -190,14 +152,7 @@ class HotSpotResolvedJavaFieldImpl implements HotSpotResolvedJavaField, HotSpotP
|
|||||||
* @return true if field has {@link Stable} annotation, false otherwise
|
* @return true if field has {@link Stable} annotation, false otherwise
|
||||||
*/
|
*/
|
||||||
public boolean isStable() {
|
public boolean isStable() {
|
||||||
if ((config().jvmAccFieldStable & modifiers) != 0) {
|
return (config().jvmAccFieldStable & modifiers) != 0;
|
||||||
return true;
|
|
||||||
}
|
|
||||||
assert getAnnotation(Stable.class) == null;
|
|
||||||
if (Option.ImplicitStableValues.getBoolean() && isImplicitStableField()) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -209,6 +164,15 @@ class HotSpotResolvedJavaFieldImpl implements HotSpotResolvedJavaField, HotSpotP
|
|||||||
return new Annotation[0];
|
return new Annotation[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Annotation[] getDeclaredAnnotations() {
|
||||||
|
Field javaField = toJava();
|
||||||
|
if (javaField != null) {
|
||||||
|
return javaField.getDeclaredAnnotations();
|
||||||
|
}
|
||||||
|
return new Annotation[0];
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
|
public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
|
||||||
Field javaField = toJava();
|
Field javaField = toJava();
|
||||||
@ -234,69 +198,4 @@ class HotSpotResolvedJavaFieldImpl implements HotSpotResolvedJavaField, HotSpotP
|
|||||||
return null;
|
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -46,11 +46,8 @@ import jdk.vm.ci.meta.JavaConstant;
|
|||||||
import jdk.vm.ci.meta.JavaMethod;
|
import jdk.vm.ci.meta.JavaMethod;
|
||||||
import jdk.vm.ci.meta.JavaType;
|
import jdk.vm.ci.meta.JavaType;
|
||||||
import jdk.vm.ci.meta.LineNumberTable;
|
import jdk.vm.ci.meta.LineNumberTable;
|
||||||
import jdk.vm.ci.meta.LineNumberTableImpl;
|
|
||||||
import jdk.vm.ci.meta.Local;
|
import jdk.vm.ci.meta.Local;
|
||||||
import jdk.vm.ci.meta.LocalImpl;
|
|
||||||
import jdk.vm.ci.meta.LocalVariableTable;
|
import jdk.vm.ci.meta.LocalVariableTable;
|
||||||
import jdk.vm.ci.meta.LocalVariableTableImpl;
|
|
||||||
import jdk.vm.ci.meta.ModifiersProvider;
|
import jdk.vm.ci.meta.ModifiersProvider;
|
||||||
import jdk.vm.ci.meta.ProfilingInfo;
|
import jdk.vm.ci.meta.ProfilingInfo;
|
||||||
import jdk.vm.ci.meta.ResolvedJavaMethod;
|
import jdk.vm.ci.meta.ResolvedJavaMethod;
|
||||||
@ -62,7 +59,7 @@ import jdk.vm.ci.meta.TriState;
|
|||||||
/**
|
/**
|
||||||
* Implementation of {@link JavaMethod} for resolved HotSpot methods.
|
* 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.
|
* Reference to metaspace Method object.
|
||||||
@ -472,7 +469,19 @@ final class HotSpotResolvedJavaMethodImpl extends HotSpotMethod implements HotSp
|
|||||||
@Override
|
@Override
|
||||||
public Annotation[] getAnnotations() {
|
public Annotation[] getAnnotations() {
|
||||||
Executable javaMethod = toJava();
|
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
|
@Override
|
||||||
@ -559,7 +568,7 @@ final class HotSpotResolvedJavaMethodImpl extends HotSpotMethod implements HotSp
|
|||||||
line[i] = (int) values[i * 2 + 1];
|
line[i] = (int) values[i * 2 + 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
return new LineNumberTableImpl(line, bci);
|
return new LineNumberTable(line, bci);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -584,13 +593,13 @@ final class HotSpotResolvedJavaMethodImpl extends HotSpotMethod implements HotSp
|
|||||||
String localName = getConstantPool().lookupUtf8(nameCpIndex);
|
String localName = getConstantPool().lookupUtf8(nameCpIndex);
|
||||||
String localType = getConstantPool().lookupUtf8(typeCpIndex);
|
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
|
// Go to the next LocalVariableTableElement
|
||||||
localVariableTableElement += config.localVariableTableElementSize;
|
localVariableTableElement += config.localVariableTableElementSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
return new LocalVariableTableImpl(locals);
|
return new LocalVariableTable(locals);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -28,7 +28,6 @@ import jdk.vm.ci.meta.ConstantPool;
|
|||||||
import jdk.vm.ci.meta.JavaConstant;
|
import jdk.vm.ci.meta.JavaConstant;
|
||||||
import jdk.vm.ci.meta.JavaKind;
|
import jdk.vm.ci.meta.JavaKind;
|
||||||
import jdk.vm.ci.meta.JavaType;
|
import jdk.vm.ci.meta.JavaType;
|
||||||
import jdk.vm.ci.meta.ResolvedJavaField;
|
|
||||||
import jdk.vm.ci.meta.ResolvedJavaMethod;
|
import jdk.vm.ci.meta.ResolvedJavaMethod;
|
||||||
import jdk.vm.ci.meta.ResolvedJavaType;
|
import jdk.vm.ci.meta.ResolvedJavaType;
|
||||||
|
|
||||||
@ -60,8 +59,6 @@ public interface HotSpotResolvedObjectType extends ResolvedJavaType {
|
|||||||
|
|
||||||
HotSpotResolvedObjectType findLeastCommonAncestor(ResolvedJavaType otherType);
|
HotSpotResolvedObjectType findLeastCommonAncestor(ResolvedJavaType otherType);
|
||||||
|
|
||||||
HotSpotResolvedObjectType asExactType();
|
|
||||||
|
|
||||||
default boolean isPrimitive() {
|
default boolean isPrimitive() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -109,6 +106,4 @@ public interface HotSpotResolvedObjectType extends ResolvedJavaType {
|
|||||||
HotSpotResolvedObjectType getEnclosingType();
|
HotSpotResolvedObjectType getEnclosingType();
|
||||||
|
|
||||||
ResolvedJavaMethod getClassInitializer();
|
ResolvedJavaMethod getClassInitializer();
|
||||||
|
|
||||||
ResolvedJavaField createField(String name, JavaType type, long offset, int modifiers);
|
|
||||||
}
|
}
|
||||||
|
@ -52,12 +52,11 @@ import jdk.vm.ci.meta.ModifiersProvider;
|
|||||||
import jdk.vm.ci.meta.ResolvedJavaField;
|
import jdk.vm.ci.meta.ResolvedJavaField;
|
||||||
import jdk.vm.ci.meta.ResolvedJavaMethod;
|
import jdk.vm.ci.meta.ResolvedJavaMethod;
|
||||||
import jdk.vm.ci.meta.ResolvedJavaType;
|
import jdk.vm.ci.meta.ResolvedJavaType;
|
||||||
import jdk.vm.ci.meta.TrustedInterface;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implementation of {@link JavaType} for resolved non-primitive HotSpot classes.
|
* 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.
|
* The Java class this type represents.
|
||||||
@ -128,9 +127,9 @@ final class HotSpotResolvedObjectTypeImpl extends HotSpotResolvedJavaType implem
|
|||||||
*/
|
*/
|
||||||
long getMetaspaceKlass() {
|
long getMetaspaceKlass() {
|
||||||
if (HotSpotJVMCIRuntime.getHostWordKind() == JavaKind.Long) {
|
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() {
|
public long getMetaspacePointer() {
|
||||||
@ -167,9 +166,25 @@ final class HotSpotResolvedObjectTypeImpl extends HotSpotResolvedJavaType implem
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AssumptionResult<ResolvedJavaType> findLeafConcreteSubtype() {
|
public AssumptionResult<ResolvedJavaType> findLeafConcreteSubtype() {
|
||||||
|
if (isLeaf()) {
|
||||||
|
// No assumptions are required.
|
||||||
|
return new AssumptionResult<>(this);
|
||||||
|
}
|
||||||
HotSpotVMConfig config = config();
|
HotSpotVMConfig config = config();
|
||||||
if (isArray()) {
|
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()) {
|
} else if (isInterface()) {
|
||||||
HotSpotResolvedObjectTypeImpl implementor = getSingleImplementor();
|
HotSpotResolvedObjectTypeImpl implementor = getSingleImplementor();
|
||||||
/*
|
/*
|
||||||
@ -192,8 +207,7 @@ final class HotSpotResolvedObjectTypeImpl extends HotSpotResolvedJavaType implem
|
|||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
return concreteSubtype(implementor);
|
||||||
return new AssumptionResult<>(implementor, new LeafType(implementor), new ConcreteSubtype(this, implementor));
|
|
||||||
} else {
|
} else {
|
||||||
HotSpotResolvedObjectTypeImpl type = this;
|
HotSpotResolvedObjectTypeImpl type = this;
|
||||||
while (type.isAbstract()) {
|
while (type.isAbstract()) {
|
||||||
@ -207,7 +221,7 @@ final class HotSpotResolvedObjectTypeImpl extends HotSpotResolvedJavaType implem
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
if (this.isAbstract()) {
|
if (this.isAbstract()) {
|
||||||
return new AssumptionResult<>(type, new LeafType(type), new ConcreteSubtype(this, type));
|
return concreteSubtype(type);
|
||||||
} else {
|
} else {
|
||||||
assert this.equals(type);
|
assert this.equals(type);
|
||||||
return new AssumptionResult<>(type, new LeafType(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
|
* 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.
|
* {@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
|
@Override
|
||||||
public AssumptionResult<Boolean> hasFinalizableSubclass() {
|
public AssumptionResult<Boolean> hasFinalizableSubclass() {
|
||||||
assert !isArray();
|
assert !isArray();
|
||||||
@ -470,7 +487,7 @@ final class HotSpotResolvedObjectTypeImpl extends HotSpotResolvedJavaType implem
|
|||||||
return result;
|
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;
|
HotSpotResolvedJavaField result = null;
|
||||||
|
|
||||||
final int flags = rawFlags & ModifiersProvider.jvmFieldModifiers();
|
final int flags = rawFlags & ModifiersProvider.jvmFieldModifiers();
|
||||||
@ -490,7 +507,12 @@ final class HotSpotResolvedObjectTypeImpl extends HotSpotResolvedJavaType implem
|
|||||||
fieldCache.put(id, result);
|
fieldCache.put(id, result);
|
||||||
} else {
|
} else {
|
||||||
assert result.getName().equals(fieldName);
|
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.offset() == offset;
|
||||||
assert result.getModifiers() == flags;
|
assert result.getModifiers() == flags;
|
||||||
}
|
}
|
||||||
@ -744,6 +766,11 @@ final class HotSpotResolvedObjectTypeImpl extends HotSpotResolvedJavaType implem
|
|||||||
return mirror().getAnnotations();
|
return mirror().getAnnotations();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Annotation[] getDeclaredAnnotations() {
|
||||||
|
return mirror().getDeclaredAnnotations();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
|
public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
|
||||||
return mirror().getAnnotation(annotationClass);
|
return mirror().getAnnotation(annotationClass);
|
||||||
@ -878,11 +905,6 @@ final class HotSpotResolvedObjectTypeImpl extends HotSpotResolvedJavaType implem
|
|||||||
return "HotSpotType<" + getName() + ", resolved>";
|
return "HotSpotType<" + getName() + ", resolved>";
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isTrustedInterfaceType() {
|
|
||||||
return TrustedInterface.class.isAssignableFrom(mirror());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isCloneableWithAllocation() {
|
public boolean isCloneableWithAllocation() {
|
||||||
return (getAccessFlags() & config().jvmAccIsCloneableFast) != 0;
|
return (getAccessFlags() & config().jvmAccIsCloneableFast) != 0;
|
||||||
|
@ -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.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -40,7 +40,7 @@ import jdk.vm.ci.meta.ResolvedJavaType;
|
|||||||
/**
|
/**
|
||||||
* Implementation of {@link JavaType} for primitive HotSpot types.
|
* 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;
|
private final JavaKind kind;
|
||||||
|
|
||||||
@ -55,7 +55,7 @@ public final class HotSpotResolvedPrimitiveType extends HotSpotResolvedJavaType
|
|||||||
* @param kind the Kind to create the mirror for
|
* @param kind the Kind to create the mirror for
|
||||||
*/
|
*/
|
||||||
public HotSpotResolvedPrimitiveType(JavaKind kind) {
|
public HotSpotResolvedPrimitiveType(JavaKind kind) {
|
||||||
super(String.valueOf(Character.toUpperCase(kind.getTypeChar())));
|
super(String.valueOf(kind.getTypeChar()));
|
||||||
this.kind = kind;
|
this.kind = kind;
|
||||||
assert mirror().isPrimitive() : mirror() + " not a primitive type";
|
assert mirror().isPrimitive() : mirror() + " not a primitive type";
|
||||||
}
|
}
|
||||||
@ -83,11 +83,6 @@ public final class HotSpotResolvedPrimitiveType extends HotSpotResolvedJavaType
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public ResolvedJavaType asExactType() {
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ResolvedJavaType getSuperclass() {
|
public ResolvedJavaType getSuperclass() {
|
||||||
return null;
|
return null;
|
||||||
@ -203,6 +198,11 @@ public final class HotSpotResolvedPrimitiveType extends HotSpotResolvedJavaType
|
|||||||
return new Annotation[0];
|
return new Annotation[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Annotation[] getDeclaredAnnotations() {
|
||||||
|
return new Annotation[0];
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
|
public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
|
||||||
return null;
|
return null;
|
||||||
@ -263,11 +263,6 @@ public final class HotSpotResolvedPrimitiveType extends HotSpotResolvedJavaType
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isTrustedInterfaceType() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isCloneableWithAllocation() {
|
public boolean isCloneableWithAllocation() {
|
||||||
return false;
|
return false;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -24,7 +24,7 @@ package jdk.vm.ci.hotspot;
|
|||||||
|
|
||||||
import jdk.vm.ci.meta.JavaConstant;
|
import jdk.vm.ci.meta.JavaConstant;
|
||||||
import jdk.vm.ci.meta.JavaKind;
|
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.VMConstant;
|
||||||
import jdk.vm.ci.meta.Value;
|
import jdk.vm.ci.meta.Value;
|
||||||
|
|
||||||
@ -32,8 +32,8 @@ public final class HotSpotSentinelConstant extends Value implements JavaConstant
|
|||||||
|
|
||||||
private final JavaKind javaKind;
|
private final JavaKind javaKind;
|
||||||
|
|
||||||
public HotSpotSentinelConstant(LIRKind lirKind, JavaKind javaKind) {
|
public HotSpotSentinelConstant(ValueKind<?> valueKind, JavaKind javaKind) {
|
||||||
super(lirKind);
|
super(valueKind);
|
||||||
this.javaKind = javaKind;
|
this.javaKind = javaKind;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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 + ">";
|
|
||||||
}
|
|
||||||
}
|
|
@ -22,7 +22,6 @@
|
|||||||
*/
|
*/
|
||||||
package jdk.vm.ci.hotspot;
|
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.HotSpotJVMCIRuntime.runtime;
|
||||||
import static jdk.vm.ci.hotspot.UnsafeAccess.UNSAFE;
|
import static jdk.vm.ci.hotspot.UnsafeAccess.UNSAFE;
|
||||||
|
|
||||||
@ -31,6 +30,8 @@ import java.lang.reflect.Modifier;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Iterator;
|
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.common.JVMCIError;
|
||||||
import jdk.vm.ci.hotspotvmconfig.HotSpotVMAddress;
|
import jdk.vm.ci.hotspotvmconfig.HotSpotVMAddress;
|
||||||
import jdk.vm.ci.hotspotvmconfig.HotSpotVMConstant;
|
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.HotSpotVMField;
|
||||||
import jdk.vm.ci.hotspotvmconfig.HotSpotVMFlag;
|
import jdk.vm.ci.hotspotvmconfig.HotSpotVMFlag;
|
||||||
import jdk.vm.ci.hotspotvmconfig.HotSpotVMType;
|
import jdk.vm.ci.hotspotvmconfig.HotSpotVMType;
|
||||||
import jdk.internal.misc.Unsafe;
|
|
||||||
|
|
||||||
//JaCoCo Exclude
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used to access native configuration details.
|
* Used to access native configuration details.
|
||||||
@ -108,6 +106,27 @@ public class HotSpotVMConfig {
|
|||||||
return getClass().getSimpleName();
|
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.
|
* 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::_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;
|
@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 = "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;
|
@HotSpotVMConstant(name = "InvocationEntryBci") @Stable public int invocationEntryBci;
|
||||||
|
|
||||||
@HotSpotVMField(name = "JVMCIEnv::_task", type = "CompileTask*", get = HotSpotVMField.Type.OFFSET) @Stable public int jvmciEnvTaskOffset;
|
@HotSpotVMField(name = "JVMCIEnv::_task", type = "CompileTask*", get = HotSpotVMField.Type.OFFSET) @Stable public int jvmciEnvTaskOffset;
|
||||||
|
@ -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.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -20,19 +20,21 @@
|
|||||||
* or visit www.oracle.com if you need additional information or have any
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
* questions.
|
* questions.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package jdk.vm.ci.hotspot;
|
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
|
* Used to suppress <a href="http://findbugs.sourceforge.net">FindBugs</a> warnings.
|
||||||
* code. It is specially recognized during class file parsing in the same way as that annotation.
|
|
||||||
*/
|
*/
|
||||||
@Target(ElementType.FIELD)
|
@interface SuppressFBWarnings {
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
/**
|
||||||
public @interface Stable {
|
* 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();
|
||||||
}
|
}
|
@ -20,23 +20,30 @@
|
|||||||
* or visit www.oracle.com if you need additional information or have any
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
* questions.
|
* questions.
|
||||||
*/
|
*/
|
||||||
package jdk.vm.ci.hotspot.events;
|
package jdk.vm.ci.hotspot.services;
|
||||||
|
|
||||||
import jdk.vm.ci.common.JVMCIError;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An empty implementation for {@link EventProvider}. This implementation is used when no logging is
|
* An empty implementation for {@link EventProvider}. This implementation is used when no logging is
|
||||||
* requested.
|
* 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() {
|
public CompilationEvent newCompilationEvent() {
|
||||||
return new EmptyCompilationEvent();
|
return new EmptyCompilationEvent();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class EmptyCompilationEvent implements CompilationEvent {
|
static class EmptyCompilationEvent implements CompilationEvent {
|
||||||
public void commit() {
|
public void commit() {
|
||||||
throw JVMCIError.shouldNotReachHere();
|
throw shouldNotReachHere();
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean shouldWrite() {
|
public boolean shouldWrite() {
|
||||||
@ -51,41 +58,42 @@ public final class EmptyEventProvider implements EventProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void setMethod(String method) {
|
public void setMethod(String method) {
|
||||||
throw JVMCIError.shouldNotReachHere();
|
throw shouldNotReachHere();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setCompileId(int compileId) {
|
public void setCompileId(int compileId) {
|
||||||
throw JVMCIError.shouldNotReachHere();
|
throw shouldNotReachHere();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setCompileLevel(int compileLevel) {
|
public void setCompileLevel(int compileLevel) {
|
||||||
throw JVMCIError.shouldNotReachHere();
|
throw shouldNotReachHere();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setSucceeded(boolean succeeded) {
|
public void setSucceeded(boolean succeeded) {
|
||||||
throw JVMCIError.shouldNotReachHere();
|
throw shouldNotReachHere();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setIsOsr(boolean isOsr) {
|
public void setIsOsr(boolean isOsr) {
|
||||||
throw JVMCIError.shouldNotReachHere();
|
throw shouldNotReachHere();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setCodeSize(int codeSize) {
|
public void setCodeSize(int codeSize) {
|
||||||
throw JVMCIError.shouldNotReachHere();
|
throw shouldNotReachHere();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setInlinedBytes(int inlinedBytes) {
|
public void setInlinedBytes(int inlinedBytes) {
|
||||||
throw JVMCIError.shouldNotReachHere();
|
throw shouldNotReachHere();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public CompilerFailureEvent newCompilerFailureEvent() {
|
public CompilerFailureEvent newCompilerFailureEvent() {
|
||||||
return new EmptyCompilerFailureEvent();
|
return new EmptyCompilerFailureEvent();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class EmptyCompilerFailureEvent implements CompilerFailureEvent {
|
static class EmptyCompilerFailureEvent implements CompilerFailureEvent {
|
||||||
public void commit() {
|
public void commit() {
|
||||||
throw JVMCIError.shouldNotReachHere();
|
throw shouldNotReachHere();
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean shouldWrite() {
|
public boolean shouldWrite() {
|
||||||
@ -94,11 +102,11 @@ public final class EmptyEventProvider implements EventProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void setCompileId(int compileId) {
|
public void setCompileId(int compileId) {
|
||||||
throw JVMCIError.shouldNotReachHere();
|
throw shouldNotReachHere();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setMessage(String message) {
|
public void setMessage(String message) {
|
||||||
throw JVMCIError.shouldNotReachHere();
|
throw shouldNotReachHere();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -20,17 +20,65 @@
|
|||||||
* or visit www.oracle.com if you need additional information or have any
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
* questions.
|
* 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.
|
* An instant event is an event that is not considered to have taken any time.
|
||||||
*/
|
*/
|
||||||
interface InstantEvent {
|
public interface InstantEvent {
|
||||||
/**
|
/**
|
||||||
* Commits the event.
|
* Commits the event.
|
||||||
*/
|
*/
|
||||||
@ -49,7 +97,7 @@ public interface EventProvider {
|
|||||||
/**
|
/**
|
||||||
* Timed events describe an operation that somehow consumes time.
|
* Timed events describe an operation that somehow consumes time.
|
||||||
*/
|
*/
|
||||||
interface TimedEvent extends InstantEvent {
|
public interface TimedEvent extends InstantEvent {
|
||||||
/**
|
/**
|
||||||
* Starts the timing for this event.
|
* Starts the timing for this event.
|
||||||
*/
|
*/
|
||||||
@ -66,12 +114,12 @@ public interface EventProvider {
|
|||||||
*
|
*
|
||||||
* @return a compilation event
|
* @return a compilation event
|
||||||
*/
|
*/
|
||||||
CompilationEvent newCompilationEvent();
|
public abstract CompilationEvent newCompilationEvent();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A compilation event.
|
* A compilation event.
|
||||||
*/
|
*/
|
||||||
interface CompilationEvent extends TimedEvent {
|
public interface CompilationEvent extends TimedEvent {
|
||||||
void setMethod(String method);
|
void setMethod(String method);
|
||||||
|
|
||||||
void setCompileId(int compileId);
|
void setCompileId(int compileId);
|
||||||
@ -92,12 +140,12 @@ public interface EventProvider {
|
|||||||
*
|
*
|
||||||
* @return a compiler failure event
|
* @return a compiler failure event
|
||||||
*/
|
*/
|
||||||
CompilerFailureEvent newCompilerFailureEvent();
|
public abstract CompilerFailureEvent newCompilerFailureEvent();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A compiler failure event.
|
* A compiler failure event.
|
||||||
*/
|
*/
|
||||||
interface CompilerFailureEvent extends InstantEvent {
|
public interface CompilerFailureEvent extends InstantEvent {
|
||||||
void setCompileId(int compileId);
|
void setCompileId(int compileId);
|
||||||
|
|
||||||
void setMessage(String message);
|
void setMessage(String message);
|
@ -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");
|
||||||
|
}
|
||||||
|
}
|
@ -20,19 +20,44 @@
|
|||||||
* or visit www.oracle.com if you need additional information or have any
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
* questions.
|
* questions.
|
||||||
*/
|
*/
|
||||||
package jdk.vm.ci.hotspot;
|
package jdk.vm.ci.hotspot.services;
|
||||||
|
|
||||||
import jdk.vm.ci.code.CompiledCode;
|
import jdk.vm.ci.code.CompiledCode;
|
||||||
import jdk.vm.ci.code.InstalledCode;
|
import jdk.vm.ci.code.InstalledCode;
|
||||||
import jdk.vm.ci.meta.JVMCIMetaAccessContext;
|
import jdk.vm.ci.hotspot.HotSpotCodeCacheProvider;
|
||||||
import jdk.vm.ci.meta.ResolvedJavaType;
|
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.
|
* 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 installedCode
|
||||||
* @param compiledCode
|
* @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
|
* Notify on completion of a bootstrap.
|
||||||
* 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
|
|
||||||
*/
|
*/
|
||||||
default JVMCIMetaAccessContext createMetaAccessContext(HotSpotJVMCIRuntime hotSpotJVMCIRuntime) {
|
public void notifyBootstrapFinished() {
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user