This commit is contained in:
Lana Steuck 2015-12-10 09:24:59 -08:00
commit 6917180972
39 changed files with 2561 additions and 214 deletions

View File

@ -11,7 +11,12 @@
^.hgtip
.DS_Store
\.class$
^\.?mx.jvmci/
^\.mx.jvmci/env
^\.mx.jvmci/.*\.pyc
^\.mx.jvmci/eclipse-launches/.*
^\.mx.jvmci/hotspot/eclipse/.*
^\.idea/
^workingsets.xml
^src/jdk.vm.ci/share/classes/\w[\w\.]*/.*\.xml
^src/jdk.vm.ci/share/classes/\w[\w\.]*/.*\.iml
^src/jdk.vm.ci/share/classes/\w[\w\.]*/nbproject

View File

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>mx.jvmci</name>
<comment></comment>
<projects>
<project>mx</project>
</projects>
<buildSpec>
<buildCommand>
<name>org.python.pydev.PyDevBuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.python.pydev.pythonNature</nature>
</natures>
</projectDescription>

View File

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?eclipse-pydev version="1.0"?>
<pydev_project>
<pydev_property name="org.python.pydev.PYTHON_PROJECT_INTERPRETER">Default</pydev_property>
<pydev_property name="org.python.pydev.PYTHON_PROJECT_VERSION">python 2.7</pydev_property>
<pydev_pathproperty name="org.python.pydev.PROJECT_SOURCE_PATH">
<path>/mx.jvmci</path>
</pydev_pathproperty>
<pydev_pathproperty name="org.python.pydev.PROJECT_SOURCE_PATH">
<path>/mx</path>
</pydev_pathproperty>
</pydev_project>

View File

@ -0,0 +1 @@
org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsNotVisibleRef=disabled

View File

@ -0,0 +1,145 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?fileVersion 4.0.0?><cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage">
<storageModule moduleId="org.eclipse.cdt.core.settings">
<cconfiguration id="cdt.managedbuild.toolchain.gnu.solaris.base.945602881">
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="cdt.managedbuild.toolchain.gnu.solaris.base.945602881" moduleId="org.eclipse.cdt.core.settings" name="Default">
<externalSettings/>
<extensions>
<extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/>
<extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
</extensions>
</storageModule>
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
<configuration artifactName="hotspot" buildProperties="" description="" id="cdt.managedbuild.toolchain.gnu.solaris.base.945602881" name="Default" parent="org.eclipse.cdt.build.core.emptycfg">
<folderInfo id="cdt.managedbuild.toolchain.gnu.solaris.base.945602881.305678577" name="/" resourcePath="">
<toolChain id="cdt.managedbuild.toolchain.gnu.base.1866612258" name="Linux GCC" superClass="cdt.managedbuild.toolchain.gnu.base">
<targetPlatform archList="all" binaryParser="org.eclipse.cdt.core.ELF" id="cdt.managedbuild.target.gnu.platform.base.2075405295" name="Debug Platform" osList="linux,hpux,aix,qnx" superClass="cdt.managedbuild.target.gnu.platform.base"/>
<builder autoBuildTarget="" buildPath="${workspace_loc:/hotspot}/.." cleanBuildTarget="clean" enableAutoBuild="true" enableCleanBuild="false" enabledIncrementalBuild="false" id="cdt.managedbuild.target.gnu.builder.base.81453037" incrementalBuildTarget="jvmg1" keepEnvironmentInBuildfile="false" managedBuildOn="false" name="Gnu Make Builder" superClass="cdt.managedbuild.target.gnu.builder.base">
<outputEntries>
<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="outputPath" name=""/>
</outputEntries>
</builder>
<tool id="cdt.managedbuild.tool.gnu.archiver.base.1094883386" name="GCC Archiver" superClass="cdt.managedbuild.tool.gnu.archiver.base"/>
<tool id="cdt.managedbuild.tool.gnu.cpp.compiler.base.1342888057" name="GCC C++ Compiler" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.base">
<option id="gnu.cpp.compiler.option.preprocessor.def.634868600" name="Defined symbols (-D)" superClass="gnu.cpp.compiler.option.preprocessor.def" valueType="definedSymbols">
<listOptionValue builtIn="false" value="_LP64=1"/>
<listOptionValue builtIn="false" value="COMPILER1=1"/>
<listOptionValue builtIn="false" value="VM_LITTLE_ENDIAN=1"/>
<listOptionValue builtIn="false" value="ASSERT=1"/>
<listOptionValue builtIn="false" value="_REENTRANT=1"/>
<listOptionValue builtIn="false" value="DEBUG=1"/>
<listOptionValue builtIn="false" value="AMD64=1"/>
<listOptionValue builtIn="false" value="LINUX=1"/>
<listOptionValue builtIn="false" value="TARGET_ARCH_x86=1"/>
<listOptionValue builtIn="false" value="TARGET_COMPILER_gcc=1"/>
<listOptionValue builtIn="false" value="TARGET_OS_FAMILY_linux=1"/>
<listOptionValue builtIn="false" value="TARGET_OS_ARCH_linux_x86=1"/>
<listOptionValue builtIn="false" value="TARGET_ARCH_MODEL_x86_64=1"/>
<listOptionValue builtIn="false" value="INCLUDE_JVMCI=1"/>
<listOptionValue builtIn="false" value="COMPILER2=1"/>
</option>
<option id="gnu.cpp.compiler.option.preprocessor.undef.2137486146" name="Undefined symbols (-U)" superClass="gnu.cpp.compiler.option.preprocessor.undef"/>
<inputType id="cdt.managedbuild.tool.gnu.cpp.compiler.input.866181452" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.input"/>
</tool>
<tool id="cdt.managedbuild.tool.gnu.c.compiler.base.1535888880" name="GCC C Compiler" superClass="cdt.managedbuild.tool.gnu.c.compiler.base">
<option id="gnu.c.compiler.option.preprocessor.def.symbols.825962493" name="Defined symbols (-D)" superClass="gnu.c.compiler.option.preprocessor.def.symbols" valueType="definedSymbols">
<listOptionValue builtIn="false" value="_LP64=1"/>
<listOptionValue builtIn="false" value="COMPILER1=1"/>
<listOptionValue builtIn="false" value="VM_LITTLE_ENDIAN=1"/>
<listOptionValue builtIn="false" value="ASSERT=1"/>
<listOptionValue builtIn="false" value="_REENTRANT=1"/>
<listOptionValue builtIn="false" value="DEBUG=1"/>
<listOptionValue builtIn="false" value="AMD64=1"/>
</option>
<inputType id="cdt.managedbuild.tool.gnu.c.compiler.input.906671119" superClass="cdt.managedbuild.tool.gnu.c.compiler.input"/>
</tool>
<tool id="cdt.managedbuild.tool.gnu.c.linker.base.1271041307" name="GCC C Linker" superClass="cdt.managedbuild.tool.gnu.c.linker.base"/>
<tool id="cdt.managedbuild.tool.gnu.cpp.linker.base.550499946" name="GCC C++ Linker" superClass="cdt.managedbuild.tool.gnu.cpp.linker.base">
<inputType id="cdt.managedbuild.tool.gnu.cpp.linker.input.274517766" superClass="cdt.managedbuild.tool.gnu.cpp.linker.input">
<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
<additionalInput kind="additionalinput" paths="$(LIBS)"/>
</inputType>
</tool>
<tool id="cdt.managedbuild.tool.gnu.assembler.base.554053529" name="GCC Assembler" superClass="cdt.managedbuild.tool.gnu.assembler.base">
<inputType id="cdt.managedbuild.tool.gnu.assembler.input.1055083385" superClass="cdt.managedbuild.tool.gnu.assembler.input"/>
</tool>
</toolChain>
</folderInfo>
<sourceEntries>
<entry excluding="cpu/vm/templateTable_x86_32.cpp|cpu/vm/templateInterpreter_x86_32.cpp|cpu/vm/stubRoutines_x86_32.cpp|cpu/vm/stubGenerator_x86_32.cpp|cpu/vm/sharedRuntime_x86_32.cpp|cpu/vm/jniFastGetField_x86_32.cpp|cpu/vm/interpreterRT_x86_32.cpp|cpu/vm/interpreter_x86_32.cpp|cpu/vm/interp_masm_x86_32.cpp|cpu/vm/vtableStubs_x86_32.cpp" flags="VALUE_WORKSPACE_PATH" kind="sourcePath" name=""/>
</sourceEntries>
</configuration>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
<storageModule moduleId="org.eclipse.cdt.internal.ui.text.commentOwnerProjectMappings"/>
<storageModule moduleId="org.eclipse.cdt.core.language.mapping"/>
<storageModule moduleId="org.eclipse.cdt.make.core.buildtargets"/>
</cconfiguration>
</storageModule>
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
<project id="hotspot.null.1712822257" name="hotspot"/>
</storageModule>
<storageModule moduleId="refreshScope" versionNumber="2">
<configuration configurationName="Default">
<resource resourceType="PROJECT" workspacePath="/hotspot"/>
</configuration>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.internal.ui.text.commentOwnerProjectMappings"/>
<storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
<storageModule moduleId="scannerConfiguration">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
<scannerConfigBuildInfo instanceId="cdt.managedbuild.toolchain.gnu.solaris.base.945602881.982312162;cdt.managedbuild.toolchain.gnu.solaris.base.945602881.982312162.;cdt.managedbuild.tool.gnu.c.compiler.base.1862778408;cdt.managedbuild.tool.gnu.c.compiler.input.29080811">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
</scannerConfigBuildInfo>
<scannerConfigBuildInfo instanceId="cdt.managedbuild.toolchain.gnu.solaris.base.945602881.2116626004;cdt.managedbuild.toolchain.gnu.solaris.base.945602881.2116626004.;cdt.managedbuild.tool.gnu.cpp.compiler.base.501581878;cdt.managedbuild.tool.gnu.cpp.compiler.input.1552002453">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
</scannerConfigBuildInfo>
<scannerConfigBuildInfo instanceId="cdt.managedbuild.toolchain.gnu.solaris.base.945602881;cdt.managedbuild.toolchain.gnu.solaris.base.945602881.388217325;cdt.managedbuild.tool.gnu.solaris.cpp.compiler.base.377383651;cdt.managedbuild.tool.gnu.cpp.compiler.input.103897085">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileCPP"/>
</scannerConfigBuildInfo>
<scannerConfigBuildInfo instanceId="cdt.managedbuild.toolchain.gnu.solaris.base.945602881;cdt.managedbuild.toolchain.gnu.solaris.base.945602881.305678577;cdt.managedbuild.tool.gnu.solaris.c.compiler.base.351149667;cdt.managedbuild.tool.gnu.c.compiler.input.820447325">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC"/>
</scannerConfigBuildInfo>
<scannerConfigBuildInfo instanceId="cdt.managedbuild.toolchain.gnu.solaris.base.945602881;cdt.managedbuild.toolchain.gnu.solaris.base.945602881.388217325;cdt.managedbuild.tool.gnu.solaris.c.compiler.base.212558466;cdt.managedbuild.tool.gnu.c.compiler.input.1115218695">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC"/>
</scannerConfigBuildInfo>
<scannerConfigBuildInfo instanceId="cdt.managedbuild.toolchain.gnu.solaris.base.945602881;cdt.managedbuild.toolchain.gnu.solaris.base.945602881.305678577;cdt.managedbuild.tool.gnu.c.compiler.base.1535888880;cdt.managedbuild.tool.gnu.c.compiler.input.906671119">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC"/>
</scannerConfigBuildInfo>
<scannerConfigBuildInfo instanceId="cdt.managedbuild.toolchain.gnu.solaris.base.945602881.500153051;cdt.managedbuild.toolchain.gnu.solaris.base.945602881.500153051.;cdt.managedbuild.tool.gnu.c.compiler.base.592469102;cdt.managedbuild.tool.gnu.c.compiler.input.1891927256">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
</scannerConfigBuildInfo>
<scannerConfigBuildInfo instanceId="cdt.managedbuild.toolchain.gnu.solaris.base.945602881;cdt.managedbuild.toolchain.gnu.solaris.base.945602881.305678577;cdt.managedbuild.tool.gnu.solaris.cpp.compiler.base.429326045;cdt.managedbuild.tool.gnu.cpp.compiler.input.1860785837">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileCPP"/>
</scannerConfigBuildInfo>
<scannerConfigBuildInfo instanceId="cdt.managedbuild.toolchain.gnu.solaris.base.945602881.2116626004;cdt.managedbuild.toolchain.gnu.solaris.base.945602881.2116626004.;cdt.managedbuild.tool.gnu.c.compiler.base.647707969;cdt.managedbuild.tool.gnu.c.compiler.input.1613323394">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
</scannerConfigBuildInfo>
<scannerConfigBuildInfo instanceId="cdt.managedbuild.toolchain.gnu.solaris.base.945602881.1958236162;cdt.managedbuild.toolchain.gnu.solaris.base.945602881.1958236162.;cdt.managedbuild.tool.gnu.c.compiler.base.1536145259;cdt.managedbuild.tool.gnu.c.compiler.input.1935913022">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
</scannerConfigBuildInfo>
<scannerConfigBuildInfo instanceId="cdt.managedbuild.toolchain.gnu.solaris.base.945602881;cdt.managedbuild.toolchain.gnu.solaris.base.945602881.305678577;cdt.managedbuild.tool.gnu.cpp.compiler.base.1342888057;cdt.managedbuild.tool.gnu.cpp.compiler.input.866181452">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileCPP"/>
</scannerConfigBuildInfo>
<scannerConfigBuildInfo instanceId="cdt.managedbuild.toolchain.gnu.solaris.base.945602881.915924225;cdt.managedbuild.toolchain.gnu.solaris.base.945602881.915924225.;cdt.managedbuild.tool.gnu.cpp.compiler.base.1404788740;cdt.managedbuild.tool.gnu.cpp.compiler.input.1175382997">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
</scannerConfigBuildInfo>
<scannerConfigBuildInfo instanceId="cdt.managedbuild.toolchain.gnu.solaris.base.945602881.1958236162;cdt.managedbuild.toolchain.gnu.solaris.base.945602881.1958236162.;cdt.managedbuild.tool.gnu.cpp.compiler.base.677873708;cdt.managedbuild.tool.gnu.cpp.compiler.input.429177901">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
</scannerConfigBuildInfo>
<scannerConfigBuildInfo instanceId="cdt.managedbuild.toolchain.gnu.solaris.base.945602881.500153051;cdt.managedbuild.toolchain.gnu.solaris.base.945602881.500153051.;cdt.managedbuild.tool.gnu.cpp.compiler.base.1920567990;cdt.managedbuild.tool.gnu.cpp.compiler.input.1463421641">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
</scannerConfigBuildInfo>
<scannerConfigBuildInfo instanceId="cdt.managedbuild.toolchain.gnu.solaris.base.945602881.915924225;cdt.managedbuild.toolchain.gnu.solaris.base.945602881.915924225.;cdt.managedbuild.tool.gnu.c.compiler.base.961579870;cdt.managedbuild.tool.gnu.c.compiler.input.1710196852">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
</scannerConfigBuildInfo>
<scannerConfigBuildInfo instanceId="cdt.managedbuild.toolchain.gnu.solaris.base.945602881.982312162;cdt.managedbuild.toolchain.gnu.solaris.base.945602881.982312162.;cdt.managedbuild.tool.gnu.cpp.compiler.base.1673917487;cdt.managedbuild.tool.gnu.cpp.compiler.input.931461388">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
</scannerConfigBuildInfo>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.pathentry"/>
</cproject>

View File

