This commit is contained in:
Vladimir Ivanov 2016-05-20 18:05:09 +03:00
commit 36daf60d8f
349 changed files with 7202 additions and 5787 deletions

View file

@ -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,7 +181,10 @@ To build hotspot and import it into the JDK: "mx make hotspot import-hotspot"
# The OpenJDK build creates an empty cacerts file so copy one from # The 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, 'jre', 'lib', 'security', 'cacerts') srcCerts = join(mx.get_jdk(tag='default').home, 'lib', 'security', 'cacerts')
if not exists(srcCerts):
# Might be building with JDK8 which has cacerts under jre/
srcCerts = join(mx.get_jdk(tag='default').home, 'jre', 'lib', 'security', 'cacerts')
dstCerts = join(jdkImageDir, 'lib', 'security', 'cacerts') 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()

View file

@ -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"]
},
}, },
} }

View file

@ -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.

View file

@ -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();
}
} }

View file

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

View file

@ -178,10 +178,15 @@ void CompiledStaticCall::set_to_interpreted(methodHandle callee, address entry)
NativeMovConstReg* method_holder = nativeMovConstReg_at(stub + IC_pos_in_java_to_interp_stub); 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());

View file

@ -1404,7 +1404,7 @@ address MacroAssembler::get_stack_bang_address(int instruction, void *ucontext)
void MacroAssembler::cmpxchgw(ConditionRegister flag, Register dest_current_value, 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 (UseStaticBranchPredictionInCompareAndSwapPPC64) { if (!weak || use_result_reg) {
bne_predict_not_taken(CCR0, retry); // StXcx_ sets CCR0. if (UseStaticBranchPredictionInCompareAndSwapPPC64) {
} else { bne_predict_not_taken(CCR0, weak ? failed : retry); // StXcx_ sets CCR0.
bne( CCR0, retry); // StXcx_ sets CCR0. } else {
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 (UseStaticBranchPredictionInCompareAndSwapPPC64) { if (!weak || use_result_reg || failed_ext) {
bne_predict_not_taken(CCR0, retry); // stXcx_ sets CCR0 if (UseStaticBranchPredictionInCompareAndSwapPPC64) {
} else { bne_predict_not_taken(CCR0, weak ? failed : retry); // stXcx_ sets CCR0
bne( CCR0, retry); // stXcx_ sets CCR0 } else {
bne( CCR0, weak ? failed : retry); // stXcx_ sets CCR0
}
} }
// result in register (must do this at the end because int_flag_success can be the same register as one above) // result in register (must do this at the end because int_flag_success can be the same register as one above)

View file

@ -430,11 +430,11 @@ class MacroAssembler: public Assembler {
void cmpxchgw(ConditionRegister flag, 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,

View file

@ -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);

View file

@ -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());

View file

@ -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 '-';
} }

View file

@ -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;
/** /**

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2010, 2015, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2010, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * 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);
} }
} }

View file

@ -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;
}
} }

View file

@ -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 {
} }

View file

@ -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

View file

@ -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 {
} }

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2009, 2015, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2009, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * 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;

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2009, 2015, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2009, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * 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}.

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2009, 2015, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2009, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * 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;
} }

View file

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

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2010, 2015, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2010, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * 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;
} }

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2009, 2015, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2009, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * 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);
}
}
} }

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * 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,10 +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.hotspot; package jdk.vm.ci.code;
import jdk.vm.ci.meta.JavaKind;
import jdk.vm.ci.meta.ValueKind;
/** /**
* Marker interface for classes whose values are proxied during replay compilation capture. * Can be implemented by compilers to create custom {@link ValueKind} subclasses.
*/ */
public interface HotSpotProxified { public interface ValueKindFactory<K extends ValueKind<K>> {
K getValueKind(JavaKind javaKind);
} }

View file

@ -22,9 +22,6 @@
*/ */
package jdk.vm.ci.code; 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);
}
} }

View file

@ -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;

View file

@ -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;

View file

@ -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 {

View file

@ -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;

View file

@ -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;

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2009, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * 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 {

View file

@ -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);

View file

@ -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;

View file

@ -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));
}
} }

View file

@ -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();

View file

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

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * 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);
} }
} }

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -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);
} }

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * 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);
} }
} }

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * 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);
} }

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * 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);

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * 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) {

View file

@ -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();
/** /**

View file

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

View file

@ -25,7 +25,6 @@ package jdk.vm.ci.hotspot;
import jdk.vm.ci.code.StackSlot; import jdk.vm.ci.code.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;

View file

@ -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}.

View file

@ -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.forObject(element);
return HotSpotObjectConstantImpl.forStableArray(element, ((HotSpotObjectConstantImpl) array).getStableDimension() - 1, ((HotSpotObjectConstantImpl) array).isDefaultStable());
} else {
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());

View file

@ -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.

View file

@ -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;
} }
} }

View file

@ -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;

View file

@ -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.
* *

View file

@ -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.
* *

View file

@ -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);
} }

View file

@ -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();
}
}
} }

View file

@ -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();

View file

@ -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;

View file

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

View file

@ -27,7 +27,7 @@ import java.util.Objects;
import jdk.vm.ci.meta.Constant; import jdk.vm.ci.meta.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;
}
} }

View file

@ -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) {

View file

@ -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;

View file

@ -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;
}
} }

View file

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

View file

@ -28,10 +28,7 @@ import jdk.vm.ci.meta.JavaTypeProfile;
import jdk.vm.ci.meta.ProfilingInfo; import jdk.vm.ci.meta.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();
} }
} }

View file

@ -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;
} }
} }

View file

@ -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();
} }

View file

@ -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;
}
} }

View file

@ -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);
} }
/** /**

View file

@ -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);
} }

View file

@ -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;

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * 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;

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -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;
} }

View file

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

View file

@ -22,7 +22,6 @@
*/ */
package jdk.vm.ci.hotspot; 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;

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * 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();
} }

View file

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

View file

@ -20,23 +20,30 @@
* or visit www.oracle.com if you need additional information or have any * 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();
} }
} }

View file

@ -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);

View file

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

View file