@ -0,0 +1,198 @@
eclipse.preferences.version=1
environment/project/cdt.managedbuild.toolchain.gnu.solaris.base.945602881.1958236162/BUILDING_FROM_IDE/delimiter=\:
environment/project/cdt.managedbuild.toolchain.gnu.solaris.base.945602881.1958236162/BUILDING_FROM_IDE/operation=append
environment/project/cdt.managedbuild.toolchain.gnu.solaris.base.945602881.1958236162/BUILDING_FROM_IDE/value=true
environment/project/cdt.managedbuild.toolchain.gnu.solaris.base.945602881.1958236162/append=true
environment/project/cdt.managedbuild.toolchain.gnu.solaris.base.945602881.1958236162/appendContributed=true
environment/project/cdt.managedbuild.toolchain.gnu.solaris.base.945602881.2116626004.562670952/BUILDING_FROM_IDE/delimiter=\:
environment/project/cdt.managedbuild.toolchain.gnu.solaris.base.945602881.2116626004.562670952/BUILDING_FROM_IDE/operation=append
environment/project/cdt.managedbuild.toolchain.gnu.solaris.base.945602881.2116626004.562670952/BUILDING_FROM_IDE/value=true
environment/project/cdt.managedbuild.toolchain.gnu.solaris.base.945602881.2116626004.562670952/append=true
environment/project/cdt.managedbuild.toolchain.gnu.solaris.base.945602881.2116626004.562670952/appendContributed=true
environment/project/cdt.managedbuild.toolchain.gnu.solaris.base.945602881.2116626004/BUILDING_FROM_IDE/delimiter=\:
environment/project/cdt.managedbuild.toolchain.gnu.solaris.base.945602881.2116626004/BUILDING_FROM_IDE/operation=append
environment/project/cdt.managedbuild.toolchain.gnu.solaris.base.945602881.2116626004/BUILDING_FROM_IDE/value=true
environment/project/cdt.managedbuild.toolchain.gnu.solaris.base.945602881.2116626004/append=true
environment/project/cdt.managedbuild.toolchain.gnu.solaris.base.945602881.2116626004/appendContributed=true
environment/project/cdt.managedbuild.toolchain.gnu.solaris.base.945602881.500153051/BUILDING_FROM_IDE/delimiter=\:
environment/project/cdt.managedbuild.toolchain.gnu.solaris.base.945602881.500153051/BUILDING_FROM_IDE/operation=append
environment/project/cdt.managedbuild.toolchain.gnu.solaris.base.945602881.500153051/BUILDING_FROM_IDE/value=true
environment/project/cdt.managedbuild.toolchain.gnu.solaris.base.945602881.500153051/append=true
environment/project/cdt.managedbuild.toolchain.gnu.solaris.base.945602881.500153051/appendContributed=true
environment/project/cdt.managedbuild.toolchain.gnu.solaris.base.945602881.915924225/BUILDING_FROM_IDE/delimiter=\:
environment/project/cdt.managedbuild.toolchain.gnu.solaris.base.945602881.915924225/BUILDING_FROM_IDE/operation=append
environment/project/cdt.managedbuild.toolchain.gnu.solaris.base.945602881.915924225/BUILDING_FROM_IDE/value=true
environment/project/cdt.managedbuild.toolchain.gnu.solaris.base.945602881.915924225/append=true
environment/project/cdt.managedbuild.toolchain.gnu.solaris.base.945602881.915924225/appendContributed=true
environment/project/cdt.managedbuild.toolchain.gnu.solaris.base.945602881.982312162/BUILDING_FROM_IDE/delimiter=\:
environment/project/cdt.managedbuild.toolchain.gnu.solaris.base.945602881.982312162/BUILDING_FROM_IDE/operation=append
environment/project/cdt.managedbuild.toolchain.gnu.solaris.base.945602881.982312162/BUILDING_FROM_IDE/value=true
environment/project/cdt.managedbuild.toolchain.gnu.solaris.base.945602881.982312162/append=true
environment/project/cdt.managedbuild.toolchain.gnu.solaris.base.945602881.982312162/appendContributed=true
environment/project/cdt.managedbuild.toolchain.gnu.solaris.base.945602881/BUILDING_FROM_IDE/delimiter=\:
environment/project/cdt.managedbuild.toolchain.gnu.solaris.base.945602881/BUILDING_FROM_IDE/operation=append
environment/project/cdt.managedbuild.toolchain.gnu.solaris.base.945602881/BUILDING_FROM_IDE/value=true
environment/project/cdt.managedbuild.toolchain.gnu.solaris.base.945602881/append=true
environment/project/cdt.managedbuild.toolchain.gnu.solaris.base.945602881/appendContributed=true
org.eclipse.cdt.core.formatter.alignment_for_arguments_in_method_invocation=16
org.eclipse.cdt.core.formatter.alignment_for_assignment=16
org.eclipse.cdt.core.formatter.alignment_for_base_clause_in_type_declaration=80
org.eclipse.cdt.core.formatter.alignment_for_binary_expression=16
org.eclipse.cdt.core.formatter.alignment_for_compact_if=0
org.eclipse.cdt.core.formatter.alignment_for_conditional_expression=80
org.eclipse.cdt.core.formatter.alignment_for_conditional_expression_chain=18
org.eclipse.cdt.core.formatter.alignment_for_constructor_initializer_list=0
org.eclipse.cdt.core.formatter.alignment_for_declarator_list=16
org.eclipse.cdt.core.formatter.alignment_for_enumerator_list=48
org.eclipse.cdt.core.formatter.alignment_for_expression_list=0
org.eclipse.cdt.core.formatter.alignment_for_expressions_in_array_initializer=16
org.eclipse.cdt.core.formatter.alignment_for_member_access=0
org.eclipse.cdt.core.formatter.alignment_for_overloaded_left_shift_chain=16
org.eclipse.cdt.core.formatter.alignment_for_parameters_in_method_declaration=16
org.eclipse.cdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16
org.eclipse.cdt.core.formatter.brace_position_for_array_initializer=end_of_line
org.eclipse.cdt.core.formatter.brace_position_for_block=end_of_line
org.eclipse.cdt.core.formatter.brace_position_for_block_in_case=end_of_line
org.eclipse.cdt.core.formatter.brace_position_for_method_declaration=end_of_line
org.eclipse.cdt.core.formatter.brace_position_for_namespace_declaration=end_of_line
org.eclipse.cdt.core.formatter.brace_position_for_switch=end_of_line
org.eclipse.cdt.core.formatter.brace_position_for_type_declaration=end_of_line
org.eclipse.cdt.core.formatter.comment.min_distance_between_code_and_line_comment=1
org.eclipse.cdt.core.formatter.comment.never_indent_line_comments_on_first_column=true
org.eclipse.cdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments=false
org.eclipse.cdt.core.formatter.compact_else_if=true
org.eclipse.cdt.core.formatter.continuation_indentation=2
org.eclipse.cdt.core.formatter.continuation_indentation_for_array_initializer=2
org.eclipse.cdt.core.formatter.format_guardian_clause_on_one_line=false
org.eclipse.cdt.core.formatter.indent_access_specifier_compare_to_type_header=false
org.eclipse.cdt.core.formatter.indent_access_specifier_extra_spaces=0
org.eclipse.cdt.core.formatter.indent_body_declarations_compare_to_access_specifier=true
org.eclipse.cdt.core.formatter.indent_body_declarations_compare_to_namespace_header=false
org.eclipse.cdt.core.formatter.indent_breaks_compare_to_cases=true
org.eclipse.cdt.core.formatter.indent_declaration_compare_to_template_header=false
org.eclipse.cdt.core.formatter.indent_empty_lines=false
org.eclipse.cdt.core.formatter.indent_statements_compare_to_block=true
org.eclipse.cdt.core.formatter.indent_statements_compare_to_body=true
org.eclipse.cdt.core.formatter.indent_switchstatements_compare_to_cases=true
org.eclipse.cdt.core.formatter.indent_switchstatements_compare_to_switch=true
org.eclipse.cdt.core.formatter.indentation.size=2
org.eclipse.cdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert
org.eclipse.cdt.core.formatter.insert_new_line_after_template_declaration=do not insert
org.eclipse.cdt.core.formatter.insert_new_line_at_end_of_file_if_missing=do not insert
org.eclipse.cdt.core.formatter.insert_new_line_before_catch_in_try_statement=do not insert
org.eclipse.cdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert
org.eclipse.cdt.core.formatter.insert_new_line_before_colon_in_constructor_initializer_list=do not insert
org.eclipse.cdt.core.formatter.insert_new_line_before_else_in_if_statement=do not insert
org.eclipse.cdt.core.formatter.insert_new_line_before_identifier_in_function_declaration=do not insert
org.eclipse.cdt.core.formatter.insert_new_line_before_while_in_do_statement=do not insert
org.eclipse.cdt.core.formatter.insert_new_line_in_empty_block=insert
org.eclipse.cdt.core.formatter.insert_space_after_assignment_operator=insert
org.eclipse.cdt.core.formatter.insert_space_after_binary_operator=insert
org.eclipse.cdt.core.formatter.insert_space_after_closing_angle_bracket_in_template_arguments=insert
org.eclipse.cdt.core.formatter.insert_space_after_closing_angle_bracket_in_template_parameters=insert
org.eclipse.cdt.core.formatter.insert_space_after_closing_brace_in_block=insert
org.eclipse.cdt.core.formatter.insert_space_after_closing_paren_in_cast=insert
org.eclipse.cdt.core.formatter.insert_space_after_colon_in_base_clause=insert
org.eclipse.cdt.core.formatter.insert_space_after_colon_in_case=insert
org.eclipse.cdt.core.formatter.insert_space_after_colon_in_conditional=insert
org.eclipse.cdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert
org.eclipse.cdt.core.formatter.insert_space_after_comma_in_array_initializer=insert
org.eclipse.cdt.core.formatter.insert_space_after_comma_in_base_types=insert
org.eclipse.cdt.core.formatter.insert_space_after_comma_in_declarator_list=insert
org.eclipse.cdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert
org.eclipse.cdt.core.formatter.insert_space_after_comma_in_expression_list=insert
org.eclipse.cdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert
org.eclipse.cdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert
org.eclipse.cdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert
org.eclipse.cdt.core.formatter.insert_space_after_comma_in_template_arguments=insert
org.eclipse.cdt.core.formatter.insert_space_after_comma_in_template_parameters=insert
org.eclipse.cdt.core.formatter.insert_space_after_opening_angle_bracket_in_template_arguments=do not insert
org.eclipse.cdt.core.formatter.insert_space_after_opening_angle_bracket_in_template_parameters=do not insert
org.eclipse.cdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=insert
org.eclipse.cdt.core.formatter.insert_space_after_opening_bracket=do not insert
org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert
org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert
org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_exception_specification=do not insert
org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert
org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert
org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert
org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert
org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert
org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert
org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert
org.eclipse.cdt.core.formatter.insert_space_after_postfix_operator=do not insert
org.eclipse.cdt.core.formatter.insert_space_after_prefix_operator=do not insert
org.eclipse.cdt.core.formatter.insert_space_after_question_in_conditional=insert
org.eclipse.cdt.core.formatter.insert_space_after_semicolon_in_for=insert
org.eclipse.cdt.core.formatter.insert_space_after_unary_operator=do not insert
org.eclipse.cdt.core.formatter.insert_space_before_assignment_operator=insert
org.eclipse.cdt.core.formatter.insert_space_before_binary_operator=insert
org.eclipse.cdt.core.formatter.insert_space_before_closing_angle_bracket_in_template_arguments=do not insert
org.eclipse.cdt.core.formatter.insert_space_before_closing_angle_bracket_in_template_parameters=do not insert
org.eclipse.cdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert
org.eclipse.cdt.core.formatter.insert_space_before_closing_bracket=do not insert
org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert
org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert
org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_exception_specification=do not insert
org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert
org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert
org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert
org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert
org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert
org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert
org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert
org.eclipse.cdt.core.formatter.insert_space_before_colon_in_base_clause=do not insert
org.eclipse.cdt.core.formatter.insert_space_before_colon_in_case=do not insert
org.eclipse.cdt.core.formatter.insert_space_before_colon_in_conditional=insert
org.eclipse.cdt.core.formatter.insert_space_before_colon_in_default=do not insert
org.eclipse.cdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert
org.eclipse.cdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert
org.eclipse.cdt.core.formatter.insert_space_before_comma_in_base_types=do not insert
org.eclipse.cdt.core.formatter.insert_space_before_comma_in_declarator_list=do not insert
org.eclipse.cdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert
org.eclipse.cdt.core.formatter.insert_space_before_comma_in_expression_list=do not insert
org.eclipse.cdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert
org.eclipse.cdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert
org.eclipse.cdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert
org.eclipse.cdt.core.formatter.insert_space_before_comma_in_template_arguments=do not insert
org.eclipse.cdt.core.formatter.insert_space_before_comma_in_template_parameters=do not insert
org.eclipse.cdt.core.formatter.insert_space_before_opening_angle_bracket_in_template_arguments=do not insert
org.eclipse.cdt.core.formatter.insert_space_before_opening_angle_bracket_in_template_parameters=do not insert
org.eclipse.cdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert
org.eclipse.cdt.core.formatter.insert_space_before_opening_brace_in_block=insert
org.eclipse.cdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert
org.eclipse.cdt.core.formatter.insert_space_before_opening_brace_in_namespace_declaration=insert
org.eclipse.cdt.core.formatter.insert_space_before_opening_brace_in_switch=insert
org.eclipse.cdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert
org.eclipse.cdt.core.formatter.insert_space_before_opening_bracket=do not insert
org.eclipse.cdt.core.formatter.insert_space_before_opening_paren_in_catch=insert
org.eclipse.cdt.core.formatter.insert_space_before_opening_paren_in_exception_specification=insert
org.eclipse.cdt.core.formatter.insert_space_before_opening_paren_in_for=insert
org.eclipse.cdt.core.formatter.insert_space_before_opening_paren_in_if=insert
org.eclipse.cdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert
org.eclipse.cdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert
org.eclipse.cdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert
org.eclipse.cdt.core.formatter.insert_space_before_opening_paren_in_switch=insert
org.eclipse.cdt.core.formatter.insert_space_before_opening_paren_in_while=insert
org.eclipse.cdt.core.formatter.insert_space_before_postfix_operator=do not insert
org.eclipse.cdt.core.formatter.insert_space_before_prefix_operator=do not insert
org.eclipse.cdt.core.formatter.insert_space_before_question_in_conditional=insert
org.eclipse.cdt.core.formatter.insert_space_before_semicolon=do not insert
org.eclipse.cdt.core.formatter.insert_space_before_semicolon_in_for=do not insert
org.eclipse.cdt.core.formatter.insert_space_before_unary_operator=do not insert
org.eclipse.cdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert
org.eclipse.cdt.core.formatter.insert_space_between_empty_brackets=do not insert
org.eclipse.cdt.core.formatter.insert_space_between_empty_parens_in_exception_specification=do not insert
org.eclipse.cdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert
org.eclipse.cdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert
org.eclipse.cdt.core.formatter.join_wrapped_lines=true
org.eclipse.cdt.core.formatter.keep_else_statement_on_same_line=false
org.eclipse.cdt.core.formatter.keep_empty_array_initializer_on_one_line=false
org.eclipse.cdt.core.formatter.keep_imple_if_on_one_line=true
org.eclipse.cdt.core.formatter.keep_then_statement_on_same_line=false
org.eclipse.cdt.core.formatter.lineSplit=160
org.eclipse.cdt.core.formatter.number_of_empty_lines_to_preserve=1
org.eclipse.cdt.core.formatter.put_empty_statement_on_new_line=true
org.eclipse.cdt.core.formatter.tabulation.char=space
org.eclipse.cdt.core.formatter.tabulation.size=2
org.eclipse.cdt.core.formatter.use_tabs_only_for_leading_indentations=false

View File

@ -0,0 +1,5 @@
#Wed Sep 01 16:21:02 PDT 2010
eclipse.preferences.version=1
formatter_profile=_hotspotStyle
formatter_settings_version=1

View File

@ -0,0 +1,6 @@
#Wed Sep 01 16:13:40 PDT 2010
content-types/enabled=true
content-types/org.eclipse.cdt.core.cxxHeader/file-extensions=hpp,incl
content-types/org.eclipse.cdt.core.cxxSource/file-extensions=cpp
eclipse.preferences.version=1

View File