@ -20,19 +20,44 @@
* or visit www.oracle.com if you need additional information or have any * 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;
} }
} }

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2009, 2015, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2009, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * 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
@ -28,7 +28,7 @@ import static jdk.vm.ci.meta.MetaUtil.internalNameToJava;
* Represents a resolved or unresolved type. Types include primitives, objects, {@code void}, and * Represents a resolved or unresolved type. Types include primitives, objects, {@code void}, and
* arrays thereof. * arrays thereof.
*/ */
public interface JavaType extends TrustedInterface { public interface JavaType {
/** /**
* Returns the name of this type in internal form. The following are examples of strings * Returns the name of this type in internal form. The following are examples of strings
@ -61,6 +61,15 @@ public interface JavaType extends TrustedInterface {
return name; return name;
} }
/**
* Checks whether this type is an array class.
*
* @return {@code true} if this type is an array class
*/
default boolean isArray() {
return getComponentType() != null;
}
/** /**
* For array types, gets the type of the components, or {@code null} if this is not an array * For array types, gets the type of the components, or {@code null} if this is not an array
* type. This method is analogous to {@link Class#getComponentType()}. * type. This method is analogous to {@link Class#getComponentType()}.

View file

@ -1,460 +0,0 @@
/*
* Copyright (c) 2014, 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.meta;
import java.util.ArrayList;
/**
* Represents the type of values in the LIR. It is composed of a {@link PlatformKind} that gives the
* low level representation of the value, and a {@link #referenceMask} that describes the location
* of object references in the value, and optionally a {@link #derivedReferenceBase}.
*
* <h2>Constructing {@link LIRKind} instances</h2>
*
* During LIR generation, every new {@link Value} should get a {@link LIRKind} of the correct
* {@link PlatformKind} that also contains the correct reference information. {@linkplain LIRKind
* LIRKinds} should be created as follows:
*
* <p>
* If the result value is created from one or more input values, the {@link LIRKind} should be
* created with {@link LIRKind#combine}(inputs). If the result has a different {@link PlatformKind}
* than the inputs, {@link LIRKind#combine}(inputs).{@link #changeType}(resultKind) should be used.
* <p>
* If the result is an exact copy of one of the inputs, {@link Value#getLIRKind()} can be used. Note
* that this is only correct for move-like operations, like conditional move or compare-and-swap.
* For convert operations, {@link LIRKind#combine} should be used.
* <p>
* If it is known that the result will be a reference (e.g. pointer arithmetic where the end result
* is a valid oop), {@link LIRKind#reference} should be used.
* <p>
* If it is known that the result will neither be a reference nor be derived from a reference,
* {@link LIRKind#value} can be used. If the operation producing this value has inputs, this is very
* likely wrong, and {@link LIRKind#combine} should be used instead.
* <p>
* If it is known that the result is derived from a reference in a way that the garbage collector
* can not track, {@link LIRKind#unknownReference} can be used. In most cases,
* {@link LIRKind#combine} should be used instead, since it is able to detect this automatically.
*/
public final class LIRKind {
private enum IllegalKind implements PlatformKind {
ILLEGAL;
private final EnumKey<IllegalKind> key = new EnumKey<>(this);
public Key getKey() {
return key;
}
public int getSizeInBytes() {
return 0;
}
public int getVectorLength() {
return 0;
}
public char getTypeChar() {
return '-';
}
}
/**
* The non-type. This uses {@link #unknownReference}, so it can never be part of an oop map.
*/
public static final LIRKind Illegal = unknownReference(IllegalKind.ILLEGAL);
private final PlatformKind platformKind;
private final int referenceMask;
private AllocatableValue derivedReferenceBase;
private static final int UNKNOWN_REFERENCE = -1;
private LIRKind(PlatformKind platformKind, int referenceMask, AllocatableValue derivedReferenceBase) {
this.platformKind = platformKind;
this.referenceMask = referenceMask;
this.derivedReferenceBase = derivedReferenceBase;
assert derivedReferenceBase == null || !derivedReferenceBase.getLIRKind().isDerivedReference() : "derived reference can't have another derived reference as base";
}
/**
* Create a {@link LIRKind} of type {@code platformKind} that contains a primitive value. Should
* be only used when it's guaranteed that the value is not even indirectly derived from a
* reference. Otherwise, {@link #combine(Value...)} should be used instead.
*/
public static LIRKind value(PlatformKind platformKind) {
return new LIRKind(platformKind, 0, null);
}
/**
* Create a {@link LIRKind} of type {@code platformKind} that contains a single tracked oop
* reference.
*/
public static LIRKind reference(PlatformKind platformKind) {
return derivedReference(platformKind, null);
}
/**
* Create a {@link LIRKind} of type {@code platformKind} that contains a derived reference.
*/
public static LIRKind derivedReference(PlatformKind platformKind, AllocatableValue base) {
int length = platformKind.getVectorLength();
assert 0 < length && length < 32 : "vector of " + length + " references not supported";
return new LIRKind(platformKind, (1 << length) - 1, base);
}
/**
* Create a {@link LIRKind} of type {@code platformKind} that contains a value that is derived
* from a reference in a non-linear way. Values of this {@link LIRKind} can not be live at
* safepoints. In most cases, this should not be called directly. {@link #combine} should be
* used instead to automatically propagate this information.
*/
public static LIRKind unknownReference(PlatformKind platformKind) {
return new LIRKind(platformKind, UNKNOWN_REFERENCE, null);
}
/**
* Create a derived reference.
*
* @param base An {@link AllocatableValue} containing the base pointer of the derived reference.
*/
public LIRKind makeDerivedReference(AllocatableValue base) {
assert !isUnknownReference() && derivedReferenceBase == null;
if (Value.ILLEGAL.equals(base)) {
return makeUnknownReference();
} else {
if (isValue()) {
return derivedReference(platformKind, base);
} else {
return new LIRKind(platformKind, referenceMask, base);
}
}
}
/**
* Derive a new type from inputs. The result will have the {@link PlatformKind} of one of the
* inputs. If all inputs are values, the result is a value. Otherwise, the result is an unknown
* reference.
*
* This method should be used to construct the result {@link LIRKind} of any operation that
* modifies values (e.g. arithmetics).
*/
public static LIRKind combine(Value... inputs) {
assert inputs.length > 0;
for (Value input : inputs) {
LIRKind kind = input.getLIRKind();
if (kind.isUnknownReference()) {
return kind;
} else if (!kind.isValue()) {
return kind.makeUnknownReference();
}
}
// all inputs are values, just return one of them
return inputs[0].getLIRKind();
}
/**
* Merge the types of the inputs. The result will have the {@link PlatformKind} of one of the
* inputs. If all inputs are values (references), the result is a value (reference). Otherwise,
* the result is an unknown reference.
*
* This method should be used to construct the result {@link LIRKind} of merge operation that
* does not modify values (e.g. phis).
*/
public static LIRKind merge(Value... inputs) {
assert inputs.length > 0;
ArrayList<LIRKind> kinds = new ArrayList<>(inputs.length);
for (int i = 0; i < inputs.length; i++) {
kinds.add(inputs[i].getLIRKind());
}
return merge(kinds);
}
/**
* Helper method to construct derived reference kinds. Returns the base value of a reference or
* derived reference. For values it returns {@code null}, and for unknown references it returns
* {@link Value#ILLEGAL}.
*/
public static AllocatableValue derivedBaseFromValue(AllocatableValue value) {
LIRKind kind = value.getLIRKind();
if (kind.isValue()) {
return null;
} else if (kind.isDerivedReference()) {
return kind.getDerivedReferenceBase();
} else if (kind.isUnknownReference()) {
return Value.ILLEGAL;
} else {
// kind is a reference
return value;
}
}
/**
* Helper method to construct derived reference kinds. If one of {@code base1} or {@code base2}
* are set, it creates a derived reference using it as the base. If both are set, the result is
* an unknown reference.
*/
public static LIRKind combineDerived(LIRKind kind, AllocatableValue base1, AllocatableValue base2) {
if (base1 == null && base2 == null) {
return kind;
} else if (base1 == null) {
return kind.makeDerivedReference(base2);
} else if (base2 == null) {
return kind.makeDerivedReference(base1);
} else {
return kind.makeUnknownReference();
}
}
/**
* @see #merge(Value...)
*/
public static LIRKind merge(Iterable<LIRKind> kinds) {
LIRKind mergeKind = null;
for (LIRKind kind : kinds) {
if (kind.isUnknownReference()) {
/**
* Kind is an unknown reference, therefore the result can only be also an unknown
* reference.
*/
mergeKind = kind;
break;
}
if (mergeKind == null) {
mergeKind = kind;
continue;
}
if (kind.isValue()) {
/* Kind is a value. */
if (mergeKind.referenceMask != 0) {
/*
* Inputs consists of values and references. Make the result an unknown
* reference.
*/
mergeKind = mergeKind.makeUnknownReference();
break;
}
/* Check that other inputs are also values. */
} else {
/* Kind is a reference. */
if (mergeKind.referenceMask != kind.referenceMask) {
/*
* Reference maps do not match so the result can only be an unknown reference.
*/
mergeKind = mergeKind.makeUnknownReference();
break;
}
}
}
assert mergeKind != null && verifyMerge(mergeKind, kinds);
// all inputs are values or references, just return one of them
return mergeKind;
}
private static boolean verifyMerge(LIRKind mergeKind, Iterable<LIRKind> kinds) {
for (LIRKind kind : kinds) {
assert mergeKind == null || verifyMoveKinds(mergeKind, kind) : String.format("Input kinds do not match %s vs. %s", mergeKind, kind);
}
return true;
}
/**
* Create a new {@link LIRKind} with the same reference information and a new
* {@linkplain #getPlatformKind platform kind}. If the new kind is a longer vector than this,
* the new elements are marked as untracked values.
*/
public LIRKind changeType(PlatformKind newPlatformKind) {
if (newPlatformKind == platformKind) {
return this;
} else if (isUnknownReference()) {
return unknownReference(newPlatformKind);
} else if (referenceMask == 0) {
// value type
return LIRKind.value(newPlatformKind);
} else {
// reference type
int newLength = Math.min(32, newPlatformKind.getVectorLength());
int newReferenceMask = referenceMask & (0xFFFFFFFF >>> (32 - newLength));
assert newReferenceMask != UNKNOWN_REFERENCE;
return new LIRKind(newPlatformKind, newReferenceMask, derivedReferenceBase);
}
}
/**
* Create a new {@link LIRKind} with a new {@linkplain #getPlatformKind platform kind}. If the
* new kind is longer than this, the reference positions are repeated to fill the vector.
*/
public LIRKind repeat(PlatformKind newPlatformKind) {
if (isUnknownReference()) {
return unknownReference(newPlatformKind);
} else if (referenceMask == 0) {
// value type
return LIRKind.value(newPlatformKind);
} else {
// reference type
int oldLength = platformKind.getVectorLength();
int newLength = newPlatformKind.getVectorLength();
assert oldLength <= newLength && newLength < 32 && (newLength % oldLength) == 0;
// repeat reference mask to fill new kind
int newReferenceMask = 0;
for (int i = 0; i < newLength; i += platformKind.getVectorLength()) {
newReferenceMask |= referenceMask << i;
}
assert newReferenceMask != UNKNOWN_REFERENCE;
return new LIRKind(newPlatformKind, newReferenceMask, derivedReferenceBase);
}
}
/**
* Create a new {@link LIRKind} with the same type, but marked as containing an
* {@link LIRKind#unknownReference}.
*/
public LIRKind makeUnknownReference() {
return new LIRKind(platformKind, UNKNOWN_REFERENCE, null);
}
/**
* Get the low level type that is used in code generation.
*/
public PlatformKind getPlatformKind() {
return platformKind;
}
/**
* Check whether this value is a derived reference.
*/
public boolean isDerivedReference() {
return getDerivedReferenceBase() != null;
}
/**
* Get the base value of a derived reference.
*/
public AllocatableValue getDerivedReferenceBase() {
return derivedReferenceBase;
}
/**
* Change the base value of a derived reference. This must be called on derived references only.
*/
public void setDerivedReferenceBase(AllocatableValue derivedReferenceBase) {
assert isDerivedReference();
this.derivedReferenceBase = derivedReferenceBase;
}
/**
* Check whether this value is derived from a reference in a non-linear way. If this returns
* {@code true}, this value must not be live at safepoints.
*/
public boolean isUnknownReference() {
return referenceMask == UNKNOWN_REFERENCE;
}
public int getReferenceCount() {
assert !isUnknownReference();
return Integer.bitCount(referenceMask);
}
/**
* Check whether the {@code idx}th part of this value is a reference that must be tracked at
* safepoints.
*
* @param idx The index into the vector if this is a vector kind. Must be 0 if this is a scalar
* kind.
*/
public boolean isReference(int idx) {
assert 0 <= idx && idx < platformKind.getVectorLength() : "invalid index " + idx + " in " + this;
return !isUnknownReference() && (referenceMask & 1 << idx) != 0;
}
/**
* Check whether this kind is a value type that doesn't need to be tracked at safepoints.
*/
public boolean isValue() {
return referenceMask == 0;
}
@Override
public String toString() {
if (isValue()) {
return platformKind.name();
} else if (isUnknownReference()) {
return platformKind.name() + "[*]";
} else {
StringBuilder ret = new StringBuilder();
ret.append(platformKind.name());
ret.append('[');
for (int i = 0; i < platformKind.getVectorLength(); i++) {
if (isReference(i)) {
ret.append('.');
} else {
ret.append(' ');
}
}
ret.append(']');
return ret.toString();
}
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((platformKind == null) ? 0 : platformKind.hashCode());
result = prime * result + referenceMask;
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (!(obj instanceof LIRKind)) {
return false;
}
LIRKind other = (LIRKind) obj;
return platformKind == other.platformKind && referenceMask == other.referenceMask;
}
public static boolean verifyMoveKinds(LIRKind dst, LIRKind src) {
if (src.equals(dst)) {
return true;
}
if (src.getPlatformKind().equals(dst.getPlatformKind())) {
return !src.isUnknownReference() || dst.isUnknownReference();
}
return false;
}
}

View file

@ -22,11 +22,30 @@
*/ */
package jdk.vm.ci.meta; package jdk.vm.ci.meta;
public interface LineNumberTable { public class LineNumberTable {
int[] getLineNumberEntries(); private final int[] lineNumbers;
private final int[] bci;
int[] getBciEntries(); public LineNumberTable(int[] lineNumbers, int[] bci) {
this.lineNumbers = lineNumbers;
this.bci = bci;
}
int getLineNumber(int bci); public int[] getLineNumberEntries() {
return lineNumbers;
}
public int[] getBciEntries() {
return bci;
}
public int getLineNumber(int atBci) {
for (int i = 0; i < this.bci.length - 1; i++) {
if (this.bci[i] <= atBci && atBci < this.bci[i + 1]) {
return lineNumbers[i];
}
}
return lineNumbers[lineNumbers.length - 1];
}
} }

View file

@ -1,54 +0,0 @@
/*
* Copyright (c) 2011, 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.meta;
public class LineNumberTableImpl implements LineNumberTable {
private final int[] lineNumbers;
private final int[] bci;
public LineNumberTableImpl(int[] lineNumbers, int[] bci) {
this.lineNumbers = lineNumbers;
this.bci = bci;
}
@Override
public int[] getLineNumberEntries() {
return lineNumbers;
}
@Override
public int[] getBciEntries() {
return bci;
}
@Override
public int getLineNumber(@SuppressWarnings("hiding") int bci) {
for (int i = 0; i < this.bci.length - 1; i++) {
if (this.bci[i] <= bci && bci < this.bci[i + 1]) {
return lineNumbers[i];
}
}
return lineNumbers[lineNumbers.length - 1];
}
}

View file

@ -22,15 +22,58 @@
*/ */
package jdk.vm.ci.meta; package jdk.vm.ci.meta;
public interface Local { public class Local {
int getStartBCI(); private final String name;
private final int startBci;
private final int endBci;
private final int slot;
private final JavaType type;
int getEndBCI(); public Local(String name, JavaType type, int startBci, int endBci, int slot) {
this.name = name;
this.startBci = startBci;
this.endBci = endBci;
this.slot = slot;
this.type = type;
}
int getSlot(); public int getStartBCI() {
return startBci;
}
String getName(); public int getEndBCI() {
return endBci;
}
JavaType getType(); public String getName() {
return name;
}
public JavaType getType() {
return type;
}
public int getSlot() {
return slot;
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof Local)) {
return false;
}
Local that = (Local) obj;
return this.name.equals(that.name) && this.startBci == that.startBci && this.endBci == that.endBci && this.slot == that.slot && this.type.equals(that.type);
}
@Override
public int hashCode() {
return super.hashCode();
}
@Override
public String toString() {
return "LocalImpl<name=" + name + ", type=" + type + ", startBci=" + startBci + ", endBci=" + endBci + ", slot=" + slot + ">";
}
} }

View file

@ -1,84 +0,0 @@
/*
* Copyright (c) 2011, 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.meta;
public class LocalImpl implements Local {
private final String name;
private final int startBci;
private final int endBci;
private final int slot;
private final JavaType type;
public LocalImpl(String name, JavaType type, int startBci, int endBci, int slot) {
this.name = name;
this.startBci = startBci;
this.endBci = endBci;
this.slot = slot;
this.type = type;
}
@Override
public int getStartBCI() {
return startBci;
}
@Override
public int getEndBCI() {
return endBci;
}
@Override
public String getName() {
return name;
}
@Override
public JavaType getType() {
return type;
}
@Override
public int getSlot() {
return slot;
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof LocalImpl)) {
return false;
}
LocalImpl that = (LocalImpl) obj;
return this.name.equals(that.name) && this.startBci == that.startBci && this.endBci == that.endBci && this.slot == that.slot && this.type.equals(that.type);
}
@Override
public int hashCode() {
return super.hashCode();
}
@Override
public String toString() {
return "LocalImpl<name=" + name + ", type=" + type + ", startBci=" + startBci + ", endBci=" + endBci + ", slot=" + slot + ">";
}
}

View file

@ -22,11 +22,42 @@
*/ */
package jdk.vm.ci.meta; package jdk.vm.ci.meta;
public interface LocalVariableTable { import java.util.ArrayList;
import java.util.List;
Local[] getLocals(); public class LocalVariableTable {
Local[] getLocalsAt(int bci); private final Local[] locals;
Local getLocal(int slot, int bci); public LocalVariableTable(Local[] locals) {
this.locals = locals;
}
public Local getLocal(int slot, int bci) {
Local result = null;
for (Local local : locals) {
if (local.getSlot() == slot && local.getStartBCI() <= bci && local.getEndBCI() >= bci) {
if (result == null) {
result = local;
} else {
throw new IllegalStateException("Locals overlap!");
}
}
}
return result;
}
public Local[] getLocals() {
return locals;
}
public Local[] getLocalsAt(int bci) {
List<Local> result = new ArrayList<>();
for (Local l : locals) {
if (l.getStartBCI() <= bci && bci <= l.getEndBCI()) {
result.add(l);
}
}
return result.toArray(new Local[result.size()]);
}
} }