@ -0,0 +1,890 @@
#
# ----------------------------------------------------------------------------------------------------
#
# Copyright (c) 2007, 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.
#
# ----------------------------------------------------------------------------------------------------
import os, shutil, zipfile, re, time, sys, datetime, platform
from os.path import join, exists, dirname, isdir
from argparse import ArgumentParser, REMAINDER
import StringIO
import xml.dom.minidom
import subprocess
import mx
import mx_gate
import mx_unittest
from mx_gate import Task
from mx_unittest import unittest
_suite = mx.suite('jvmci')
"""
Top level directory of the JDK source workspace.
"""
_jdkSourceRoot = dirname(_suite.dir)
_JVMCI_JDK_TAG = 'jvmci'
_minVersion = mx.VersionSpec('1.9')
# max version (first _unsupported_ version)
_untilVersion = None
_jvmciModes = {
'hosted' : ['-XX:+UnlockExperimentalVMOptions', '-XX:+EnableJVMCI'],
'jit' : ['-XX:+UnlockExperimentalVMOptions', '-XX:+EnableJVMCI', '-XX:+UseJVMCICompiler'],
'disabled' : []
}
# TODO: can optimized be built without overriding release build?
_jdkDebugLevels = ['release', 'fastdebug', 'slowdebug']
# TODO: add client once/if it can be built on 64-bit platforms
_jdkJvmVariants = ['server']
"""
Translation table from mx_jvmci:8 --vmbuild values to mx_jvmci:9 --jdk-debug-level values.
"""
_legacyVmbuilds = {
'product' : 'release',
'debug' : 'slowdebug'
}
"""
Translates a mx_jvmci:8 --vmbuild value to a mx_jvmci:9 --jdk-debug-level value.
"""
def _translateLegacyDebugLevel(debugLevel):
return _legacyVmbuilds.get(debugLevel, debugLevel)
"""
Translation table from mx_jvmci:8 --vm values to mx_jvmci:9 (--jdk-jvm-variant, --jvmci-mode) tuples.
"""
_legacyVms = {
'jvmci' : ('server', 'jit')
}
"""
A VM configuration composed of a JDK debug level, JVM variant and a JVMCI mode.
This is also a context manager that can be used with the 'with' statement to set/change
a VM configuration within a dynamic scope. For example:
with ConfiguredJDK(debugLevel='fastdebug'):
dacapo(['pmd'])
"""
class VM:
def __init__(self, jvmVariant=None, debugLevel=None, jvmciMode=None):
self.update(jvmVariant, debugLevel, jvmciMode)
def update(self, jvmVariant=None, debugLevel=None, jvmciMode=None):
if jvmVariant in _legacyVms:
# Backwards compatibility for mx_jvmci:8 API
jvmVariant, newJvmciMode = _legacyVms[jvmVariant]
if jvmciMode is not None and jvmciMode != newJvmciMode:
mx.abort('JVM variant "' + jvmVariant + '" implies JVMCI mode "' + newJvmciMode +
'" which conflicts with explicitly specified JVMCI mode of "' + jvmciMode + '"')
jvmciMode = newJvmciMode
debugLevel = _translateLegacyDebugLevel(debugLevel)
assert jvmVariant is None or jvmVariant in _jdkJvmVariants, jvmVariant
assert debugLevel is None or debugLevel in _jdkDebugLevels, debugLevel
assert jvmciMode is None or jvmciMode in _jvmciModes, jvmciMode
self.jvmVariant = jvmVariant or _vm.jvmVariant
self.debugLevel = debugLevel or _vm.debugLevel
self.jvmciMode = jvmciMode or _vm.jvmciMode
def __enter__(self):
global _vm
self.previousVm = _vm
_vm = self
def __exit__(self, exc_type, exc_value, traceback):
global _vm
_vm = self.previousVm
_vm = VM(jvmVariant=_jdkJvmVariants[0], debugLevel=_jdkDebugLevels[0], jvmciMode='hosted')
def get_vm():
"""
Gets the configured VM.
"""
return _vm
def relativeVmLibDirInJdk():
mxos = mx.get_os()
if mxos == 'darwin':
return join('lib')
if mxos == 'windows' or mxos == 'cygwin':
return join('bin')
return join('lib', mx.get_arch())
def isJVMCIEnabled(vm):
assert vm in _jdkJvmVariants
return True
class JvmciJDKDeployedDist(object):
def __init__(self, name, compilers=False):
self._name = name
self._compilers = compilers
def dist(self):
return mx.distribution(self._name)
def deploy(self, jdkDir):
mx.nyi('deploy', self)
class ExtJDKDeployedDist(JvmciJDKDeployedDist):
def __init__(self, name):
JvmciJDKDeployedDist.__init__(self, name)
"""
The monolithic JVMCI distribution is deployed through use of -Xbootclasspath/p
so that it's not necessary to run JDK make after editing JVMCI sources.
The latter causes all JDK Java sources to be rebuilt since JVMCI is
(currently) in java.base.
"""
_monolithicJvmci = JvmciJDKDeployedDist('JVMCI')
"""
List of distributions that are deployed on the boot class path.
Note: In jvmci-8, they were deployed directly into the JDK directory.
"""
jdkDeployedDists = [_monolithicJvmci]
def _makehelp():
return subprocess.check_output([mx.gmake_cmd(), 'help'], cwd=_jdkSourceRoot)
def _runmake(args):
"""run the JDK make process
To build hotspot and import it into the JDK: "mx make hotspot import-hotspot"
{0}"""
jdkBuildDir = _get_jdk_build_dir()
if not exists(jdkBuildDir):
# JDK9 must be bootstrapped with a JDK8
compliance = mx.JavaCompliance('8')
jdk8 = mx.get_jdk(compliance.exactMatch, versionDescription=compliance.value)
cmd = ['sh', 'configure', '--with-debug-level=' + _vm.debugLevel, '--disable-debug-symbols', '--disable-precompiled-headers',
'--with-jvm-variants=' + _vm.jvmVariant, '--disable-warnings-as-errors', '--with-boot-jdk=' + jdk8.home]
mx.run(cmd, cwd=_jdkSourceRoot)
cmd = [mx.gmake_cmd(), 'CONF=' + _vm.debugLevel]
if mx.get_opts().verbose:
cmd.append('LOG=debug')
cmd.extend(args)
if mx.get_opts().use_jdk_image and 'images' not in args:
cmd.append('images')
if not mx.get_opts().verbose:
mx.log('--------------- make execution ----------------------')
mx.log('Working directory: ' + _jdkSourceRoot)
mx.log('Command line: ' + ' '.join(cmd))
mx.log('-----------------------------------------------------')
mx.run(cmd, cwd=_jdkSourceRoot)
if 'images' in cmd:
_create_jdk_bundle(jdkBuildDir)
def _get_jdk_bundle_arches():
"""
Gets a list of names that will be the part of a JDK bundle's file name denoting the architecture.
The first element in the list is the canonical name. Symlinks should be created for the
remaining names.
"""
cpu = mx.get_arch()
if cpu == 'amd64':
return ['x64', 'x86_64', 'amd64']
elif cpu == 'sparcv9':
return ['sparcv9']
mx.abort('Unsupported JDK bundle arch: ' + cpu)
def _create_jdk_bundle(jdkBuildDir):
"""
Creates a tar.gz JDK archive, an accompanying tar.gz.sha1 file with its
SHA1 signature plus symlinks to the archive for non-canonical architecture names.
"""
jdkImageDir = join(jdkBuildDir, 'images', 'jdk')
arches = _get_jdk_bundle_arches()
jdkTgzPath = join(_suite.get_output_root(), 'jdk-bundles', 'jdk9-{}-{}.tar.gz'.format(_get_openjdk_os(), arches[0]))
with mx.Archiver(jdkTgzPath, kind='tgz') as arc:
mx.log('Creating ' + jdkTgzPath)
for root, _, filenames in os.walk(jdkImageDir):
for name in filenames:
f = join(root, name)
arcname = 'jdk1.9.0/' + os.path.relpath(f, jdkImageDir)
arc.zf.add(name=f, arcname=arcname, recursive=False)
# The OpenJDK build creates an empty cacerts file so grab one from
# the default JDK which is assumed to be an OracleJDK
cacerts = join(mx.get_jdk(tag='default').home, 'jre', 'lib', 'security', 'cacerts')
arc.zf.add(name=cacerts, arcname='jdk1.9.0/lib/security/cacerts')
with open(jdkTgzPath + '.sha1', 'w') as fp:
mx.log('Creating ' + jdkTgzPath + '.sha1')
fp.write(mx.sha1OfFile(jdkTgzPath))
def _create_link(source, link_name):
if exists(link_name):
os.remove(link_name)
mx.log('Creating ' + link_name + ' -> ' + source)
os.symlink(source, link_name)
for arch in arches[1:]:
link_name = join(_suite.get_output_root(), 'jdk-bundles', 'jdk9-{}-{}.tar.gz'.format(_get_openjdk_os(), arch))
jdkTgzName = os.path.basename(jdkTgzPath)
_create_link(jdkTgzName, link_name)
_create_link(jdkTgzName + '.sha1', link_name + '.sha1')
def _runmultimake(args):
"""run the JDK make process for one or more configurations"""
jvmVariantsDefault = ','.join(_jdkJvmVariants)
debugLevelsDefault = ','.join(_jdkDebugLevels)
parser = ArgumentParser(prog='mx multimake')
parser.add_argument('--jdk-jvm-variants', '--vms', help='a comma separated list of VMs to build (default: ' + jvmVariantsDefault + ')', metavar='<args>', default=jvmVariantsDefault)
parser.add_argument('--jdk-debug-levels', '--builds', help='a comma separated list of JDK debug levels (default: ' + debugLevelsDefault + ')', metavar='<args>', default=debugLevelsDefault)
parser.add_argument('-n', '--no-check', action='store_true', help='omit running "java -version" after each build')
select = parser.add_mutually_exclusive_group()
select.add_argument('-c', '--console', action='store_true', help='send build output to console instead of log files')
select.add_argument('-d', '--output-dir', help='directory for log files instead of current working directory', default=os.getcwd(), metavar='<dir>')
args = parser.parse_args(args)
jvmVariants = args.jdk_jvm_variants.split(',')
debugLevels = [_translateLegacyDebugLevel(dl) for dl in args.jdk_debug_levels.split(',')]
allStart = time.time()
for jvmVariant in jvmVariants:
for debugLevel in debugLevels:
if not args.console:
logFile = join(mx.ensure_dir_exists(args.output_dir), jvmVariant + '-' + debugLevel + '.log')
log = open(logFile, 'wb')
start = time.time()
mx.log('BEGIN: ' + jvmVariant + '-' + debugLevel + '\t(see: ' + logFile + ')')
verbose = ['-v'] if mx.get_opts().verbose else []
# Run as subprocess so that output can be directed to a file
cmd = [sys.executable, '-u', mx.__file__] + verbose + ['--jdk-jvm-variant=' + jvmVariant, '--jdk-debug-level=' + debugLevel, 'make']
mx.logv("executing command: " + str(cmd))
subprocess.check_call(cmd, cwd=_suite.dir, stdout=log, stderr=subprocess.STDOUT)
duration = datetime.timedelta(seconds=time.time() - start)
mx.log('END: ' + jvmVariant + '-' + debugLevel + '\t[' + str(duration) + ']')
else:
with VM(jvmVariant=jvmVariant, debugLevel=debugLevel):
_runmake([])
if not args.no_check:
with VM(jvmciMode='jit'):
run_vm(['-XX:-BootstrapJVMCI', '-version'])
allDuration = datetime.timedelta(seconds=time.time() - allStart)
mx.log('TOTAL TIME: ' + '[' + str(allDuration) + ']')
class HotSpotProject(mx.NativeProject):
"""
Defines a NativeProject representing the HotSpot binaries built via make.
"""
def __init__(self, suite, name, deps, workingSets, **args):
assert name == 'hotspot'
mx.NativeProject.__init__(self, suite, name, "", [], deps, workingSets, None, None, join(suite.mxDir, name))
def eclipse_config_up_to_date(self, configZip):
# Assume that any change to this module might imply changes to the generated IDE files
if configZip.isOlderThan(__file__):
return False
for _, source in self._get_eclipse_settings_sources().iteritems():
if configZip.isOlderThan(source):
return False
return True
def _get_eclipse_settings_sources(self):
"""
Gets a dictionary from the name of an Eclipse settings file to
the file providing its generated content.
"""
if not hasattr(self, '_eclipse_settings'):
esdict = {}
templateSettingsDir = join(self.dir, 'templates', 'eclipse', 'settings')
if exists(templateSettingsDir):
for name in os.listdir(templateSettingsDir):
source = join(templateSettingsDir, name)
esdict[name] = source
self._eclipse_settings = esdict
return self._eclipse_settings
def _eclipseinit(self, files=None, libFiles=None):
"""
Generates an Eclipse project for each HotSpot build configuration.
"""
roots = [
'ASSEMBLY_EXCEPTION',
'LICENSE',
'README',
'THIRD_PARTY_README',
'agent',
'make',
'src',
'test'
]
for jvmVariant in _jdkJvmVariants:
for debugLevel in _jdkDebugLevels:
name = jvmVariant + '-' + debugLevel
eclProjectDir = join(self.dir, 'eclipse', name)
mx.ensure_dir_exists(eclProjectDir)
out = mx.XMLDoc()
out.open('projectDescription')
out.element('name', data='hotspot:' + name)
out.element('comment', data='')
out.element('projects', data='')
out.open('buildSpec')
out.open('buildCommand')
out.element('name', data='org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder')
out.element('triggers', data='full,incremental')
out.element('arguments', data='')
out.close('buildCommand')
out.close('buildSpec')
out.open('natures')
out.element('nature', data='org.eclipse.cdt.core.cnature')
out.element('nature', data='org.eclipse.cdt.core.ccnature')
out.element('nature', data='org.eclipse.cdt.managedbuilder.core.managedBuildNature')
out.element('nature', data='org.eclipse.cdt.managedbuilder.core.ScannerConfigNature')
out.close('natures')
if roots:
out.open('linkedResources')
for r in roots:
f = join(_suite.dir, r)
out.open('link')
out.element('name', data=r)
out.element('type', data='2' if isdir(f) else '1')
out.element('locationURI', data=mx.get_eclipse_project_rel_locationURI(f, eclProjectDir))
out.close('link')
out.open('link')
out.element('name', data='generated')
out.element('type', data='2')
generated = join(_get_hotspot_build_dir(jvmVariant, debugLevel), 'generated')
out.element('locationURI', data=mx.get_eclipse_project_rel_locationURI(generated, eclProjectDir))
out.close('link')
out.close('linkedResources')
out.close('projectDescription')
projectFile = join(eclProjectDir, '.project')
mx.update_file(projectFile, out.xml(indent='\t', newl='\n'))
if files:
files.append(projectFile)
cprojectTemplate = join(self.dir, 'templates', 'eclipse', 'cproject')
cprojectFile = join(eclProjectDir, '.cproject')
with open(cprojectTemplate) as f:
content = f.read()
mx.update_file(cprojectFile, content)
if files:
files.append(cprojectFile)
settingsDir = join(eclProjectDir, ".settings")
mx.ensure_dir_exists(settingsDir)
for name, source in self._get_eclipse_settings_sources().iteritems():
out = StringIO.StringIO()
print >> out, '# GENERATED -- DO NOT EDIT'
print >> out, '# Source:', source
with open(source) as f:
print >> out, f.read()
content = out.getvalue()
mx.update_file(join(settingsDir, name), content)
if files:
files.append(join(settingsDir, name))
def getBuildTask(self, args):
return JDKBuildTask(self, args, _vm.debugLevel, _vm.jvmVariant)
class JDKBuildTask(mx.NativeBuildTask):
def __init__(self, project, args, debugLevel, jvmVariant):
mx.NativeBuildTask.__init__(self, args, project)
self.jvmVariant = jvmVariant
self.debugLevel = debugLevel
def __str__(self):
return 'Building JDK[{}, {}]'.format(self.debugLevel, self.jvmVariant)
def build(self):
if mx.get_opts().use_jdk_image:
_runmake(['images'])
else:
_runmake([])
self._newestOutput = None
def clean(self, forBuild=False):
if forBuild: # Let make handle incremental builds
return
if exists(_get_jdk_build_dir(self.debugLevel)):
_runmake(['clean'])
self._newestOutput = None
# Backwards compatibility for mx_jvmci:8 API
def buildvms(args):
_runmultimake(args)
def run_vm(args, vm=None, nonZeroIsFatal=True, out=None, err=None, cwd=None, timeout=None, debugLevel=None, vmbuild=None):
"""run a Java program by executing the java executable in a JVMCI JDK"""
jdkTag = mx.get_jdk_option().tag
if jdkTag and jdkTag != _JVMCI_JDK_TAG:
mx.abort('The "--jdk" option must have the tag "' + _JVMCI_JDK_TAG + '" when running a command requiring a JVMCI VM')
jdk = get_jvmci_jdk(debugLevel=debugLevel or _translateLegacyDebugLevel(vmbuild))
return jdk.run_java(args, nonZeroIsFatal=nonZeroIsFatal, out=out, err=err, cwd=cwd, timeout=timeout)
def _unittest_vm_launcher(vmArgs, mainClass, mainClassArgs):
run_vm(vmArgs + [mainClass] + mainClassArgs)
mx_unittest.set_vm_launcher('JVMCI VM launcher', _unittest_vm_launcher)
def _jvmci_gate_runner(args, tasks):
# Build release server VM now so we can run the unit tests
with Task('BuildHotSpotJVMCIHosted: release', tasks) as t:
if t: _runmultimake(['--jdk-jvm-variants', 'server', '--jdk-debug-levels', 'release'])
# Run unit tests in hosted mode
with VM(jvmVariant='server', debugLevel='release', jvmciMode='hosted'):
with Task('JVMCI UnitTests: hosted-release', tasks) as t:
if t: unittest(['--suite', 'jvmci', '--enable-timing', '--verbose', '--fail-fast'])
# Build the other VM flavors
with Task('BuildHotSpotJVMCIOthers: fastdebug', tasks) as t:
if t: _runmultimake(['--jdk-jvm-variants', 'server', '--jdk-debug-levels', 'fastdebug'])
with Task('CleanAndBuildIdealGraphVisualizer', tasks, disableJacoco=True) as t:
if t and platform.processor() != 'sparc':
buildxml = mx._cygpathU2W(join(_suite.dir, 'src', 'share', 'tools', 'IdealGraphVisualizer', 'build.xml'))
mx.run(['ant', '-f', buildxml, '-q', 'clean', 'build'], env=_igvBuildEnv())
mx_gate.add_gate_runner(_suite, _jvmci_gate_runner)
mx_gate.add_gate_argument('-g', '--only-build-jvmci', action='store_false', dest='buildNonJVMCI', help='only build the JVMCI VM')
def _igvJdk():
v8u20 = mx.VersionSpec("1.8.0_20")
v8u40 = mx.VersionSpec("1.8.0_40")
v8 = mx.VersionSpec("1.8")
def _igvJdkVersionCheck(version):
return version >= v8 and (version < v8u20 or version >= v8u40)
return mx.get_jdk(_igvJdkVersionCheck, versionDescription='>= 1.8 and < 1.8.0u20 or >= 1.8.0u40', purpose="building & running IGV").home
def _igvBuildEnv():
# When the http_proxy environment variable is set, convert it to the proxy settings that ant needs
env = dict(os.environ)
proxy = os.environ.get('http_proxy')
if not (proxy is None) and len(proxy) > 0:
if '://' in proxy:
# Remove the http:// prefix (or any other protocol prefix)
proxy = proxy.split('://', 1)[1]
# Separate proxy server name and port number
proxyName, proxyPort = proxy.split(':', 1)
proxyEnv = '-DproxyHost="' + proxyName + '" -DproxyPort=' + proxyPort
env['ANT_OPTS'] = proxyEnv
env['JAVA_HOME'] = _igvJdk()
return env
def igv(args):
"""run the Ideal Graph Visualizer"""
logFile = '.ideal_graph_visualizer.log'
with open(join(_suite.dir, logFile), 'w') as fp:
mx.logv('[Ideal Graph Visualizer log is in ' + fp.name + ']')
nbplatform = join(_suite.dir, 'src', 'share', 'tools', 'IdealGraphVisualizer', 'nbplatform')
# Remove NetBeans platform if it is earlier than the current supported version
if exists(nbplatform):
updateTrackingFile = join(nbplatform, 'platform', 'update_tracking', 'org-netbeans-core.xml')
if not exists(updateTrackingFile):
mx.log('Could not find \'' + updateTrackingFile + '\', removing NetBeans platform')
shutil.rmtree(nbplatform)
else:
dom = xml.dom.minidom.parse(updateTrackingFile)
currentVersion = mx.VersionSpec(dom.getElementsByTagName('module_version')[0].getAttribute('specification_version'))
supportedVersion = mx.VersionSpec('3.43.1')
if currentVersion < supportedVersion:
mx.log('Replacing NetBeans platform version ' + str(currentVersion) + ' with version ' + str(supportedVersion))
shutil.rmtree(nbplatform)
elif supportedVersion < currentVersion:
mx.log('Supported NetBeans version in igv command should be updated to ' + str(currentVersion))
if not exists(nbplatform):
mx.logv('[This execution may take a while as the NetBeans platform needs to be downloaded]')
env = _igvBuildEnv()
# make the jar for Batik 1.7 available.
env['IGV_BATIK_JAR'] = mx.library('BATIK').get_path(True)
if mx.run(['ant', '-f', mx._cygpathU2W(join(_suite.dir, 'src', 'share', 'tools', 'IdealGraphVisualizer', 'build.xml')), '-l', mx._cygpathU2W(fp.name), 'run'], env=env, nonZeroIsFatal=False):
mx.abort("IGV ant build & launch failed. Check '" + logFile + "'. You can also try to delete 'src/share/tools/IdealGraphVisualizer/nbplatform'.")
def c1visualizer(args):
"""run the Cl Compiler Visualizer"""
libpath = join(_suite.dir, 'lib')
if mx.get_os() == 'windows':
executable = join(libpath, 'c1visualizer', 'bin', 'c1visualizer.exe')
else:
executable = join(libpath, 'c1visualizer', 'bin', 'c1visualizer')
# Check whether the current C1Visualizer installation is the up-to-date
if exists(executable) and not exists(mx.library('C1VISUALIZER_DIST').get_path(resolve=False)):
mx.log('Updating C1Visualizer')
shutil.rmtree(join(libpath, 'c1visualizer'))
archive = mx.library('C1VISUALIZER_DIST').get_path(resolve=True)
if not exists(executable):
zf = zipfile.ZipFile(archive, 'r')
zf.extractall(libpath)
if not exists(executable):
mx.abort('C1Visualizer binary does not exist: ' + executable)
if mx.get_os() != 'windows':
# Make sure that execution is allowed. The zip file does not always specfiy that correctly
os.chmod(executable, 0777)
mx.run([executable])
def hsdis(args, copyToDir=None):
"""download the hsdis library
This is needed to support HotSpot's assembly dumping features.
By default it downloads the Intel syntax version, use the 'att' argument to install AT&T syntax."""
flavor = 'intel'
if 'att' in args:
flavor = 'att'
if mx.get_arch() == "sparcv9":
flavor = "sparcv9"
lib = mx.add_lib_suffix('hsdis-' + mx.get_arch())
path = join(_suite.dir, 'lib', lib)
sha1s = {
'att/hsdis-amd64.dll' : 'bcbd535a9568b5075ab41e96205e26a2bac64f72',
'att/hsdis-amd64.so' : '58919ba085d4ef7a513f25bae75e7e54ee73c049',
'intel/hsdis-amd64.dll' : '6a388372cdd5fe905c1a26ced614334e405d1f30',
'intel/hsdis-amd64.so' : '844ed9ffed64fe9599638f29a8450c50140e3192',
'intel/hsdis-amd64.dylib' : 'fdb13ef0d7d23d93dacaae9c98837bea0d4fc5a2',
'sparcv9/hsdis-sparcv9.so': '970640a9af0bd63641f9063c11275b371a59ee60',
}
flavoredLib = flavor + "/" + lib
if flavoredLib not in sha1s:
mx.logv("hsdis not supported on this plattform or architecture")
return
if not exists(path):
sha1 = sha1s[flavoredLib]
sha1path = path + '.sha1'
mx.download_file_with_sha1('hsdis', path, ['https://lafo.ssw.uni-linz.ac.at/pub/hsdis/' + flavoredLib], sha1, sha1path, True, True, sources=False)
if copyToDir is not None and exists(copyToDir):
shutil.copy(path, copyToDir)
def hcfdis(args):
"""disassemble HexCodeFiles embedded in text files
Run a tool over the input files to convert all embedded HexCodeFiles
to a disassembled format."""
parser = ArgumentParser(prog='mx hcfdis')
parser.add_argument('-m', '--map', help='address to symbol map applied to disassembler output')
parser.add_argument('files', nargs=REMAINDER, metavar='files...')
args = parser.parse_args(args)
path = mx.library('HCFDIS').get_path(resolve=True)
mx.run_java(['-cp', path, 'com.oracle.max.hcfdis.HexCodeFileDis'] + args.files)
if args.map is not None:
addressRE = re.compile(r'0[xX]([A-Fa-f0-9]+)')
with open(args.map) as fp:
lines = fp.read().splitlines()
symbols = dict()
for l in lines:
addressAndSymbol = l.split(' ', 1)
if len(addressAndSymbol) == 2:
address, symbol = addressAndSymbol
if address.startswith('0x'):
address = long(address, 16)
symbols[address] = symbol
for f in args.files:
with open(f) as fp:
lines = fp.read().splitlines()
updated = False
for i in range(0, len(lines)):
l = lines[i]
for m in addressRE.finditer(l):
sval = m.group(0)
val = long(sval, 16)
sym = symbols.get(val)
if sym:
l = l.replace(sval, sym)
updated = True
lines[i] = l
if updated:
mx.log('updating ' + f)
with open('new_' + f, "w") as fp:
for l in lines:
print >> fp, l
def jol(args):
"""Java Object Layout"""
joljar = mx.library('JOL_INTERNALS').get_path(resolve=True)
candidates = mx.findclass(args, logToConsole=False, matcher=lambda s, classname: s == classname or classname.endswith('.' + s) or classname.endswith('$' + s))
if len(candidates) > 0:
candidates = mx.select_items(sorted(candidates))
else:
# mx.findclass can be mistaken, don't give up yet
candidates = args
run_vm(['-javaagent:' + joljar, '-cp', os.pathsep.join([mx.classpath(), joljar]), "org.openjdk.jol.MainObjectInternals"] + candidates)
class JVMCIArchiveParticipant:
def __init__(self, dist):
self.dist = dist
def __opened__(self, arc, srcArc, services):
self.services = services
self.arc = arc
def __add__(self, arcname, contents):
if arcname.startswith('META-INF/jvmci.providers/'):
provider = arcname[len('META-INF/jvmci.providers/'):]
for service in contents.strip().split(os.linesep):
assert service
self.services.setdefault(service, []).append(provider)
return True
elif arcname.endswith('_OptionDescriptors.class'):
# Need to create service files for the providers of the
# jdk.vm.ci.options.Options service created by
# jdk.vm.ci.options.processor.OptionProcessor.
provider = arcname[:-len('.class'):].replace('/', '.')
self.services.setdefault('jdk.vm.ci.options.OptionDescriptors', []).append(provider)
return False
def __addsrc__(self, arcname, contents):
return False
def __closing__(self):
pass
def _get_openjdk_os():
# See: common/autoconf/platform.m4
os = mx.get_os()
if 'darwin' in os:
os = 'macosx'
elif 'linux' in os:
os = 'linux'
elif 'solaris' in os:
os = 'solaris'
elif 'cygwin' in os or 'mingw' in os:
os = 'windows'
return os
def _get_openjdk_cpu():
cpu = mx.get_arch()
if cpu == 'amd64':
cpu = 'x86_64'
elif cpu == 'sparcv9':
cpu = 'sparcv9'
return cpu
def _get_openjdk_os_cpu():
return _get_openjdk_os() + '-' + _get_openjdk_cpu()
def _get_jdk_build_dir(debugLevel=None):
"""
Gets the directory into which the JDK is built. This directory contains
the exploded JDK under jdk/ and the JDK image under images/jdk/.
"""
if debugLevel is None:
debugLevel = _vm.debugLevel
name = '{}-{}-{}-{}'.format(_get_openjdk_os_cpu(), 'normal', _vm.jvmVariant, debugLevel)
return join(dirname(_suite.dir), 'build', name)
_jvmci_bootclasspath_prepends = []
def _get_hotspot_build_dir(jvmVariant=None, debugLevel=None):
"""
Gets the directory in which a particular HotSpot configuration is built
(e.g., <JDK_REPO_ROOT>/build/macosx-x86_64-normal-server-release/hotspot/bsd_amd64_compiler2)
"""
if jvmVariant is None:
jvmVariant = _vm.jvmVariant
os = mx.get_os()
if os == 'darwin':
os = 'bsd'
arch = mx.get_arch()
buildname = {'client': 'compiler1', 'server': 'compiler2'}.get(jvmVariant, jvmVariant)
name = '{}_{}_{}'.format(os, arch, buildname)
return join(_get_jdk_build_dir(debugLevel=debugLevel), 'hotspot', name)
def add_bootclasspath_prepend(dep):
assert isinstance(dep, mx.ClasspathDependency)
_jvmci_bootclasspath_prepends.append(dep)
class JVMCI9JDKConfig(mx.JDKConfig):
def __init__(self, debugLevel):
self.debugLevel = debugLevel
jdkBuildDir = _get_jdk_build_dir(debugLevel)
jdkDir = join(jdkBuildDir, 'images', 'jdk') if mx.get_opts().use_jdk_image else join(jdkBuildDir, 'jdk')
mx.JDKConfig.__init__(self, jdkDir, tag=_JVMCI_JDK_TAG)
def parseVmArgs(self, args, addDefaultArgs=True):
args = mx.expand_project_in_args(args, insitu=False)
jacocoArgs = mx_gate.get_jacoco_agent_args()
if jacocoArgs:
args = jacocoArgs + args
# Support for -G: options
def translateGOption(arg):
if arg.startswith('-G:+'):
if '=' in arg:
mx.abort('Mixing + and = in -G: option specification: ' + arg)
arg = '-Djvmci.option.' + arg[len('-G:+'):] + '=true'
elif arg.startswith('-G:-'):
if '=' in arg:
mx.abort('Mixing - and = in -G: option specification: ' + arg)
arg = '-Djvmci.option.' + arg[len('-G:+'):] + '=false'
elif arg.startswith('-G:'):
arg = '-Djvmci.option.' + arg[len('-G:'):]
return arg
args = map(translateGOption, args)
args = ['-Xbootclasspath/p:' + dep.classpath_repr() for dep in _jvmci_bootclasspath_prepends] + args
jvmciModeArgs = _jvmciModes[_vm.jvmciMode]
if jvmciModeArgs:
bcpDeps = [jdkDist.dist() for jdkDist in jdkDeployedDists]
if bcpDeps:
args = ['-Xbootclasspath/p:' + os.pathsep.join([d.classpath_repr() for d in bcpDeps])] + args
# Set the default JVMCI compiler
for jdkDist in reversed(jdkDeployedDists):
assert isinstance(jdkDist, JvmciJDKDeployedDist), jdkDist
if jdkDist._compilers:
jvmciCompiler = jdkDist._compilers[-1]
args = ['-Djvmci.compiler=' + jvmciCompiler] + args
break
if '-version' in args:
ignoredArgs = args[args.index('-version') + 1:]
if len(ignoredArgs) > 0:
mx.log("Warning: The following options will be ignored by the vm because they come after the '-version' argument: " + ' '.join(ignoredArgs))
return self.processArgs(args, addDefaultArgs=addDefaultArgs)
# Overrides JDKConfig
def run_java(self, args, vm=None, nonZeroIsFatal=True, out=None, err=None, cwd=None, timeout=None, env=None, addDefaultArgs=True):
if vm is None:
vm = 'server'
args = self.parseVmArgs(args, addDefaultArgs=addDefaultArgs)
jvmciModeArgs = _jvmciModes[_vm.jvmciMode]
cmd = [self.java] + ['-' + vm] + jvmciModeArgs + args
return mx.run(cmd, nonZeroIsFatal=nonZeroIsFatal, out=out, err=err, cwd=cwd)
"""
The dict of JVMCI JDKs indexed by debug-level names.
"""
_jvmci_jdks = {}
def get_jvmci_jdk(debugLevel=None):
"""
Gets the JVMCI JDK corresponding to 'debugLevel'.
"""
if not debugLevel:
debugLevel = _vm.debugLevel
jdk = _jvmci_jdks.get(debugLevel)
if jdk is None:
try:
jdk = JVMCI9JDKConfig(debugLevel)
except mx.JDKConfigException as e:
jdkBuildDir = _get_jdk_build_dir(debugLevel)
msg = 'Error with the JDK built into {}:\n{}\nTry (re)building it with: mx --jdk-debug-level={} make'
if mx.get_opts().use_jdk_image:
msg += ' images'
mx.abort(msg.format(jdkBuildDir, e.message, debugLevel))
_jvmci_jdks[debugLevel] = jdk
return jdk
class JVMCIJDKFactory(mx.JDKFactory):
def getJDKConfig(self):
jdk = get_jvmci_jdk(_vm.debugLevel)
return jdk
def description(self):
return "JVMCI JDK"
mx.update_commands(_suite, {
'make': [_runmake, '[args...]', _makehelp],
'multimake': [_runmultimake, '[options]'],
'c1visualizer' : [c1visualizer, ''],
'hsdis': [hsdis, '[att]'],
'hcfdis': [hcfdis, ''],
'igv' : [igv, ''],
'jol' : [jol, ''],
'vm': [run_vm, '[-options] class [args...]'],
})
mx.add_argument('-M', '--jvmci-mode', action='store', choices=sorted(_jvmciModes.viewkeys()), help='the JVM variant type to build/run (default: ' + _vm.jvmciMode + ')')
mx.add_argument('--jdk-jvm-variant', '--vm', action='store', choices=_jdkJvmVariants + sorted(_legacyVms.viewkeys()), help='the JVM variant type to build/run (default: ' + _vm.jvmVariant + ')')
mx.add_argument('--jdk-debug-level', '--vmbuild', action='store', choices=_jdkDebugLevels + sorted(_legacyVmbuilds.viewkeys()), help='the JDK debug level to build/run (default: ' + _vm.debugLevel + ')')
mx.add_argument('-I', '--use-jdk-image', action='store_true', help='build/run JDK image instead of exploded JDK')
def mx_post_parse_cmd_line(opts):
mx.addJDKFactory(_JVMCI_JDK_TAG, mx.JavaCompliance('9'), JVMCIJDKFactory())
mx.set_java_command_default_jdk_tag(_JVMCI_JDK_TAG)
jdkTag = mx.get_jdk_option().tag
jvmVariant = None
debugLevel = None
jvmciMode = None
if opts.jdk_jvm_variant is not None:
jvmVariant = opts.jdk_jvm_variant
if jdkTag and jdkTag != _JVMCI_JDK_TAG:
mx.warn('Ignoring "--jdk-jvm-variant" option as "--jdk" tag is not "' + _JVMCI_JDK_TAG + '"')
if opts.jdk_debug_level is not None:
debugLevel = _translateLegacyDebugLevel(opts.jdk_debug_level)
if jdkTag and jdkTag != _JVMCI_JDK_TAG:
mx.warn('Ignoring "--jdk-debug-level" option as "--jdk" tag is not "' + _JVMCI_JDK_TAG + '"')
if opts.jvmci_mode is not None:
jvmciMode = opts.jvmci_mode
if jdkTag and jdkTag != _JVMCI_JDK_TAG:
mx.warn('Ignoring "--jvmci-mode" option as "--jdk" tag is not "' + _JVMCI_JDK_TAG + '"')
_vm.update(jvmVariant, debugLevel, jvmciMode)
for jdkDist in jdkDeployedDists:
dist = jdkDist.dist()
if isinstance(jdkDist, JvmciJDKDeployedDist):
dist.set_archiveparticipant(JVMCIArchiveParticipant(dist))