View file

@ -1,67 +0,0 @@
/*
* Copyright (c) 2011, 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.meta;
import java.util.ArrayList;
import java.util.List;
public class LocalVariableTableImpl implements LocalVariableTable {
private final Local[] locals;
public LocalVariableTableImpl(Local[] locals) {
this.locals = locals;
}
@Override
public Local getLocal(int slot, int bci) {
Local result = null;
for (Local local : locals) {
if (local.getSlot() == slot && local.getStartBCI() <= bci && local.getEndBCI() >= bci) {
if (result == null) {
result = local;
} else {
throw new IllegalStateException("Locals overlap!");
}
}
}
return result;
}
@Override
public Local[] getLocals() {
return locals;
}
@Override
public Local[] getLocalsAt(int bci) {
List<Local> result = new ArrayList<>();
for (Local l : locals) {
if (l.getStartBCI() <= bci && bci <= l.getEndBCI()) {
result.add(l);
}
}
return result.toArray(new Local[result.size()]);
}
}

View file

@ -1,78 +0,0 @@
/*
* Copyright (c) 2011, 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.meta;
import java.util.IdentityHashMap;
// JaCoCo Exclude
/**
* Marker interface for location identities. A different location identity of two memory accesses
* guarantees that the two accesses do not interfere.
*
* Clients of {@link LocationIdentity} must use {@link #equals(Object)}, not {@code ==}, when
* comparing two {@link LocationIdentity} values for equality. Likewise, they must not use
* {@link IdentityHashMap}s with {@link LocationIdentity} values as keys.
*/
public abstract class LocationIdentity {
private static final class AnyLocationIdentity extends LocationIdentity {
@Override
public boolean isImmutable() {
return false;
}
@Override
public String toString() {
return "ANY_LOCATION";
}
}
public static final LocationIdentity ANY_LOCATION = new AnyLocationIdentity();
public static LocationIdentity any() {
return ANY_LOCATION;
}
/**
* Denotes a location is unchanging in all cases. Not that this is different than the Java
* notion of final which only requires definite assignment.
*/
public abstract boolean isImmutable();
public final boolean isMutable() {
return !isImmutable();
}
public final boolean isAny() {
return this == ANY_LOCATION;
}
public final boolean isSingle() {
return this != ANY_LOCATION;
}
public final boolean overlaps(LocationIdentity other) {
return isAny() || other.isAny() || this.equals(other);
}
}

View file

@ -35,8 +35,8 @@ public interface MemoryAccessProvider {
* @param displacement the displacement within the object in bytes * @param displacement the displacement within the object in bytes
* @return the read value encapsulated in a {@link JavaConstant} object, or {@code null} if the * @return the read value encapsulated in a {@link JavaConstant} object, or {@code null} if the
* value cannot be read. * value cannot be read.
* @throws IllegalArgumentException if {@code kind} is {@code null}, {@link JavaKind#Void} or * @throws IllegalArgumentException if {@code kind} is {@code null}, {@link JavaKind#Void}, not
* not {@linkplain JavaKind#isPrimitive() primitive} kind * {@link JavaKind#Object} or not {@linkplain JavaKind#isPrimitive() primitive} kind
*/ */
JavaConstant readUnsafeConstant(JavaKind kind, JavaConstant base, long displacement) throws IllegalArgumentException; JavaConstant readUnsafeConstant(JavaKind kind, JavaConstant base, long displacement) throws IllegalArgumentException;
@ -59,7 +59,9 @@ public interface MemoryAccessProvider {
* *
* @param base the base address from which the value is read * @param base the base address from which the value is read
* @param displacement the displacement within the object in bytes * @param displacement the displacement within the object in bytes
* @return the read value encapsulated in a {@link Constant} object * @return the read value encapsulated in a {@link Constant} object or {@code null} if the
* address computed from {@code base} and {@code displacement} does not denote a
* location holding an {@code Object} value
*/ */
JavaConstant readObjectConstant(Constant base, long displacement); JavaConstant readObjectConstant(Constant base, long displacement);
} }

View file

@ -81,8 +81,8 @@ public interface MetaAccessProvider {
long getMemorySize(JavaConstant constant); long getMemorySize(JavaConstant constant);
/** /**
* Parses a <a * Parses a
* href="http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms-4.3.3">method * <a href="http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms-4.3.3">method
* descriptor</a> into a {@link Signature}. The behavior of this method is undefined if the * descriptor</a> into a {@link Signature}. The behavior of this method is undefined if the
* method descriptor is not well formed. * method descriptor is not well formed.
*/ */

View file

@ -22,132 +22,14 @@
*/ */
package jdk.vm.ci.meta; package jdk.vm.ci.meta;
import java.io.PrintStream;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.lang.reflect.Modifier; import java.lang.reflect.Modifier;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Deque;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Set;
/** /**
* Miscellaneous collection of utility methods used by {@code jdk.vm.ci.meta} and its clients. * Miscellaneous collection of utility methods used by {@code jdk.vm.ci.meta} and its clients.
*/ */
public class MetaUtil { public class MetaUtil {
private static class ClassInfo {
public long totalSize;
public long instanceCount;
@Override
public String toString() {
return "totalSize=" + totalSize + ", instanceCount=" + instanceCount;
}
}
/**
* Returns the number of bytes occupied by this constant value or constant object and
* recursively all values reachable from this value.
*
* @param constant the constant whose bytes should be measured
* @param printTopN print total size and instance count of the top n classes is desired
* @return the number of bytes occupied by this constant
*/
public static long getMemorySizeRecursive(MetaAccessProvider access, ConstantReflectionProvider constantReflection, JavaConstant constant, PrintStream out, int printTopN) {
Set<JavaConstant> marked = new HashSet<>();
Deque<JavaConstant> stack = new ArrayDeque<>();
if (constant.getJavaKind() == JavaKind.Object && constant.isNonNull()) {
marked.add(constant);
}
final HashMap<ResolvedJavaType, ClassInfo> histogram = new HashMap<>();
stack.push(constant);
long sum = 0;
while (!stack.isEmpty()) {
JavaConstant c = stack.pop();
long memorySize = access.getMemorySize(constant);
sum += memorySize;
if (c.getJavaKind() == JavaKind.Object && c.isNonNull()) {
ResolvedJavaType clazz = access.lookupJavaType(c);
if (!histogram.containsKey(clazz)) {
histogram.put(clazz, new ClassInfo());
}
ClassInfo info = histogram.get(clazz);
info.instanceCount++;
info.totalSize += memorySize;
ResolvedJavaType type = access.lookupJavaType(c);
if (type.isArray()) {
if (!type.getComponentType().isPrimitive()) {
int length = constantReflection.readArrayLength(c);
for (int i = 0; i < length; i++) {
JavaConstant value = constantReflection.readArrayElement(c, i);
pushConstant(marked, stack, value);
}
}
} else {
ResolvedJavaField[] instanceFields = type.getInstanceFields(true);
for (ResolvedJavaField f : instanceFields) {
if (f.getJavaKind() == JavaKind.Object) {
JavaConstant value = constantReflection.readFieldValue(f, c);
pushConstant(marked, stack, value);
}
}
}
}
}
ArrayList<ResolvedJavaType> clazzes = new ArrayList<>();
clazzes.addAll(histogram.keySet());
Collections.sort(clazzes, new Comparator<ResolvedJavaType>() {
@Override
public int compare(ResolvedJavaType o1, ResolvedJavaType o2) {
long l1 = histogram.get(o1).totalSize;
long l2 = histogram.get(o2).totalSize;
if (l1 > l2) {
return -1;
} else if (l1 == l2) {
return 0;
} else {
return 1;
}
}
});
int z = 0;
for (ResolvedJavaType c : clazzes) {
if (z > printTopN) {
break;
}
out.println("Class " + c + ", " + histogram.get(c));
++z;
}
return sum;
}
private static void pushConstant(Set<JavaConstant> marked, Deque<JavaConstant> stack, JavaConstant value) {
if (value.isNonNull()) {
if (!marked.contains(value)) {
marked.add(value);
stack.push(value);
}
}
}
/**
* Calls {@link JavaType#resolve(ResolvedJavaType)} on an array of types.
*/
public static ResolvedJavaType[] resolveJavaTypes(JavaType[] types, ResolvedJavaType accessingClass) {
ResolvedJavaType[] result = new ResolvedJavaType[types.length];
for (int i = 0; i < result.length; i++) {
result[i] = types[i].resolve(accessingClass);
}
return result;
}
/** /**
* Extends the functionality of {@link Class#getSimpleName()} to include a non-empty string for * Extends the functionality of {@link Class#getSimpleName()} to include a non-empty string for
* anonymous and local classes. * anonymous and local classes.
@ -184,7 +66,17 @@ public class MetaUtil {
return name.substring(index + 1); return name.substring(index + 1);
} }
static String internalNameToJava(String name, boolean qualified, boolean classForNameCompatible) { /**
* Converts a type name in internal form to an external form.
*
* @param name the internal name to convert
* @param qualified whether the returned name should be qualified with the package name
* @param classForNameCompatible specifies if the returned name for array types should be in
* {@link Class#forName(String)} format (e.g., {@code "[Ljava.lang.Object;"},
* {@code "[[I"}) or in Java source code format (e.g., {@code "java.lang.Object[]"},
* {@code "int[][]"} ).
*/
public static String internalNameToJava(String name, boolean qualified, boolean classForNameCompatible) {
switch (name.charAt(0)) { switch (name.charAt(0)) {
case 'L': { case 'L': {
String result = name.substring(1, name.length() - 1).replace('/', '.'); String result = name.substring(1, name.length() - 1).replace('/', '.');
@ -206,19 +98,6 @@ public class MetaUtil {
} }
} }
/**
* Turns an class name in internal format into a resolved Java type.
*/
public static ResolvedJavaType classForName(String internal, MetaAccessProvider metaAccess, ClassLoader cl) {
JavaKind k = JavaKind.fromTypeString(internal);
try {
String n = internalNameToJava(internal, true, true);
return metaAccess.lookupJavaType(k.isPrimitive() ? k.toJavaClass() : Class.forName(n, true, cl));
} catch (ClassNotFoundException cnfe) {
throw new IllegalArgumentException("could not instantiate class described by " + internal, cnfe);
}
}
/** /**
* Convenient shortcut for calling * Convenient shortcut for calling
* {@link #appendLocation(StringBuilder, ResolvedJavaMethod, int)} without having to supply a * {@link #appendLocation(StringBuilder, ResolvedJavaMethod, int)} without having to supply a
@ -336,21 +215,6 @@ public class MetaUtil {
return result.toString(); return result.toString();
} }
/**
* Prepends the String {@code indentation} to every line in String {@code lines}, including a
* possibly non-empty line following the final newline.
*/
public static String indent(String lines, String indentation) {
if (lines.length() == 0) {
return lines;
}
final String newLine = "\n";
if (lines.endsWith(newLine)) {
return indentation + (lines.substring(0, lines.length() - 1)).replace(newLine, newLine + indentation) + newLine;
}
return indentation + lines.replace(newLine, newLine + indentation);
}
/** /**
* Gets a string representation of an object based soley on its class and its * Gets a string representation of an object based soley on its class and its
* {@linkplain System#identityHashCode(Object) identity hash code}. This avoids and calls to * {@linkplain System#identityHashCode(Object) identity hash code}. This avoids and calls to

View file

@ -42,7 +42,7 @@ public interface PlatformKind {
@Override @Override
public int hashCode() { public int hashCode() {
return e.ordinal() ^ e.name().hashCode(); return e.ordinal();
} }
@Override @Override

View file

@ -22,14 +22,14 @@
*/ */
package jdk.vm.ci.meta; package jdk.vm.ci.meta;
import java.lang.annotation.Annotation; import java.lang.reflect.AnnotatedElement;
import java.lang.reflect.Modifier; import java.lang.reflect.Modifier;
/** /**
* Represents a reference to a resolved Java field. Fields, like methods and types, are resolved * Represents a reference to a resolved Java field. Fields, like methods and types, are resolved
* through {@link ConstantPool constant pools}. * through {@link ConstantPool constant pools}.
*/ */
public interface ResolvedJavaField extends JavaField, ModifiersProvider { public interface ResolvedJavaField extends JavaField, ModifiersProvider, AnnotatedElement {
/** /**
* {@inheritDoc} * {@inheritDoc}
@ -59,27 +59,4 @@ public interface ResolvedJavaField extends JavaField, ModifiersProvider {
* this field. * this field.
*/ */
ResolvedJavaType getDeclaringClass(); ResolvedJavaType getDeclaringClass();
/**
* Returns all annotations of this field. If no annotations are present, an array of length 0 is
* returned.
*/
Annotation[] getAnnotations();
/**
* Returns the annotation for the specified type of this field, if such an annotation is
* present.
*
* @param annotationClass the Class object corresponding to the annotation type
* @return this element's annotation for the specified annotation type if present on this field,
* else {@code null}
*/
<T extends Annotation> T getAnnotation(Class<T> annotationClass);
/**
* Returns an object representing the unique location identity of this resolved Java field.
*
* @return the location identity of the field
*/
LocationIdentity getLocationIdentity();
} }

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