358
hotspot/.mx.jvmci/suite.py Normal file
View File

@ -0,0 +1,358 @@
suite = {
"mxversion" : "5.5.12",
"name" : "jvmci",
"url" : "http://openjdk.java.net/projects/graal",
"developer" : {
"name" : "Truffle and Graal developers",
"email" : "graal-dev@openjdk.java.net",
"organization" : "Graal",
"organizationUrl" : "http://openjdk.java.net/projects/graal",
},
"repositories" : {
"lafo-snapshots" : {
"url" : "https://curio.ssw.jku.at/nexus/content/repositories/snapshots",
"licenses" : ["GPLv2-CPE", "UPL"]
},
},
"licenses" : {
"UPL" : {
"name" : "Universal Permissive License, Version 1.0",
"url" : "http://opensource.org/licenses/UPL",
}
},
"defaultLicense" : "GPLv2-CPE",
# This puts mx/ as a sibiling of the JDK build configuration directories
# (e.g., macosx-x86_64-normal-server-release).
"outputRoot" : "../build/mx/hotspot",
# ------------- Libraries -------------
"libraries" : {
# ------------- Libraries -------------
"HCFDIS" : {
"urls" : ["https://lafo.ssw.uni-linz.ac.at/pub/hcfdis-3.jar"],
"sha1" : "a71247c6ddb90aad4abf7c77e501acc60674ef57",
},
"C1VISUALIZER_DIST" : {
"urls" : ["https://java.net/downloads/c1visualizer/c1visualizer_2015-07-22.zip"],
"sha1" : "7ead6b2f7ed4643ef4d3343a5562e3d3f39564ac",
},
"JOL_INTERNALS" : {
"urls" : ["https://lafo.ssw.uni-linz.ac.at/pub/truffle/jol/jol-internals.jar"],
"sha1" : "508bcd26a4d7c4c44048990c6ea789a3b11a62dc",
},
"BATIK" : {
"sha1" : "122b87ca88e41a415cf8b523fd3d03b4325134a3",
"urls" : ["https://lafo.ssw.uni-linz.ac.at/pub/graal-external-deps/batik-all-1.7.jar"],
},
},
"projects" : {
# ------------- JVMCI:Service -------------
"jdk.vm.ci.service" : {
"subDir" : "src/jdk.vm.ci/share/classes",
"sourceDirs" : ["src"],
"javaCompliance" : "1.8",
"workingSets" : "API,JVMCI",
},
"jdk.vm.ci.service.processor" : {
"subDir" : "src/jdk.vm.ci/share/classes",
"sourceDirs" : ["src"],
"dependencies" : ["jdk.vm.ci.service"],
"checkstyle" : "jdk.vm.ci.service",
"javaCompliance" : "1.8",
"workingSets" : "JVMCI,Codegen,HotSpot",
},
# ------------- JVMCI:API -------------
"jdk.vm.ci.common" : {
"subDir" : "src/jdk.vm.ci/share/classes",
"sourceDirs" : ["src"],
"checkstyle" : "jdk.vm.ci.service",
"javaCompliance" : "1.8",
"workingSets" : "API,JVMCI",
},
"jdk.vm.ci.meta" : {
"subDir" : "src/jdk.vm.ci/share/classes",
"sourceDirs" : ["src"],
"checkstyle" : "jdk.vm.ci.service",
"javaCompliance" : "1.8",
"workingSets" : "API,JVMCI",
},
"jdk.vm.ci.code" : {
"subDir" : "src/jdk.vm.ci/share/classes",
"sourceDirs" : ["src"],
"dependencies" : ["jdk.vm.ci.meta"],
"checkstyle" : "jdk.vm.ci.service",
"javaCompliance" : "1.8",
"workingSets" : "API,JVMCI",
},
"jdk.vm.ci.runtime" : {
"subDir" : "src/jdk.vm.ci/share/classes",
"sourceDirs" : ["src"],
"dependencies" : [
"jdk.vm.ci.code",
],
"checkstyle" : "jdk.vm.ci.service",
"annotationProcessors" : ["JVMCI_OPTIONS_PROCESSOR"],
"javaCompliance" : "1.8",
"workingSets" : "API,JVMCI",
},
"jdk.vm.ci.runtime.test" : {
"subDir" : "test/compiler/jvmci",
"sourceDirs" : ["src"],
"dependencies" : [
"mx:JUNIT",
"jdk.vm.ci.common",
"jdk.vm.ci.runtime",
],
"checkstyle" : "jdk.vm.ci.service",
"javaCompliance" : "1.8",
"workingSets" : "API,JVMCI",
},
"jdk.vm.ci.inittimer" : {
"subDir" : "src/jdk.vm.ci/share/classes",
"sourceDirs" : ["src"],
"checkstyle" : "jdk.vm.ci.service",
"javaCompliance" : "1.8",
"workingSets" : "JVMCI",
},
"jdk.vm.ci.options" : {
"subDir" : "src/jdk.vm.ci/share/classes",
"sourceDirs" : ["src"],
"checkstyle" : "jdk.vm.ci.service",
"dependencies" : ["jdk.vm.ci.inittimer"],
"javaCompliance" : "1.8",
"workingSets" : "JVMCI",
},
"jdk.vm.ci.options.processor" : {
"subDir" : "src/jdk.vm.ci/share/classes",
"sourceDirs" : ["src"],
"dependencies" : [
"jdk.vm.ci.options",
],
"checkstyle" : "jdk.vm.ci.service",
"javaCompliance" : "1.8",
"workingSets" : "JVMCI,Codegen",
},
"jdk.vm.ci.options.test" : {
"subDir" : "test/compiler/jvmci",
"sourceDirs" : ["src"],
"dependencies" : [
"jdk.vm.ci.options",
"mx:JUNIT",
],
"checkstyle" : "jdk.vm.ci.service",
"javaCompliance" : "1.8",
"workingSets" : "JVMCI",
},
# ------------- JVMCI:HotSpot -------------
"jdk.vm.ci.amd64" : {
"subDir" : "src/jdk.vm.ci/share/classes",
"sourceDirs" : ["src"],
"dependencies" : ["jdk.vm.ci.code"],
"checkstyle" : "jdk.vm.ci.service",
"javaCompliance" : "1.8",
"workingSets" : "JVMCI,AMD64",
},
"jdk.vm.ci.sparc" : {
"subDir" : "src/jdk.vm.ci/share/classes",
"sourceDirs" : ["src"],
"dependencies" : ["jdk.vm.ci.code"],
"checkstyle" : "jdk.vm.ci.service",
"javaCompliance" : "1.8",
"workingSets" : "JVMCI,SPARC",
},
"jdk.vm.ci.hotspot" : {
"subDir" : "src/jdk.vm.ci/share/classes",
"sourceDirs" : ["src"],
"dependencies" : [
"jdk.vm.ci.options",
"jdk.vm.ci.hotspotvmconfig",
"jdk.vm.ci.common",
"jdk.vm.ci.runtime",
"jdk.vm.ci.service",
],
"annotationProcessors" : [
"JVMCI_OPTIONS_PROCESSOR",
],
"checkstyle" : "jdk.vm.ci.service",
"javaCompliance" : "1.8",
"workingSets" : "JVMCI",
},
"jdk.vm.ci.hotspotvmconfig" : {
"subDir" : "src/jdk.vm.ci/share/classes",
"sourceDirs" : ["src"],
"checkstyle" : "jdk.vm.ci.service",
"javaCompliance" : "1.8",
"workingSets" : "JVMCI,HotSpot",
},
"jdk.vm.ci.hotspot.amd64" : {
"subDir" : "src/jdk.vm.ci/share/classes",
"sourceDirs" : ["src"],
"dependencies" : [
"jdk.vm.ci.amd64",
"jdk.vm.ci.hotspot",
],
"checkstyle" : "jdk.vm.ci.service",
"annotationProcessors" : [
"JVMCI_SERVICE_PROCESSOR",
],
"javaCompliance" : "1.8",
"workingSets" : "JVMCI,HotSpot,AMD64",
},
"jdk.vm.ci.hotspot.sparc" : {
"subDir" : "src/jdk.vm.ci/share/classes",
"sourceDirs" : ["src"],
"dependencies" : [
"jdk.vm.ci.sparc",
"jdk.vm.ci.hotspot",
],
"checkstyle" : "jdk.vm.ci.service",
"annotationProcessors" : [
"JVMCI_SERVICE_PROCESSOR",
],
"javaCompliance" : "1.8",
"workingSets" : "JVMCI,HotSpot,SPARC",
},
"hotspot" : {
"native" : True,
"class" : "HotSpotProject",
}
},
"distributions" : {
# ------------- Distributions -------------
"JVMCI_SERVICE" : {
"subDir" : "src/jdk.vm.ci/share/classes",
"dependencies" : ["jdk.vm.ci.service"],
},
"JVMCI_OPTIONS" : {
"subDir" : "src/jdk.vm.ci/share/classes",
"dependencies" : ["jdk.vm.ci.options"],
},
"JVMCI_API" : {
"subDir" : "src/jdk.vm.ci/share/classes",
"dependencies" : [
"jdk.vm.ci.inittimer",
"jdk.vm.ci.runtime",
"jdk.vm.ci.common",
"jdk.vm.ci.amd64",
"jdk.vm.ci.sparc",
],
"distDependencies" : [
"JVMCI_OPTIONS",
"JVMCI_SERVICE",
],
},
"JVMCI_HOTSPOTVMCONFIG" : {
"subDir" : "src/jdk.vm.ci/share/classes",
"dependencies" : [
"jdk.vm.ci.hotspotvmconfig",
],
},
"JVMCI_HOTSPOT" : {
"subDir" : "src/jdk.vm.ci/share/classes",
"dependencies" : [
"jdk.vm.ci.hotspot.amd64",
"jdk.vm.ci.hotspot.sparc",
],
"distDependencies" : [
"JVMCI_HOTSPOTVMCONFIG",
"JVMCI_SERVICE",
"JVMCI_API",
],
},
"JVMCI_TEST" : {
"subDir" : "test/compiler/jvmci",
"dependencies" : [
"jdk.vm.ci.options.test",
"jdk.vm.ci.runtime.test",
],
"distDependencies" : [
"JVMCI_API",
],
"exclude" : ["mx:JUNIT"],
},
"JVMCI_OPTIONS_PROCESSOR" : {
"subDir" : "src/jdk.vm.ci/share/classes",
"dependencies" : ["jdk.vm.ci.options.processor"],
"distDependencies" : [
"JVMCI_OPTIONS",
],
},
"JVMCI_SERVICE_PROCESSOR" : {
"subDir" : "src/jdk.vm.ci/share/classes",
"dependencies" : ["jdk.vm.ci.service.processor"],
"distDependencies" : [
"JVMCI_SERVICE",
],
},
# 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_OPTIONS",
"JVMCI_SERVICE",
"JVMCI_HOTSPOT",
"JVMCI_HOTSPOTVMCONFIG",
"JVMCI_SERVICE_PROCESSOR",
"JVMCI_OPTIONS_PROCESSOR"
],
"dependencies" : [
"jdk.vm.ci.options",
"jdk.vm.ci.service",
"jdk.vm.ci.inittimer",
"jdk.vm.ci.runtime",
"jdk.vm.ci.common",
"jdk.vm.ci.amd64",
"jdk.vm.ci.sparc",
"jdk.vm.ci.hotspotvmconfig",
"jdk.vm.ci.hotspot.amd64",
"jdk.vm.ci.hotspot.sparc",
"jdk.vm.ci.options.processor",
"jdk.vm.ci.service.processor"
],
},
},
}

View File

@ -129,7 +129,7 @@ esac
# Special handling of arch model.
case "${Platform_arch_model}" in
"x86_32") Src_Files_EXCLUDE="${Src_Files_EXCLUDE} *x86_64*" ;;
"x86_32") Src_Files_EXCLUDE="${Src_Files_EXCLUDE} *x86_64* ${JVMCI_SPECIFIC_FILES}" ;;
"x86_64") Src_Files_EXCLUDE="${Src_Files_EXCLUDE} *x86_32*" ;;
esac

View File

@ -45,10 +45,16 @@ CXX_FLAGS=$(CXX_FLAGS) /D "COMPILER1" /D INCLUDE_JVMCI=0
!if "$(Variant)" == "compiler2"
CXX_FLAGS=$(CXX_FLAGS) /D "COMPILER2"
!if "$(BUILDARCH)" == "i486"
CXX_FLAGS=$(CXX_FLAGS) /D INCLUDE_JVMCI=0
!endif
!endif
!if "$(Variant)" == "tiered"
CXX_FLAGS=$(CXX_FLAGS) /D "COMPILER1" /D "COMPILER2"
!if "$(BUILDARCH)" == "i486"
CXX_FLAGS=$(CXX_FLAGS) /D INCLUDE_JVMCI=0
!endif
!endif
!if "$(BUILDARCH)" == "i486"

View File

@ -4306,7 +4306,6 @@ encode %{
int disp = $mem$$disp;
if (index == -1) {
__ prfm(Address(base, disp), PSTL1KEEP);
__ nop();
} else {
Register index_reg = as_Register(index);
if (disp == 0) {
@ -13844,6 +13843,139 @@ instruct cmpP_narrowOop_imm0_branch(cmpOp cmp, iRegN oop, immP0 zero, label labl
ins_pipe(pipe_cmp_branch);
%}
// Test bit and Branch
instruct cmpL_branch_sign(cmpOp cmp, iRegL op1, immL0 op2, label labl, rFlagsReg cr) %{
match(If cmp (CmpL op1 op2));
predicate(n->in(1)->as_Bool()->_test._test == BoolTest::lt
|| n->in(1)->as_Bool()->_test._test == BoolTest::ge);
effect(USE labl);
ins_cost(BRANCH_COST);
format %{ "cb$cmp $op1, $labl # long" %}
ins_encode %{
Label* L = $labl$$label;
Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode;
if (cond == Assembler::LT)
__ tbnz($op1$$Register, 63, *L);
else
__ tbz($op1$$Register, 63, *L);
%}
ins_pipe(pipe_cmp_branch);
%}
instruct cmpI_branch_sign(cmpOp cmp, iRegIorL2I op1, immI0 op2, label labl, rFlagsReg cr) %{
match(If cmp (CmpI op1 op2));
predicate(n->in(1)->as_Bool()->_test._test == BoolTest::lt
|| n->in(1)->as_Bool()->_test._test == BoolTest::ge);
effect(USE labl);
ins_cost(BRANCH_COST);
format %{ "cb$cmp $op1, $labl # int" %}
ins_encode %{
Label* L = $labl$$label;
Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode;
if (cond == Assembler::LT)
__ tbnz($op1$$Register, 31, *L);
else
__ tbz($op1$$Register, 31, *L);
%}
ins_pipe(pipe_cmp_branch);
%}
instruct cmpL_branch_bit(cmpOp cmp, iRegL op1, immL op2, immL0 op3, label labl, rFlagsReg cr) %{
match(If cmp (CmpL (AndL op1 op2) op3));
predicate((n->in(1)->as_Bool()->_test._test == BoolTest::ne
|| n->in(1)->as_Bool()->_test._test == BoolTest::eq)
&& is_power_of_2(n->in(2)->in(1)->in(2)->get_long()));
effect(USE labl);
ins_cost(BRANCH_COST);
format %{ "tb$cmp $op1, $op2, $labl" %}
ins_encode %{
Label* L = $labl$$label;
Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode;
int bit = exact_log2($op2$$constant);
if (cond == Assembler::EQ)
__ tbz($op1$$Register, bit, *L);
else
__ tbnz($op1$$Register, bit, *L);
%}
ins_pipe(pipe_cmp_branch);
%}
instruct cmpI_branch_bit(cmpOp cmp, iRegIorL2I op1, immI op2, immI0 op3, label labl, rFlagsReg cr) %{
match(If cmp (CmpI (AndI op1 op2) op3));
predicate((n->in(1)->as_Bool()->_test._test == BoolTest::ne
|| n->in(1)->as_Bool()->_test._test == BoolTest::eq)
&& is_power_of_2(n->in(2)->in(1)->in(2)->get_int()));
effect(USE labl);
ins_cost(BRANCH_COST);
format %{ "tb$cmp $op1, $op2, $labl" %}
ins_encode %{
Label* L = $labl$$label;
Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode;
int bit = exact_log2($op2$$constant);
if (cond == Assembler::EQ)
__ tbz($op1$$Register, bit, *L);
else
__ tbnz($op1$$Register, bit, *L);
%}
ins_pipe(pipe_cmp_branch);
%}
// Test bits
instruct cmpL_and(cmpOp cmp, iRegL op1, immL op2, immL0 op3, rFlagsReg cr) %{
match(Set cr (CmpL (AndL op1 op2) op3));
predicate(Assembler::operand_valid_for_logical_immediate
(/*is_32*/false, n->in(1)->in(2)->get_long()));
ins_cost(INSN_COST);
format %{ "tst $op1, $op2 # long" %}
ins_encode %{
__ tst($op1$$Register, $op2$$constant);
%}
ins_pipe(ialu_reg_reg);
%}
instruct cmpI_and(cmpOp cmp, iRegIorL2I op1, immI op2, immI0 op3, rFlagsReg cr) %{
match(Set cr (CmpI (AndI op1 op2) op3));
predicate(Assembler::operand_valid_for_logical_immediate
(/*is_32*/true, n->in(1)->in(2)->get_int()));
ins_cost(INSN_COST);
format %{ "tst $op1, $op2 # int" %}
ins_encode %{
__ tstw($op1$$Register, $op2$$constant);
%}
ins_pipe(ialu_reg_reg);
%}
instruct cmpL_and_reg(cmpOp cmp, iRegL op1, iRegL op2, immL0 op3, rFlagsReg cr) %{
match(Set cr (CmpL (AndL op1 op2) op3));
ins_cost(INSN_COST);
format %{ "tst $op1, $op2 # long" %}
ins_encode %{
__ tst($op1$$Register, $op2$$Register);
%}
ins_pipe(ialu_reg_reg);
%}
instruct cmpI_and_reg(cmpOp cmp, iRegIorL2I op1, iRegIorL2I op2, immI0 op3, rFlagsReg cr) %{
match(Set cr (CmpI (AndI op1 op2) op3));
ins_cost(INSN_COST);
format %{ "tstw $op1, $op2 # int" %}
ins_encode %{
__ tstw($op1$$Register, $op2$$Register);
%}
ins_pipe(ialu_reg_reg);
%}
// Conditional Far Branch
// Conditional Far Branch Unsigned
// TODO: fixme
@ -14167,6 +14299,9 @@ instruct string_compare(iRegP_R1 str1, iRegI_R2 cnt1, iRegP_R3 str2, iRegI_R4 cn
format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result # KILL $tmp1" %}
ins_encode %{
// Count is in 8-bit bytes; non-Compact chars are 16 bits.
__ asrw($cnt1$$Register, $cnt1$$Register, 1);
__ asrw($cnt2$$Register, $cnt2$$Register, 1);
__ string_compare($str1$$Register, $str2$$Register,
$cnt1$$Register, $cnt2$$Register, $result$$Register,
$tmp1$$Register);
@ -14223,6 +14358,8 @@ instruct string_equals(iRegP_R1 str1, iRegP_R3 str2, iRegI_R4 cnt,
format %{ "String Equals $str1,$str2,$cnt -> $result // KILL $tmp" %}
ins_encode %{
// Count is in 8-bit bytes; non-Compact chars are 16 bits.
__ asrw($cnt$$Register, $cnt$$Register, 1);
__ string_equals($str1$$Register, $str2$$Register,
$cnt$$Register, $result$$Register,
$tmp$$Register);

View File

@ -215,8 +215,11 @@ class MacroAssembler: public Assembler {
inline void moviw(Register Rd, unsigned imm) { orrw(Rd, zr, imm); }
inline void movi(Register Rd, unsigned imm) { orr(Rd, zr, imm); }
inline void tstw(Register Rd, unsigned imm) { andsw(zr, Rd, imm); }
inline void tst(Register Rd, unsigned imm) { ands(zr, Rd, imm); }
inline void tstw(Register Rd, Register Rn) { andsw(zr, Rd, Rn); }
inline void tst(Register Rd, Register Rn) { ands(zr, Rd, Rn); }
inline void tstw(Register Rd, uint64_t imm) { andsw(zr, Rd, imm); }
inline void tst(Register Rd, uint64_t imm) { ands(zr, Rd, imm); }
inline void bfiw(Register Rd, Register Rn, unsigned lsb, unsigned width) {
bfmw(Rd, Rn, ((32 - lsb) & 31), (width - 1));

View File

@ -386,7 +386,8 @@ void TemplateTable::ldc(bool wide)
// get type
__ add(r3, r1, tags_offset);
__ ldrb(r3, Address(r0, r3));
__ lea(r3, Address(r0, r3));
__ ldarb(r3, r3);
// unresolved class - get the resolved class
__ cmp(r3, JVM_CONSTANT_UnresolvedClass);
@ -3316,7 +3317,8 @@ void TemplateTable::_new() {
// how Constant Pool is updated (see ConstantPool::klass_at_put)
const int tags_offset = Array<u1>::base_offset_in_bytes();
__ lea(rscratch1, Address(r0, r3, Address::lsl(0)));
__ ldrb(rscratch1, Address(rscratch1, tags_offset));
__ lea(rscratch1, Address(rscratch1, tags_offset));
__ ldarb(rscratch1, rscratch1);
__ cmp(rscratch1, JVM_CONSTANT_Class);
__ br(Assembler::NE, slow_case);
@ -3460,7 +3462,8 @@ void TemplateTable::checkcast()
__ get_unsigned_2_byte_index_at_bcp(r19, 1); // r19=index
// See if bytecode has already been quicked
__ add(rscratch1, r3, Array<u1>::base_offset_in_bytes());
__ ldrb(r1, Address(rscratch1, r19));
__ lea(r1, Address(rscratch1, r19));
__ ldarb(r1, r1);
__ cmp(r1, JVM_CONSTANT_Class);
__ br(Assembler::EQ, quicked);
@ -3514,7 +3517,8 @@ void TemplateTable::instanceof() {
__ get_unsigned_2_byte_index_at_bcp(r19, 1); // r19=index
// See if bytecode has already been quicked
__ add(rscratch1, r3, Array<u1>::base_offset_in_bytes());
__ ldrb(r1, Address(rscratch1, r19));
__ lea(r1, Address(rscratch1, r19));
__ ldarb(r1, r1);
__ cmp(r1, JVM_CONSTANT_Class);
__ br(Assembler::EQ, quicked);

View File

@ -552,6 +552,8 @@ public class CompilationResult {
*/
private final boolean isImmutablePIC;
private boolean closed;
private int entryBCI = -1;
private final DataSection dataSection = new DataSection();
@ -666,6 +668,7 @@ public class CompilationResult {
* @param entryBCI the entryBCI to set
*/
public void setEntryBCI(int entryBCI) {
checkOpen();
this.entryBCI = entryBCI;
}
@ -673,11 +676,14 @@ public class CompilationResult {
* Sets the assumptions made during compilation.
*/
public void setAssumptions(Assumption[] assumptions) {
checkOpen();
this.assumptions = assumptions;
}
/**
* Gets the assumptions made during compilation.
*
* The caller must not modify the contents of the returned array.
*/
public Assumption[] getAssumptions() {
return assumptions;
@ -690,6 +696,7 @@ public class CompilationResult {
* @param inlinedMethods the methods inlined during compilation
*/
public void setMethods(ResolvedJavaMethod rootMethod, Collection<ResolvedJavaMethod> inlinedMethods) {
checkOpen();
assert rootMethod != null;
assert inlinedMethods != null;
if (inlinedMethods.contains(rootMethod)) {
@ -717,6 +724,8 @@ public class CompilationResult {
/**
* Gets the methods whose bytecodes were used as input to the compilation.
*
* The caller must not modify the contents of the returned array.
*
* @return {@code null} if the compilation did not record method dependencies otherwise the
* methods whose bytecodes were used as input to the compilation with the first element
* being the root method of the compilation
@ -726,6 +735,7 @@ public class CompilationResult {
}
public void setBytecodeSize(int bytecodeSize) {
checkOpen();
this.bytecodeSize = bytecodeSize;
}
@ -755,6 +765,7 @@ public class CompilationResult {
* @param size the size of the frame in bytes
*/
public void setTotalFrameSize(int size) {
checkOpen();
totalFrameSize = size;
}
@ -765,6 +776,7 @@ public class CompilationResult {
* @param size the size of the machine code
*/
public void setTargetCode(byte[] code, int size) {
checkOpen();
targetCode = code;
targetCodeSize = size;
}
@ -778,6 +790,7 @@ public class CompilationResult {
* @param ref The reference that should be inserted in the code.
*/
public void recordDataPatch(int codePos, Reference ref) {
checkOpen();
assert codePos >= 0 && ref != null;
dataPatches.add(new DataPatch(codePos, ref));
}
@ -814,6 +827,7 @@ public class CompilationResult {
* @param direct specifies if this is a {@linkplain Call#direct direct} call
*/
public void recordCall(int codePos, int size, InvokeTarget target, DebugInfo debugInfo, boolean direct) {
checkOpen();
final Call call = new Call(target, codePos, size, direct, debugInfo);
addInfopoint(call);
}
@ -825,6 +839,7 @@ public class CompilationResult {
* @param handlerPos the position of the handler
*/
public void recordExceptionHandler(int codePos, int handlerPos) {
checkOpen();
assert validateExceptionHandlerAdd(codePos, handlerPos) : String.format("Duplicate exception handler for pc 0x%x handlerPos 0x%x", codePos, handlerPos);
exceptionHandlers.add(new ExceptionHandler(codePos, handlerPos));
}
@ -870,31 +885,12 @@ public class CompilationResult {
* Records a custom infopoint in the code section.
*
* Compiler implementations can use this method to record non-standard infopoints, which are not
* handled by the dedicated methods like {@link #recordCall}.
* handled by dedicated methods like {@link #recordCall}.
*
* @param infopoint the infopoint to record, usually a derived class from {@link Infopoint}
*/
public void addInfopoint(Infopoint infopoint) {
// The infopoints list must always be sorted
if (!infopoints.isEmpty()) {
Infopoint previousInfopoint = infopoints.get(infopoints.size() - 1);
if (previousInfopoint.pcOffset > infopoint.pcOffset) {
// This re-sorting should be very rare
Collections.sort(infopoints);
previousInfopoint = infopoints.get(infopoints.size() - 1);
}
if (previousInfopoint.pcOffset == infopoint.pcOffset) {
if (infopoint.reason.canBeOmitted()) {
return;
}
if (previousInfopoint.reason.canBeOmitted()) {
Infopoint removed = infopoints.remove(infopoints.size() - 1);
assert removed == previousInfopoint;
} else {
throw new RuntimeException("Infopoints that can not be omited should have distinct PCs");
}
}
}
checkOpen();
infopoints.add(infopoint);
}
@ -905,6 +901,7 @@ public class CompilationResult {
* @param markId the identifier for this mark
*/
public Mark recordMark(int codePos, Object markId) {
checkOpen();
Mark mark = new Mark(codePos, markId);
marks.add(mark);
return mark;
@ -924,6 +921,7 @@ public class CompilationResult {
* @param offset
*/
public void setCustomStackAreaOffset(int offset) {
checkOpen();
customStackAreaOffset = offset;
}
@ -952,6 +950,7 @@ public class CompilationResult {
}
public void addAnnotation(CodeAnnotation annotation) {
checkOpen();
assert annotation != null;
if (annotations == null) {
annotations = new ArrayList<>();
@ -1034,6 +1033,7 @@ public class CompilationResult {
}
public void setHasUnsafeAccess(boolean hasUnsafeAccess) {
checkOpen();
this.hasUnsafeAccess = hasUnsafeAccess;
}
@ -1041,8 +1041,14 @@ public class CompilationResult {
return hasUnsafeAccess;
}
public void reset() {
hasUnsafeAccess = false;
/**
* Clears the information in this object pertaining to generating code. That is, the
* {@linkplain #getMarks() marks}, {@linkplain #getInfopoints() infopoints},
* {@linkplain #getExceptionHandlers() exception handlers}, {@linkplain #getDataPatches() data
* patches} and {@linkplain #getAnnotations() annotations} recorded in this object are cleared.
*/
public void resetForEmittingCode() {
checkOpen();
infopoints.clear();
dataPatches.clear();
exceptionHandlers.clear();
@ -1052,4 +1058,21 @@ public class CompilationResult {
annotations.clear();
}
}
private void checkOpen() {
if (closed) {
throw new IllegalStateException();
}
}
/**
* Closes this compilation result to future updates.
*/
public void close() {
if (closed) {
throw new IllegalStateException("Cannot re-close compilation result " + this);
}
dataSection.close();
closed = true;
}
}

View File

@ -141,7 +141,7 @@ public final class DataSection implements Iterable<Data> {
private final ArrayList<Data> dataItems = new ArrayList<>();
private boolean finalLayout;
private boolean closed;
private int sectionAlignment;
private int sectionSize;
@ -163,7 +163,7 @@ public final class DataSection implements Iterable<Data> {
}
if (obj instanceof DataSection) {
DataSection that = (DataSection) obj;
if (this.finalLayout == that.finalLayout && this.sectionAlignment == that.sectionAlignment && this.sectionSize == that.sectionSize && Objects.equals(this.dataItems, that.dataItems)) {
if (this.closed == that.closed && this.sectionAlignment == that.sectionAlignment && this.sectionSize == that.sectionSize && Objects.equals(this.dataItems, that.dataItems)) {
return true;
}
}
@ -171,14 +171,14 @@ public final class DataSection implements Iterable<Data> {
}
/**
* Insert a {@link Data} item into the data section. If the item is already in the data section,
* the same {@link DataSectionReference} is returned.
* Inserts a {@link Data} item into the data section. If the item is already in the data
* section, the same {@link DataSectionReference} is returned.
*
* @param data the {@link Data} item to be inserted
* @return a unique {@link DataSectionReference} identifying the {@link Data} item
*/
public DataSectionReference insertData(Data data) {
assert !finalLayout;
checkOpen();
synchronized (data) {
if (data.ref == null) {
data.ref = new DataSectionReference();
@ -193,7 +193,8 @@ public final class DataSection implements Iterable<Data> {
* {@link DataSection}, and empties the other section.
*/
public void addAll(DataSection other) {
assert !finalLayout && !other.finalLayout;
checkOpen();
other.checkOpen();
for (Data data : other.dataItems) {
assert data.ref != null;
@ -203,12 +204,20 @@ public final class DataSection implements Iterable<Data> {
}
/**
* Compute the layout of the data section. This can be called only once, and after it has been
* called, the data section can no longer be modified.
* Determines if this object has been {@link #close() closed}.
*/
public void finalizeLayout() {
assert !finalLayout;
finalLayout = true;
public boolean closed() {
return closed;
}
/**
* Computes the layout of the data section and closes this object to further updates.
*
* This must be called exactly once.
*/
void close() {
checkOpen();
closed = true;
// simple heuristic: put items with larger alignment requirement first
dataItems.sort((a, b) -> a.alignment - b.alignment);
@ -227,37 +236,38 @@ public final class DataSection implements Iterable<Data> {
sectionSize = position;
}
public boolean isFinalized() {
return finalLayout;
}
/**
* Get the size of the data section. Can only be called after {@link #finalizeLayout}.
* Gets the size of the data section.
*
* This must only be called once this object has been {@linkplain #closed() closed}.
*/
public int getSectionSize() {
assert finalLayout;
checkClosed();
return sectionSize;
}
/**
* Get the minimum alignment requirement of the data section. Can only be called after
* {@link #finalizeLayout}.
* Gets the minimum alignment requirement of the data section.
*
* This must only be called once this object has been {@linkplain #closed() closed}.
*/
public int getSectionAlignment() {
assert finalLayout;
checkClosed();
return sectionAlignment;
}
/**
* Build the data section. Can only be called after {@link #finalizeLayout}.
* Builds the data section into a given buffer.
*
* @param buffer The {@link ByteBuffer} where the data section should be built. The buffer must
* This must only be called once this object has been {@linkplain #closed() closed}.
*
* @param buffer the {@link ByteBuffer} where the data section should be built. The buffer must
* hold at least {@link #getSectionSize()} bytes.
* @param patch A {@link Consumer} to receive {@link DataPatch data patches} for relocations in
* the data section.
* @param patch a {@link Consumer} to receive {@link DataPatch data patches} for relocations in
* the data section
*/
public void buildDataSection(ByteBuffer buffer, Consumer<DataPatch> patch) {
assert finalLayout;
checkClosed();
for (Data d : dataItems) {
buffer.position(d.ref.getOffset());
d.builder.emit(buffer, patch);
@ -300,8 +310,20 @@ public final class DataSection implements Iterable<Data> {
return ((position + alignment - 1) / alignment) * alignment;
}
private void checkClosed() {
if (!closed) {
throw new IllegalStateException();
}
}
private void checkOpen() {
if (closed) {
throw new IllegalStateException();
}
}
public void clear() {
assert !finalLayout;
checkOpen();
this.dataItems.clear();
this.sectionAlignment = 0;
this.sectionSize = 0;

View File

@ -26,22 +26,12 @@ package jdk.vm.ci.code;
* A reason for infopoint insertion.
*/
public enum InfopointReason {
UNKNOWN(false),
SAFEPOINT(false),
CALL(false),
IMPLICIT_EXCEPTION(false),
METHOD_START(true),
METHOD_END(true),
LINE_NUMBER(true),
METASPACE_ACCESS(true);
private InfopointReason(boolean canBeOmitted) {
this.canBeOmitted = canBeOmitted;
}
private final boolean canBeOmitted;
public boolean canBeOmitted() {
return canBeOmitted;
}
SAFEPOINT,
CALL,
IMPLICIT_EXCEPTION,
METASPACE_ACCESS,
METHOD_START,
METHOD_END,
BYTECODE_POSITION;
}

View File

@ -24,9 +24,12 @@ package jdk.vm.ci.hotspot;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.EnumMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Stream;
import java.util.stream.Stream.Builder;
@ -41,6 +44,8 @@ import jdk.vm.ci.code.CompilationResult.JumpTable;
import jdk.vm.ci.code.CompilationResult.Mark;
import jdk.vm.ci.code.CompilationResult.Site;
import jdk.vm.ci.code.DataSection;
import jdk.vm.ci.code.InfopointReason;
import jdk.vm.ci.common.JVMCIError;
import jdk.vm.ci.meta.Assumptions.Assumption;
import jdk.vm.ci.meta.ResolvedJavaMethod;
@ -118,7 +123,6 @@ public class HotSpotCompiledCode {
targetCodeSize = compResult.getTargetCodeSize();
DataSection data = compResult.getDataSection();
data.finalizeLayout();
dataSection = new byte[data.getSectionSize()];
ByteBuffer buffer = ByteBuffer.wrap(dataSection).order(ByteOrder.nativeOrder());
@ -155,14 +159,75 @@ public class HotSpotCompiledCode {
static class SiteComparator implements Comparator<Site> {
/**
* Defines an order for sorting {@link Infopoint}s based on their
* {@linkplain Infopoint#reason reasons}. This is used to choose which infopoint to preserve
* when multiple infopoints collide on the same PC offset. A negative order value implies a
* non-optional infopoint (i.e., must be preserved). Non-optional infopoints must not
* collide.
*/
static final Map<InfopointReason, Integer> HOTSPOT_INFOPOINT_SORT_ORDER = new EnumMap<>(InfopointReason.class);
static {
HOTSPOT_INFOPOINT_SORT_ORDER.put(InfopointReason.SAFEPOINT, -4);
HOTSPOT_INFOPOINT_SORT_ORDER.put(InfopointReason.CALL, -3);
HOTSPOT_INFOPOINT_SORT_ORDER.put(InfopointReason.IMPLICIT_EXCEPTION, -2);
HOTSPOT_INFOPOINT_SORT_ORDER.put(InfopointReason.METASPACE_ACCESS, 1);
HOTSPOT_INFOPOINT_SORT_ORDER.put(InfopointReason.METHOD_START, 2);
HOTSPOT_INFOPOINT_SORT_ORDER.put(InfopointReason.METHOD_END, 3);
HOTSPOT_INFOPOINT_SORT_ORDER.put(InfopointReason.BYTECODE_POSITION, 4);
}
static int ord(Infopoint info) {
return HOTSPOT_INFOPOINT_SORT_ORDER.get(info.reason);
}
static int checkCollision(Infopoint i1, Infopoint i2) {
int o1 = ord(i1);
int o2 = ord(i2);
if (o1 < 0 && o2 < 0) {
throw new JVMCIError("Non-optional infopoints cannot collide: %s and %s", i1, i2);
}
return o1 - o2;
}
/**
* Records whether any two {@link Infopoint}s had the same {@link Infopoint#pcOffset}.
*/
boolean sawCollidingInfopoints;
public int compare(Site s1, Site s2) {
if (s1.pcOffset == s2.pcOffset && (s1 instanceof Mark ^ s2 instanceof Mark)) {
return s1 instanceof Mark ? -1 : 1;
if (s1.pcOffset == s2.pcOffset) {
// Marks must come first since patching a call site
// may need to know the mark denoting the call type
// (see uses of CodeInstaller::_next_call_type).
boolean s1IsMark = s1 instanceof Mark;
boolean s2IsMark = s2 instanceof Mark;
if (s1IsMark != s2IsMark) {
return s1IsMark ? -1 : 1;
}
// Infopoints must group together so put them after
// other Site types.
boolean s1IsInfopoint = s1 instanceof Infopoint;
boolean s2IsInfopoint = s2 instanceof Infopoint;
if (s1IsInfopoint != s2IsInfopoint) {
return s1IsInfopoint ? 1 : -1;
}
if (s1IsInfopoint) {
sawCollidingInfopoints = true;
return checkCollision((Infopoint) s1, (Infopoint) s2);
}
}
return s1.pcOffset - s2.pcOffset;
}
}
/**
* HotSpot expects sites to be presented in ascending order of PC (see
* {@code DebugInformationRecorder::add_new_pc_offset}). In addition, it expects
* {@link Infopoint} PCs to be unique.
*/
private static Site[] getSortedSites(CompilationResult target) {
List<?>[] lists = new List<?>[]{target.getInfopoints(), target.getDataPatches(), target.getMarks()};
int count = 0;
@ -176,7 +241,27 @@ public class HotSpotCompiledCode {
result[pos++] = (Site) elem;
}
}
Arrays.sort(result, new SiteComparator());
SiteComparator c = new SiteComparator();
Arrays.sort(result, c);
if (c.sawCollidingInfopoints) {
Infopoint lastInfopoint = null;
List<Site> copy = new ArrayList<>(count);
for (int i = 0; i < count; i++) {
if (result[i] instanceof Infopoint) {
Infopoint info = (Infopoint) result[i];
if (lastInfopoint == null || lastInfopoint.pcOffset != info.pcOffset) {
lastInfopoint = info;
copy.add(info);
} else {
// Omit this colliding infopoint
assert lastInfopoint.reason.compareTo(info.reason) <= 0;
}
} else {
copy.add(result[i]);
}
}
result = copy.toArray(new Site[copy.size()]);
}
return result;
}

View File

@ -36,7 +36,7 @@ void LIR_Assembler::patching_epilog(PatchingStub* patch, LIR_PatchCode patch_cod
// We must have enough patching space so that call can be inserted.
// We cannot use fat nops here, since the concurrent code rewrite may transiently
// create the illegal instruction sequence.
while ((intx) _masm->pc() - (intx) patch->pc_start() < NativeCall::instruction_size) {
while ((intx) _masm->pc() - (intx) patch->pc_start() < NativeGeneralJump::instruction_size) {
_masm->nop();
}
patch->install(_masm, patch_code, obj, info);

View File

@ -1163,7 +1163,7 @@ JRT_ENTRY(void, Runtime1::patch_code(JavaThread* thread, Runtime1::StubID stub_i
}
#endif
for (int i = NativeCall::instruction_size; i < *byte_count; i++) {
for (int i = NativeGeneralJump::instruction_size; i < *byte_count; i++) {
address ptr = copy_buff + i;
int a_byte = (*ptr) & 0xFF;
address dst = instr_pc + i;

View File

@ -33,7 +33,7 @@
// We keep track of these chunks in order to detect
// repetition and enable sharing.
class DIR_Chunk {
friend class DebugInformationRecorder;
private:
int _offset; // location in the stream of this scope
int _length; // number of bytes in the stream
int _hash; // hash of stream bytes (for quicker reuse)
@ -41,6 +41,9 @@ class DIR_Chunk {
DebugInformationRecorder* _DIR;
#endif
public:
int offset() { return _offset; }
void* operator new(size_t ignore, DebugInformationRecorder* dir) throw() {
assert(ignore == sizeof(DIR_Chunk), "");
if (dir->_next_chunk >= dir->_next_chunk_limit) {
@ -284,7 +287,7 @@ int DebugInformationRecorder::find_sharable_decode_offset(int stream_offset) {
NOT_PRODUCT(++dir_stats.chunks_shared);
assert(ns+1 == _next_chunk, "");
_next_chunk = ns;
return match->_offset;
return match->offset();
} else {
// Inserted this chunk, so nothing to do
return serialized_null;
@ -296,7 +299,7 @@ int DebugInformationRecorder::find_sharable_decode_offset(int stream_offset) {
NOT_PRODUCT(++dir_stats.chunks_reshared);
assert(ns+1 == _next_chunk, "");
_next_chunk = ns;
return ms->_offset;
return ms->offset();
}
// Look in recently encountered scopes next:
@ -311,7 +314,7 @@ int DebugInformationRecorder::find_sharable_decode_offset(int stream_offset) {
_shared_chunks->append(ms);
assert(ns+1 == _next_chunk, "");
_next_chunk = ns;
return ms->_offset;
return ms->offset();
}
// No match. Add this guy to the list, in hopes of future shares.

View File

@ -727,10 +727,9 @@ JVMCIEnv::CodeInstallResult CodeInstaller::initialize_buffer(CodeBuffer& buffer,
if (InfopointReason::SAFEPOINT() == reason || InfopointReason::CALL() == reason || InfopointReason::IMPLICIT_EXCEPTION() == reason) {
TRACE_jvmci_4("safepoint at %i", pc_offset);
site_Safepoint(buffer, pc_offset, site, CHECK_OK);
} else if (InfopointReason::METHOD_START() == reason || InfopointReason::METHOD_END() == reason || InfopointReason::LINE_NUMBER() == reason) {
site_Infopoint(buffer, pc_offset, site, CHECK_OK);
} else {
JVMCI_ERROR_OK("unknown infopoint reason at %i", pc_offset);
TRACE_jvmci_4("infopoint at %i", pc_offset);
site_Infopoint(buffer, pc_offset, site, CHECK_OK);
}
} else if (site->is_a(CompilationResult_DataPatch::klass())) {
TRACE_jvmci_4("datapatch at %i", pc_offset);
@ -868,25 +867,33 @@ GrowableArray<ScopeValue*>* CodeInstaller::record_virtual_objects(Handle debug_i
return objects;
}
void CodeInstaller::record_scope(jint pc_offset, Handle debug_info, TRAPS) {
void CodeInstaller::record_scope(jint pc_offset, Handle debug_info, ScopeMode scope_mode, TRAPS) {
Handle position = DebugInfo::bytecodePosition(debug_info);
if (position.is_null()) {
// Stubs do not record scope info, just oop maps
return;
}
GrowableArray<ScopeValue*>* objectMapping = record_virtual_objects(debug_info, CHECK);
record_scope(pc_offset, position, objectMapping, CHECK);
GrowableArray<ScopeValue*>* objectMapping;
if (scope_mode == CodeInstaller::FullFrame) {
objectMapping = record_virtual_objects(debug_info, CHECK);
} else {
objectMapping = NULL;
}
record_scope(pc_offset, position, scope_mode, objectMapping, CHECK);
}
void CodeInstaller::record_scope(jint pc_offset, Handle position, GrowableArray<ScopeValue*>* objects, TRAPS) {
void CodeInstaller::record_scope(jint pc_offset, Handle position, ScopeMode scope_mode, GrowableArray<ScopeValue*>* objects, TRAPS) {
Handle frame;
if (position->is_a(BytecodeFrame::klass())) {
if (scope_mode == CodeInstaller::FullFrame) {
if (!position->is_a(BytecodeFrame::klass())) {
JVMCI_ERROR("Full frame expected for debug info at %i", pc_offset);
}
frame = position;
}
Handle caller_frame = BytecodePosition::caller(position);
if (caller_frame.not_null()) {
record_scope(pc_offset, caller_frame, objects, CHECK);
record_scope(pc_offset, caller_frame, scope_mode, objects, CHECK);
}
Handle hotspot_method = BytecodePosition::method(position);
@ -990,7 +997,7 @@ void CodeInstaller::site_Safepoint(CodeBuffer& buffer, jint pc_offset, Handle si
// jint next_pc_offset = Assembler::locate_next_instruction(instruction) - _instructions->start();
OopMap *map = create_oop_map(debug_info, CHECK);
_debug_recorder->add_safepoint(pc_offset, map);
record_scope(pc_offset, debug_info, CHECK);
record_scope(pc_offset, debug_info, CodeInstaller::FullFrame, CHECK);
_debug_recorder->end_safepoint(pc_offset);
}
@ -1000,8 +1007,12 @@ void CodeInstaller::site_Infopoint(CodeBuffer& buffer, jint pc_offset, Handle si
JVMCI_ERROR("debug info expected at infopoint at %i", pc_offset);
}
// We'd like to check that pc_offset is greater than the
// last pc recorded with _debug_recorder (raising an exception if not)
// but DebugInformationRecorder doesn't have sufficient public API.
_debug_recorder->add_non_safepoint(pc_offset);
record_scope(pc_offset, debug_info, CHECK);
record_scope(pc_offset, debug_info, CodeInstaller::BytecodePosition, CHECK);
_debug_recorder->end_non_safepoint(pc_offset);
}
@ -1028,7 +1039,7 @@ void CodeInstaller::site_Call(CodeBuffer& buffer, jint pc_offset, Handle site, T
if (debug_info.not_null()) {
OopMap *map = create_oop_map(debug_info, CHECK);
_debug_recorder->add_safepoint(next_pc_offset, map);
record_scope(next_pc_offset, debug_info, CHECK);
record_scope(next_pc_offset, debug_info, CodeInstaller::FullFrame, CHECK);
}
if (foreign_call.not_null()) {

View File

@ -219,8 +219,18 @@ protected:
OopMap* create_oop_map(Handle debug_info, TRAPS);
void record_scope(jint pc_offset, Handle debug_info, TRAPS);
void record_scope(jint pc_offset, Handle code_pos, GrowableArray<ScopeValue*>* objects, TRAPS);
/**
* Specifies the level of detail to record for a scope.
*/
enum ScopeMode {
// Only record a method and BCI
BytecodePosition,
// Record a method, bci and JVM frame state
FullFrame
};
void record_scope(jint pc_offset, Handle debug_info, ScopeMode scope_mode, TRAPS);
void record_scope(jint pc_offset, Handle position, ScopeMode scope_mode, GrowableArray<ScopeValue*>* objects, TRAPS);
void record_object_value(ObjectValue* sv, Handle value, GrowableArray<ScopeValue*>* objects, TRAPS);
GrowableArray<ScopeValue*>* record_virtual_objects(Handle debug_info, TRAPS);

View File

@ -148,14 +148,9 @@ class JVMCIJavaClasses : AllStatic {
int_field(CompilationResult_DataSectionReference, offset) \
end_class \
start_class(InfopointReason) \
static_oop_field(InfopointReason, UNKNOWN, "Ljdk/vm/ci/code/InfopointReason;") \
static_oop_field(InfopointReason, SAFEPOINT, "Ljdk/vm/ci/code/InfopointReason;") \
static_oop_field(InfopointReason, CALL, "Ljdk/vm/ci/code/InfopointReason;") \
static_oop_field(InfopointReason, IMPLICIT_EXCEPTION, "Ljdk/vm/ci/code/InfopointReason;") \
static_oop_field(InfopointReason, METHOD_START, "Ljdk/vm/ci/code/InfopointReason;") \
static_oop_field(InfopointReason, METHOD_END, "Ljdk/vm/ci/code/InfopointReason;") \
static_oop_field(InfopointReason, LINE_NUMBER, "Ljdk/vm/ci/code/InfopointReason;") \
static_oop_field(InfopointReason, METASPACE_ACCESS, "Ljdk/vm/ci/code/InfopointReason;") \
end_class \
start_class(CompilationResult_Infopoint) \
oop_field(CompilationResult_Infopoint, debugInfo, "Ljdk/vm/ci/code/DebugInfo;") \

View File

@ -744,7 +744,10 @@
range(0, max_intx) \
\
develop(bool, StressArrayCopyMacroNode, false, \
"Perform ArrayCopy load/store replacement during IGVN only")
"Perform ArrayCopy load/store replacement during IGVN only") \
\
develop(bool, RenumberLiveNodes, true, \
"Renumber live nodes") \
C2_FLAGS(DECLARE_DEVELOPER_FLAG, \
DECLARE_PD_DEVELOPER_FLAG, \

View File

@ -2156,6 +2156,20 @@ void Compile::Optimize() {
// so keep only the actual candidates for optimizations.
cleanup_expensive_nodes(igvn);
if (!failing() && RenumberLiveNodes && live_nodes() + NodeLimitFudgeFactor < unique()) {
Compile::TracePhase tp("", &timers[_t_renumberLive]);
initial_gvn()->replace_with(&igvn);
for_igvn()->clear();
Unique_Node_List new_worklist(C->comp_arena());
{
ResourceMark rm;
PhaseRenumberLive prl = PhaseRenumberLive(initial_gvn(), for_igvn(), &new_worklist);
}
set_for_igvn(&new_worklist);
igvn = PhaseIterGVN(initial_gvn());
igvn.optimize();
}
// Perform escape analysis
if (_do_escape_analysis && ConnectionGraph::has_candidates(this)) {
if (has_loops()) {

View File

@ -152,6 +152,8 @@ class LibraryCallKit : public GraphKit {
Node* generate_limit_guard(Node* offset, Node* subseq_length,
Node* array_length,
RegionNode* region);
void generate_string_range_check(Node* array, Node* offset,
Node* length, bool char_count);
Node* generate_current_thread(Node* &tls_output);
Node* load_mirror_from_klass(Node* klass);
Node* load_klass_from_mirror_common(Node* mirror, bool never_see_null,
@ -204,6 +206,8 @@ class LibraryCallKit : public GraphKit {
bool inline_string_compareTo(StrIntrinsicNode::ArgEnc ae);
bool inline_string_indexOf(StrIntrinsicNode::ArgEnc ae);
bool inline_string_indexOfI(StrIntrinsicNode::ArgEnc ae);
Node* make_indexOf_node(Node* src_start, Node* src_count, Node* tgt_start, Node* tgt_count,
RegionNode* region, Node* phi, StrIntrinsicNode::ArgEnc ae);
bool inline_string_indexOfChar();
bool inline_string_equals(StrIntrinsicNode::ArgEnc ae);
bool inline_string_toBytesU();
@ -897,6 +901,31 @@ inline Node* LibraryCallKit::generate_limit_guard(Node* offset,
return is_over;
}
// Emit range checks for the given String.value byte array
void LibraryCallKit::generate_string_range_check(Node* array, Node* offset, Node* count, bool char_count) {
if (stopped()) {
return; // already stopped
}
RegionNode* bailout = new RegionNode(1);
record_for_igvn(bailout);
if (char_count) {
// Convert char count to byte count
count = _gvn.transform(new LShiftINode(count, intcon(1)));
}
// Offset and count must not be negative
generate_negative_guard(offset, bailout);
generate_negative_guard(count, bailout);
// Offset + count must not exceed length of array
generate_limit_guard(offset, count, load_array_length(array), bailout);
if (bailout->req() > 1) {
PreserveJVMState pjvms(this);
set_control(_gvn.transform(bailout));
uncommon_trap(Deoptimization::Reason_intrinsic,
Deoptimization::Action_maybe_recompile);
}
}
//--------------------------generate_current_thread--------------------
Node* LibraryCallKit::generate_current_thread(Node* &tls_output) {
@ -1016,7 +1045,9 @@ bool LibraryCallKit::inline_array_equals(StrIntrinsicNode::ArgEnc ae) {
//------------------------------inline_hasNegatives------------------------------
bool LibraryCallKit::inline_hasNegatives() {
if (too_many_traps(Deoptimization::Reason_intrinsic)) return false;
if (too_many_traps(Deoptimization::Reason_intrinsic)) {
return false;
}
assert(callee()->signature()->size() == 3, "hasNegatives has 3 parameters");
// no receiver since it is static method
@ -1024,26 +1055,14 @@ bool LibraryCallKit::inline_hasNegatives() {
Node* offset = argument(1);
Node* len = argument(2);
RegionNode* bailout = new RegionNode(1);
record_for_igvn(bailout);
// offset must not be negative.
generate_negative_guard(offset, bailout);
// offset + length must not exceed length of ba.
generate_limit_guard(offset, len, load_array_length(ba), bailout);
if (bailout->req() > 1) {
PreserveJVMState pjvms(this);
set_control(_gvn.transform(bailout));
uncommon_trap(Deoptimization::Reason_intrinsic,
Deoptimization::Action_maybe_recompile);
}
if (!stopped()) {
Node* ba_start = array_element_address(ba, offset, T_BYTE);
Node* result = new HasNegativesNode(control(), memory(TypeAryPtr::BYTES), ba_start, len);
set_result(_gvn.transform(result));
// Range checks
generate_string_range_check(ba, offset, len, false);
if (stopped()) {
return true;
}
Node* ba_start = array_element_address(ba, offset, T_BYTE);
Node* result = new HasNegativesNode(control(), memory(TypeAryPtr::BYTES), ba_start, len);
set_result(_gvn.transform(result));
return true;
}
@ -1124,30 +1143,10 @@ bool LibraryCallKit::inline_string_indexOf(StrIntrinsicNode::ArgEnc ae) {
tgt_count = _gvn.transform(new RShiftINode(tgt_count, intcon(1)));
}
// Check for substr count > string count
Node* cmp = _gvn.transform(new CmpINode(tgt_count, src_count));
Node* bol = _gvn.transform(new BoolNode(cmp, BoolTest::gt));
Node* if_gt = generate_slow_guard(bol, NULL);
if (if_gt != NULL) {
result_phi->init_req(2, intcon(-1));
result_rgn->init_req(2, if_gt);
}
if (!stopped()) {
// Check for substr count == 0
cmp = _gvn.transform(new CmpINode(tgt_count, intcon(0)));
bol = _gvn.transform(new BoolNode(cmp, BoolTest::eq));
Node* if_zero = generate_slow_guard(bol, NULL);
if (if_zero != NULL) {
result_phi->init_req(3, intcon(0));
result_rgn->init_req(3, if_zero);
}
}
if (!stopped()) {
Node* result = make_string_method_node(Op_StrIndexOf, src_start, src_count, tgt_start, tgt_count, ae);
result_phi->init_req(1, result);
result_rgn->init_req(1, control());
Node* result = make_indexOf_node(src_start, src_count, tgt_start, tgt_count, result_rgn, result_phi, ae);
if (result != NULL) {
result_phi->init_req(3, result);
result_rgn->init_req(3, control());
}
set_control(_gvn.transform(result_rgn));
record_for_igvn(result_rgn);
@ -1158,44 +1157,53 @@ bool LibraryCallKit::inline_string_indexOf(StrIntrinsicNode::ArgEnc ae) {
//-----------------------------inline_string_indexOf-----------------------
bool LibraryCallKit::inline_string_indexOfI(StrIntrinsicNode::ArgEnc ae) {
if (too_many_traps(Deoptimization::Reason_intrinsic)) {
return false;
}
if (!Matcher::has_match_rule(Op_StrIndexOf) || !UseSSE42Intrinsics) {
return false;
}
assert(callee()->signature()->size() == 5, "String.indexOf() has 5 arguments");
Node* src = argument(0); // byte[]
Node* src_count = argument(1);
Node* src_count = argument(1); // char count
Node* tgt = argument(2); // byte[]
Node* tgt_count = argument(3);
Node* from_index = argument(4);
// Java code which calls this method has range checks for from_index value.
src_count = _gvn.transform(new SubINode(src_count, from_index));
Node* tgt_count = argument(3); // char count
Node* from_index = argument(4); // char index
// Multiply byte array index by 2 if String is UTF16 encoded
Node* src_offset = (ae == StrIntrinsicNode::LL) ? from_index : _gvn.transform(new LShiftINode(from_index, intcon(1)));
src_count = _gvn.transform(new SubINode(src_count, from_index));
Node* src_start = array_element_address(src, src_offset, T_BYTE);
Node* tgt_start = array_element_address(tgt, intcon(0), T_BYTE);
Node* result = make_string_method_node(Op_StrIndexOf, src_start, src_count, tgt_start, tgt_count, ae);
// Range checks
generate_string_range_check(src, src_offset, src_count, ae != StrIntrinsicNode::LL);
generate_string_range_check(tgt, intcon(0), tgt_count, ae == StrIntrinsicNode::UU);
if (stopped()) {
return true;
}
// The result is index relative to from_index if substring was found, -1 otherwise.
// Generate code which will fold into cmove.
RegionNode* region = new RegionNode(3);
RegionNode* region = new RegionNode(5);
Node* phi = new PhiNode(region, TypeInt::INT);
Node* cmp = _gvn.transform(new CmpINode(result, intcon(0)));
Node* bol = _gvn.transform(new BoolNode(cmp, BoolTest::lt));
Node* result = make_indexOf_node(src_start, src_count, tgt_start, tgt_count, region, phi, ae);
if (result != NULL) {
// The result is index relative to from_index if substring was found, -1 otherwise.
// Generate code which will fold into cmove.
Node* cmp = _gvn.transform(new CmpINode(result, intcon(0)));
Node* bol = _gvn.transform(new BoolNode(cmp, BoolTest::lt));
Node* if_lt = generate_slow_guard(bol, NULL);
if (if_lt != NULL) {
// result == -1
phi->init_req(2, result);
region->init_req(2, if_lt);
}
if (!stopped()) {
result = _gvn.transform(new AddINode(result, from_index));
phi->init_req(1, result);
region->init_req(1, control());
Node* if_lt = generate_slow_guard(bol, NULL);
if (if_lt != NULL) {
// result == -1
phi->init_req(3, result);
region->init_req(3, if_lt);
}
if (!stopped()) {
result = _gvn.transform(new AddINode(result, from_index));
phi->init_req(4, result);
region->init_req(4, control());
}
}
set_control(_gvn.transform(region));
@ -1205,8 +1213,38 @@ bool LibraryCallKit::inline_string_indexOfI(StrIntrinsicNode::ArgEnc ae) {
return true;
}
// Create StrIndexOfNode with fast path checks
Node* LibraryCallKit::make_indexOf_node(Node* src_start, Node* src_count, Node* tgt_start, Node* tgt_count,
RegionNode* region, Node* phi, StrIntrinsicNode::ArgEnc ae) {
// Check for substr count > string count
Node* cmp = _gvn.transform(new CmpINode(tgt_count, src_count));
Node* bol = _gvn.transform(new BoolNode(cmp, BoolTest::gt));
Node* if_gt = generate_slow_guard(bol, NULL);
if (if_gt != NULL) {
phi->init_req(1, intcon(-1));
region->init_req(1, if_gt);
}
if (!stopped()) {
// Check for substr count == 0
cmp = _gvn.transform(new CmpINode(tgt_count, intcon(0)));
bol = _gvn.transform(new BoolNode(cmp, BoolTest::eq));
Node* if_zero = generate_slow_guard(bol, NULL);
if (if_zero != NULL) {
phi->init_req(2, intcon(0));
region->init_req(2, if_zero);
}
}
if (!stopped()) {
return make_string_method_node(Op_StrIndexOf, src_start, src_count, tgt_start, tgt_count, ae);
}
return NULL;
}
//-----------------------------inline_string_indexOfChar-----------------------
bool LibraryCallKit::inline_string_indexOfChar() {
if (too_many_traps(Deoptimization::Reason_intrinsic)) {
return false;
}
if (!Matcher::has_match_rule(Op_StrIndexOfChar) || !(UseSSE > 4)) {
return false;
}
@ -1218,9 +1256,14 @@ bool LibraryCallKit::inline_string_indexOfChar() {
Node* src_offset = _gvn.transform(new LShiftINode(from_index, intcon(1)));
Node* src_start = array_element_address(src, src_offset, T_BYTE);
Node* src_count = _gvn.transform(new SubINode(max, from_index));
// Range checks
generate_string_range_check(src, src_offset, src_count, true);
if (stopped()) {
return true;
}
RegionNode* region = new RegionNode(3);
Node* phi = new PhiNode(region, TypeInt::INT);
@ -1256,6 +1299,9 @@ bool LibraryCallKit::inline_string_indexOfChar() {
// void StringLatin1.inflate(byte[] src, int srcOff, char[] dst, int dstOff, int len)
// void StringLatin1.inflate(byte[] src, int srcOff, byte[] dst, int dstOff, int len)
bool LibraryCallKit::inline_string_copy(bool compress) {
if (too_many_traps(Deoptimization::Reason_intrinsic)) {
return false;
}
int nargs = 5; // 2 oops, 3 ints
assert(callee()->signature()->size() == nargs, "string copy has 5 arguments");
@ -1278,6 +1324,13 @@ bool LibraryCallKit::inline_string_copy(bool compress) {
(!compress && src_elem == T_BYTE && (dst_elem == T_BYTE || dst_elem == T_CHAR)),
"Unsupported array types for inline_string_copy");
// Range checks
generate_string_range_check(src, src_offset, length, compress && src_elem == T_BYTE);
generate_string_range_check(dst, dst_offset, length, !compress && dst_elem == T_BYTE);
if (stopped()) {
return true;
}
// Convert char[] offsets to byte[] offsets
if (compress && src_elem == T_BYTE) {
src_offset = _gvn.transform(new LShiftINode(src_offset, intcon(1)));
@ -1329,6 +1382,9 @@ bool LibraryCallKit::inline_string_copy(bool compress) {
//------------------------inline_string_toBytesU--------------------------
// public static byte[] StringUTF16.toBytes(char[] value, int off, int len)
bool LibraryCallKit::inline_string_toBytesU() {
if (too_many_traps(Deoptimization::Reason_intrinsic)) {
return false;
}
// Get the arguments.
Node* value = argument(0);
Node* offset = argument(1);
@ -1347,8 +1403,11 @@ bool LibraryCallKit::inline_string_toBytesU() {
RegionNode* bailout = new RegionNode(1);
record_for_igvn(bailout);
// Make sure that resulting byte[] length does not overflow Integer.MAX_VALUE
// Range checks
generate_negative_guard(offset, bailout);
generate_negative_guard(length, bailout);
generate_limit_guard(offset, length, load_array_length(value), bailout);
// Make sure that resulting byte[] length does not overflow Integer.MAX_VALUE
generate_limit_guard(length, intcon(0), intcon(max_jint/2), bailout);
if (bailout->req() > 1) {
@ -1357,9 +1416,9 @@ bool LibraryCallKit::inline_string_toBytesU() {
uncommon_trap(Deoptimization::Reason_intrinsic,
Deoptimization::Action_maybe_recompile);
}
if (stopped()) return true;
// Range checks are done by caller.
if (stopped()) {
return true;
}
Node* size = _gvn.transform(new LShiftINode(length, intcon(1)));
Node* klass_node = makecon(TypeKlassPtr::make(ciTypeArrayKlass::make(T_BYTE)));
@ -1412,12 +1471,14 @@ bool LibraryCallKit::inline_string_toBytesU() {
}
//------------------------inline_string_getCharsU--------------------------
// public void StringUTF16.getChars(byte[] value, int srcBegin, int srcEnd, char dst[], int dstBegin)
// public void StringUTF16.getChars(byte[] src, int srcBegin, int srcEnd, char dst[], int dstBegin)
bool LibraryCallKit::inline_string_getCharsU() {
if (too_many_traps(Deoptimization::Reason_intrinsic)) return false;
if (too_many_traps(Deoptimization::Reason_intrinsic)) {
return false;
}
// Get the arguments.
Node* value = argument(0);
Node* src = argument(0);
Node* src_begin = argument(1);
Node* src_end = argument(2); // exclusive offset (i < src_end)
Node* dst = argument(3);
@ -1428,21 +1489,26 @@ bool LibraryCallKit::inline_string_getCharsU() {
AllocateArrayNode* alloc = tightly_coupled_allocation(dst, NULL);
// Check if a null path was taken unconditionally.
value = null_check(value);
src = null_check(src);
dst = null_check(dst);
if (stopped()) {
return true;
}
// Range checks are done by caller.
// Get length and convert char[] offset to byte[] offset
Node* length = _gvn.transform(new SubINode(src_end, src_begin));
src_begin = _gvn.transform(new LShiftINode(src_begin, intcon(1)));
// Range checks
generate_string_range_check(src, src_begin, length, true);
generate_string_range_check(dst, dst_begin, length, false);
if (stopped()) {
return true;
}
if (!stopped()) {
// Calculate starting addresses.
Node* src_start = array_element_address(value, src_begin, T_BYTE);
Node* src_start = array_element_address(src, src_begin, T_BYTE);
Node* dst_start = array_element_address(dst, dst_begin, T_CHAR);
// Check if array addresses are aligned to HeapWordSize

View File

@ -316,6 +316,9 @@ inline int Node::Init(int req) {
// Create a Node, with a given number of required edges.
Node::Node(uint req)
: _idx(Init(req))
#ifdef ASSERT
, _parse_idx(_idx)
#endif
{
assert( req < Compile::current()->max_node_limit() - NodeLimitFudgeFactor, "Input limit exceeded" );
debug_only( verify_construction() );
@ -335,6 +338,9 @@ Node::Node(uint req)
//------------------------------Node-------------------------------------------
Node::Node(Node *n0)
: _idx(Init(1))
#ifdef ASSERT
, _parse_idx(_idx)
#endif
{
debug_only( verify_construction() );
NOT_PRODUCT(nodes_created++);
@ -347,6 +353,9 @@ Node::Node(Node *n0)
//------------------------------Node-------------------------------------------
Node::Node(Node *n0, Node *n1)
: _idx(Init(2))
#ifdef ASSERT
, _parse_idx(_idx)
#endif
{
debug_only( verify_construction() );
NOT_PRODUCT(nodes_created++);
@ -361,6 +370,9 @@ Node::Node(Node *n0, Node *n1)
//------------------------------Node-------------------------------------------
Node::Node(Node *n0, Node *n1, Node *n2)
: _idx(Init(3))
#ifdef ASSERT
, _parse_idx(_idx)
#endif
{
debug_only( verify_construction() );
NOT_PRODUCT(nodes_created++);
@ -377,6 +389,9 @@ Node::Node(Node *n0, Node *n1, Node *n2)
//------------------------------Node-------------------------------------------
Node::Node(Node *n0, Node *n1, Node *n2, Node *n3)
: _idx(Init(4))
#ifdef ASSERT
, _parse_idx(_idx)
#endif
{
debug_only( verify_construction() );
NOT_PRODUCT(nodes_created++);
@ -395,6 +410,9 @@ Node::Node(Node *n0, Node *n1, Node *n2, Node *n3)
//------------------------------Node-------------------------------------------
Node::Node(Node *n0, Node *n1, Node *n2, Node *n3, Node *n4)
: _idx(Init(5))
#ifdef ASSERT
, _parse_idx(_idx)
#endif
{
debug_only( verify_construction() );
NOT_PRODUCT(nodes_created++);
@ -416,6 +434,9 @@ Node::Node(Node *n0, Node *n1, Node *n2, Node *n3, Node *n4)
Node::Node(Node *n0, Node *n1, Node *n2, Node *n3,
Node *n4, Node *n5)
: _idx(Init(6))
#ifdef ASSERT
, _parse_idx(_idx)
#endif
{
debug_only( verify_construction() );
NOT_PRODUCT(nodes_created++);
@ -439,6 +460,9 @@ Node::Node(Node *n0, Node *n1, Node *n2, Node *n3,
Node::Node(Node *n0, Node *n1, Node *n2, Node *n3,
Node *n4, Node *n5, Node *n6)
: _idx(Init(7))
#ifdef ASSERT
, _parse_idx(_idx)
#endif
{
debug_only( verify_construction() );
NOT_PRODUCT(nodes_created++);

View File

@ -293,10 +293,16 @@ protected:
public:
// Each Node is assigned a unique small/dense number. This number is used
// to index into auxiliary arrays of data and bitvectors.
// It is declared const to defend against inadvertant assignment,
// since it is used by clients as a naked field.
// to index into auxiliary arrays of data and bit vectors.
// The field _idx is declared constant to defend against inadvertent assignments,
// since it is used by clients as a naked field. However, the field's value can be
// changed using the set_idx() method.
//
// The PhaseRenumberLive phase renumbers nodes based on liveness information.
// Therefore, it updates the value of the _idx field. The parse-time _idx is
// preserved in _parse_idx.
const node_idx_t _idx;
DEBUG_ONLY(const node_idx_t _parse_idx;)
// Get the (read-only) number of input edges
uint req() const { return _cnt; }

View File

@ -77,6 +77,7 @@ void Phase::print_timers() {
tty->print_cr(" Other: %7.3f s", other);
}
}
tty->print_cr (" Renumber Live: %7.3f s", timers[_t_renumberLive].seconds());
tty->print_cr (" IdealLoop: %7.3f s", timers[_t_idealLoop].seconds());
tty->print_cr (" IdealLoop Verify: %7.3f s", timers[_t_idealLoopVerify].seconds());
tty->print_cr (" Cond Const Prop: %7.3f s", timers[_t_ccp].seconds());
@ -88,6 +89,7 @@ void Phase::print_timers() {
(timers[_t_escapeAnalysis].seconds() +
timers[_t_iterGVN].seconds() +
timers[_t_incrInline].seconds() +
timers[_t_renumberLive].seconds() +
timers[_t_idealLoop].seconds() +
timers[_t_idealLoopVerify].seconds() +
timers[_t_ccp].seconds() +

View File

@ -42,22 +42,23 @@ class PhaseGVN;
class Phase : public StackObj {
public:
enum PhaseNumber {
Compiler, // Top-level compiler phase
Parser, // Parse bytecodes
Remove_Useless, // Remove useless nodes
Optimistic, // Optimistic analysis phase
GVN, // Pessimistic global value numbering phase
Ins_Select, // Instruction selection phase
CFG, // Build a CFG
BlockLayout, // Linear ordering of blocks
Register_Allocation, // Register allocation, duh
LIVE, // Dragon-book LIVE range problem
StringOpts, // StringBuilder related optimizations
Interference_Graph, // Building the IFG
Coalesce, // Coalescing copies
Ideal_Loop, // Find idealized trip-counted loops
Macro_Expand, // Expand macro nodes
Peephole, // Apply peephole optimizations
Compiler, // Top-level compiler phase
Parser, // Parse bytecodes
Remove_Useless, // Remove useless nodes
Remove_Useless_And_Renumber_Live, // First, remove useless nodes from the graph. Then, renumber live nodes.
Optimistic, // Optimistic analysis phase
GVN, // Pessimistic global value numbering phase
Ins_Select, // Instruction selection phase
CFG, // Build a CFG
BlockLayout, // Linear ordering of blocks
Register_Allocation, // Register allocation, duh
LIVE, // Dragon-book LIVE range problem
StringOpts, // StringBuilder related optimizations
Interference_Graph, // Building the IFG
Coalesce, // Coalescing copies
Ideal_Loop, // Find idealized trip-counted loops
Macro_Expand, // Expand macro nodes
Peephole, // Apply peephole optimizations
last_phase
};
@ -73,6 +74,7 @@ public:
_t_incrInline_igvn,
_t_incrInline_pru,
_t_incrInline_inline,
_t_renumberLive,
_t_idealLoop,
_t_idealLoopVerify,
_t_ccp,

View File

@ -406,7 +406,7 @@ void NodeHash::operator=(const NodeHash& nh) {
//=============================================================================
//------------------------------PhaseRemoveUseless-----------------------------
// 1) Use a breadthfirst walk to collect useful nodes reachable from root.
PhaseRemoveUseless::PhaseRemoveUseless( PhaseGVN *gvn, Unique_Node_List *worklist ) : Phase(Remove_Useless),
PhaseRemoveUseless::PhaseRemoveUseless(PhaseGVN *gvn, Unique_Node_List *worklist, PhaseNumber phase_num) : Phase(phase_num),
_useful(Thread::current()->resource_area()) {
// Implementation requires 'UseLoopSafepoints == true' and an edge from root
@ -443,6 +443,82 @@ PhaseRemoveUseless::PhaseRemoveUseless( PhaseGVN *gvn, Unique_Node_List *worklis
}
}
//=============================================================================
//------------------------------PhaseRenumberLive------------------------------
// First, remove useless nodes (equivalent to identifying live nodes).
// Then, renumber live nodes.
//
// The set of live nodes is returned by PhaseRemoveUseless in the _useful structure.
// If the number of live nodes is 'x' (where 'x' == _useful.size()), then the
// PhaseRenumberLive updates the node ID of each node (the _idx field) with a unique
// value in the range [0, x).
//
// At the end of the PhaseRenumberLive phase, the compiler's count of unique nodes is
// updated to 'x' and the list of dead nodes is reset (as there are no dead nodes).
//
// The PhaseRenumberLive phase updates two data structures with the new node IDs.
// (1) The worklist is used by the PhaseIterGVN phase to identify nodes that must be
// processed. A new worklist (with the updated node IDs) is returned in 'new_worklist'.
// (2) Type information (the field PhaseGVN::_types) maps type information to each
// node ID. The mapping is updated to use the new node IDs as well. Updated type
// information is returned in PhaseGVN::_types.
//
// The PhaseRenumberLive phase does not preserve the order of elements in the worklist.
//
// Other data structures used by the compiler are not updated. The hash table for value
// numbering (the field PhaseGVN::_table) is not updated because computing the hash
// values is not based on node IDs. The field PhaseGVN::_nodes is not updated either
// because it is empty wherever PhaseRenumberLive is used.
PhaseRenumberLive::PhaseRenumberLive(PhaseGVN* gvn,
Unique_Node_List* worklist, Unique_Node_List* new_worklist,
PhaseNumber phase_num) :
PhaseRemoveUseless(gvn, worklist, Remove_Useless_And_Renumber_Live) {
assert(RenumberLiveNodes, "RenumberLiveNodes must be set to true for node renumbering to take place");
assert(C->live_nodes() == _useful.size(), "the number of live nodes must match the number of useful nodes");
assert(gvn->nodes_size() == 0, "GVN must not contain any nodes at this point");
uint old_unique_count = C->unique();
uint live_node_count = C->live_nodes();
uint worklist_size = worklist->size();
// Storage for the updated type information.
Type_Array new_type_array(C->comp_arena());
// Iterate over the set of live nodes.
uint current_idx = 0; // The current new node ID. Incremented after every assignment.
for (uint i = 0; i < _useful.size(); i++) {
Node* n = _useful.at(i);
const Type* type = gvn->type_or_null(n);
new_type_array.map(current_idx, type);
bool in_worklist = false;
if (worklist->member(n)) {
in_worklist = true;
}
n->set_idx(current_idx); // Update node ID.
if (in_worklist) {
new_worklist->push(n);
}
current_idx++;
}
assert(worklist_size == new_worklist->size(), "the new worklist must have the same size as the original worklist");
assert(live_node_count == current_idx, "all live nodes must be processed");
// Replace the compiler's type information with the updated type information.
gvn->replace_types(new_type_array);
// Update the unique node count of the compilation to the number of currently live nodes.
C->set_unique(live_node_count);
// Set the dead node count to 0 and reset dead node list.
C->reset_dead_node_list();
}
//=============================================================================
//------------------------------PhaseTransform---------------------------------

View File

@ -148,11 +148,21 @@ protected:
Unique_Node_List _useful; // Nodes reachable from root
// list is allocated from current resource area
public:
PhaseRemoveUseless( PhaseGVN *gvn, Unique_Node_List *worklist );
PhaseRemoveUseless(PhaseGVN *gvn, Unique_Node_List *worklist, PhaseNumber phase_num = Remove_Useless);
Unique_Node_List *get_useful() { return &_useful; }
};
//------------------------------PhaseRenumber----------------------------------
// Phase that first performs a PhaseRemoveUseless, then it renumbers compiler
// structures accordingly.
class PhaseRenumberLive : public PhaseRemoveUseless {
public:
PhaseRenumberLive(PhaseGVN* gvn,
Unique_Node_List* worklist, Unique_Node_List* new_worklist,
PhaseNumber phase_num = Remove_Useless_And_Renumber_Live);
};
//------------------------------PhaseTransform---------------------------------
// Phases that analyze, then transform. Constructing the Phase object does any
@ -162,7 +172,7 @@ public:
class PhaseTransform : public Phase {
protected:
Arena* _arena;
Node_Array _nodes; // Map old node indices to new nodes.
Node_List _nodes; // Map old node indices to new nodes.
Type_Array _types; // Map old node indices to Types.
// ConNode caches:
@ -187,7 +197,13 @@ public:
Arena* arena() { return _arena; }
Type_Array& types() { return _types; }
void replace_types(Type_Array new_types) {
_types = new_types;
}
// _nodes is used in varying ways by subclasses, which define local accessors
uint nodes_size() {
return _nodes.size();
}
public:
// Get a previously recorded type for the node n.

View File

@ -0,0 +1,164 @@
/*
* Copyright (c) 2015, Red Hat, Inc. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* 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.
*/
/*
* @test
* @bug 8144028
* @summary Use AArch64 bit-test instructions in C2
* @modules java.base
* @run main/othervm -Xbatch -XX:CompileCommand=dontinline,BitTests::* -XX:-TieredCompilation BitTests
* @run main/othervm -Xbatch -XX:+TieredCompilation -XX:TieredStopAtLevel=1 BitTests
* @run main/othervm -Xbatch -XX:+TieredCompilation BitTests
*
*/
// Try to ensure that the bit test instructions TBZ/TBNZ, TST/TSTW
// don't generate incorrect code. We can't guarantee that C2 will use
// bit test instructions for this test and it's not a bug if it
// doesn't. However, these test cases are ideal candidates for each
// of the instruction forms.
public class BitTests {
private final XorShift r = new XorShift();
private final long increment(long ctr) {
return ctr + 1;
}
private final int increment(int ctr) {
return ctr + 1;
}
private final long testIntSignedBranch(long counter) {
if ((int)r.nextLong() < 0) {
counter = increment(counter);
}
return counter;
}
private final long testLongSignedBranch(long counter) {
if (r.nextLong() < 0) {
counter = increment(counter);
}
return counter;
}
private final long testIntBitBranch(long counter) {
if (((int)r.nextLong() & (1 << 27)) != 0) {
counter = increment(counter);
}
if (((int)r.nextLong() & (1 << 27)) != 0) {
counter = increment(counter);
}
return counter;
}
private final long testLongBitBranch(long counter) {
if ((r.nextLong() & (1l << 50)) != 0) {
counter = increment(counter);
}
if ((r.nextLong() & (1l << 50)) != 0) {
counter = increment(counter);
}
return counter;
}
private final long testLongMaskBranch(long counter) {
if (((r.nextLong() & 0x0800000000l) != 0)) {
counter++;
}
return counter;
}
private final long testIntMaskBranch(long counter) {
if ((((int)r.nextLong() & 0x08) != 0)) {
counter++;
}
return counter;
}
private final long testLongMaskBranch(long counter, long mask) {
if (((r.nextLong() & mask) != 0)) {
counter++;
}
return counter;
}
private final long testIntMaskBranch(long counter, int mask) {
if ((((int)r.nextLong() & mask) != 0)) {
counter++;
}
return counter;
}
private final long step(long counter) {
counter = testIntSignedBranch(counter);
counter = testLongSignedBranch(counter);
counter = testIntBitBranch(counter);
counter = testLongBitBranch(counter);
counter = testIntMaskBranch(counter);
counter = testLongMaskBranch(counter);
counter = testIntMaskBranch(counter, 0x8000);
counter = testLongMaskBranch(counter, 0x800000000l);
return counter;
}
private final long finalBits = 3;
private long bits = 7;
public static void main(String[] args) {
BitTests t = new BitTests();
long counter = 0;
for (int i = 0; i < 10000000; i++) {
counter = t.step((int) counter);
}
if (counter != 50001495) {
System.err.println("FAILED: counter = " + counter + ", should be 50001495.");
System.exit(97);
}
System.out.println("PASSED");
}
}
// Marsaglia's xor-shift generator, used here because it is
// reproducible across all Java implementations. It is also very
// fast.
class XorShift {
private long y;
XorShift() {
y = 2463534242l;
}
public long nextLong() {
y ^= (y << 13);
y ^= (y >>> 17);
return (y ^= (y << 5));
}
}

View File

@ -0,0 +1,52 @@
/*
* 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.
*/
/*
* @test
* @bug 8142303
* @summary Tests handling of invalid array indices in C2 intrinsic if explicit range check in Java code is not inlined.
* @run main/othervm -XX:CompileCommand=inline,java.lang.String::* -XX:CompileCommand=inline,java.lang.StringUTF16::* -XX:CompileCommand=exclude,java.lang.String::checkBoundsOffCount TestStringConstruction
*/
public class TestStringConstruction {
public static void main(String[] args) {
char[] chars = new char[42];
for (int i = 0; i < 10_000; ++i) {
test(chars);
}
}
private static String test(char[] chars) {
try {
// The constructor calls String::checkBoundsOffCount(-1, 42) to perform
// range checks on offset and count. If this method is not inlined, C2
// does not know about the explicit range checks and does not cut off the
// dead code. As a result, -1 is fed as offset into the StringUTF16.compress
// intrinsic which is replaced by TOP and causes a failure in the matcher.
return new String(chars, -1 , 42);
} catch (Exception e) {
return "";
}
}
}

View File

@ -68,6 +68,7 @@ public class CodeInstallerTest {
}
protected void installCode(CompilationResult result) {
result.close();
codeCache.addCode(dummyMethod, result, null, null);
}

View File

@ -218,13 +218,6 @@ public class TestInvalidCompilationResult extends CodeInstallerTest {
installCode(result);
}
@Test(expected = JVMCIError.class)
public void testUnknownInfopointReason() {
CompilationResult result = createEmptyCompilationResult();
result.addInfopoint(new Infopoint(0, null, InfopointReason.UNKNOWN));
installCode(result);
}
@Test(expected = JVMCIError.class)
public void testInfopointMissingDebugInfo() {
CompilationResult result = createEmptyCompilationResult();

View File

@ -106,13 +106,12 @@ public class JvmciNotifyInstallEventTest implements HotSpotVMEventListener {
HotSpotCompilationRequest compRequest = new HotSpotCompilationRequest(method, -1, 0L);
// to pass sanity check of default -1
compResult.setTotalFrameSize(0);
compResult.close();
codeCache.installCode(compRequest, compResult, /* installedCode = */ null, /* speculationLog = */ null,
/* isDefault = */ false);
Asserts.assertEQ(gotInstallNotification, 1,
"Got unexpected event count after 1st install attempt");
// since "empty" compilation result is ok, a second attempt should be ok
compResult = new CompilationResult(METHOD_NAME); // create another instance with fresh state
compResult.setTotalFrameSize(0);
codeCache.installCode(compRequest, compResult, /* installedCode = */ null, /* speculationLog = */ null,
/* isDefault = */ false);
Asserts.assertEQ(gotInstallNotification, 2,