# HG changeset patch # User Thomas Wuerthinger # Date 1296062257 -3600 # Node ID 91fe28b03d6a86b57d62b9a9da4010d172b42dd5 # Parent 231bf6b9f5ad34b149017cee41c77e4dfd7f1185# Parent 102466e70debc4b907afbd7624e34ddb1aafee9f Merge. diff -r 102466e70deb -r 91fe28b03d6a .hgignore --- a/.hgignore Thu Jan 20 15:52:05 2011 -0800 +++ b/.hgignore Wed Jan 26 18:17:37 2011 +0100 @@ -1,6 +1,17 @@ ^build/ ^dist/ +^java/ +^work/ +.metadata/ +~$ +.swp$ +.class$ +.log$ +.orig$ +output.txt$ +output.cfg$ /nbproject/private/ +^scratch/ ^src/share/tools/hsdis/build/ ^src/share/tools/IdealGraphVisualizer/[a-zA-Z0-9]*/build/ ^src/share/tools/IdealGraphVisualizer/build/ diff -r 102466e70deb -r 91fe28b03d6a .jcheck/conf --- a/.jcheck/conf Thu Jan 20 15:52:05 2011 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -project=jdk7 diff -r 102466e70deb -r 91fe28b03d6a c1x4hotspotsrc/HotSpotVM/.checkstyle --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/c1x4hotspotsrc/HotSpotVM/.checkstyle Wed Jan 26 18:17:37 2011 +0100 @@ -0,0 +1,10 @@ + + + + + + + + + + diff -r 102466e70deb -r 91fe28b03d6a c1x4hotspotsrc/HotSpotVM/.checkstyle_checks.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/c1x4hotspotsrc/HotSpotVM/.checkstyle_checks.xml Wed Jan 26 18:17:37 2011 +0100 @@ -0,0 +1,182 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff -r 102466e70deb -r 91fe28b03d6a c1x4hotspotsrc/HotSpotVM/.classpath --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/c1x4hotspotsrc/HotSpotVM/.classpath Wed Jan 26 18:17:37 2011 +0100 @@ -0,0 +1,10 @@ + + + + + + + + + + diff -r 102466e70deb -r 91fe28b03d6a c1x4hotspotsrc/HotSpotVM/.project --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/c1x4hotspotsrc/HotSpotVM/.project Wed Jan 26 18:17:37 2011 +0100 @@ -0,0 +1,29 @@ + + + HotSpotVM + + + + + + org.eclipse.jdt.core.javabuilder + + + + + net.sourceforge.metrics.builder + + + + + net.sf.eclipsecs.core.CheckstyleBuilder + + + + + + org.eclipse.jdt.core.javanature + net.sourceforge.metrics.nature + net.sf.eclipsecs.core.CheckstyleNature + + diff -r 102466e70deb -r 91fe28b03d6a c1x4hotspotsrc/HotSpotVM/.settings/org.eclipse.jdt.core.prefs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/c1x4hotspotsrc/HotSpotVM/.settings/org.eclipse.jdt.core.prefs Wed Jan 26 18:17:37 2011 +0100 @@ -0,0 +1,384 @@ +#Sat Jan 22 17:02:08 CET 2011 +eclipse.preferences.version=1 +org.eclipse.jdt.core.builder.cleanOutputFolder=clean +org.eclipse.jdt.core.builder.duplicateResourceTask=warning +org.eclipse.jdt.core.builder.invalidClasspath=abort +org.eclipse.jdt.core.builder.resourceCopyExclusionFilter=*.launch +org.eclipse.jdt.core.circularClasspath=error +org.eclipse.jdt.core.classpath.exclusionPatterns=enabled +org.eclipse.jdt.core.classpath.multipleOutputLocations=enabled +org.eclipse.jdt.core.codeComplete.argumentPrefixes= +org.eclipse.jdt.core.codeComplete.argumentSuffixes= +org.eclipse.jdt.core.codeComplete.fieldPrefixes= +org.eclipse.jdt.core.codeComplete.fieldSuffixes= +org.eclipse.jdt.core.codeComplete.localPrefixes= +org.eclipse.jdt.core.codeComplete.localSuffixes= +org.eclipse.jdt.core.codeComplete.staticFieldPrefixes= +org.eclipse.jdt.core.codeComplete.staticFieldSuffixes= +org.eclipse.jdt.core.codeComplete.staticFinalFieldPrefixes= +org.eclipse.jdt.core.codeComplete.staticFinalFieldSuffixes= +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6 +org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve +org.eclipse.jdt.core.compiler.compliance=1.6 +org.eclipse.jdt.core.compiler.debug.lineNumber=generate +org.eclipse.jdt.core.compiler.debug.localVariable=generate +org.eclipse.jdt.core.compiler.debug.sourceFile=generate +org.eclipse.jdt.core.compiler.doc.comment.support=enabled +org.eclipse.jdt.core.compiler.maxProblemPerUnit=100 +org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.autoboxing=ignore +org.eclipse.jdt.core.compiler.problem.comparingIdentical=ignore +org.eclipse.jdt.core.compiler.problem.deadCode=ignore +org.eclipse.jdt.core.compiler.problem.deprecation=error +org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=enabled +org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=enabled +org.eclipse.jdt.core.compiler.problem.discouragedReference=warning +org.eclipse.jdt.core.compiler.problem.emptyStatement=warning +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.problem.fallthroughCase=ignore +org.eclipse.jdt.core.compiler.problem.fatalOptionalError=enabled +org.eclipse.jdt.core.compiler.problem.fieldHiding=warning +org.eclipse.jdt.core.compiler.problem.finalParameterBound=error +org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=ignore +org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning +org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning +org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning +org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=error +org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore +org.eclipse.jdt.core.compiler.problem.invalidJavadoc=ignore +org.eclipse.jdt.core.compiler.problem.invalidJavadocTags=enabled +org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsDeprecatedRef=enabled +org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsNotVisibleRef=enabled +org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsVisibility=private +org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore +org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=error +org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=error +org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=ignore +org.eclipse.jdt.core.compiler.problem.missingJavadocComments=ignore +org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsOverriding=enabled +org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsVisibility=public +org.eclipse.jdt.core.compiler.problem.missingJavadocTags=ignore +org.eclipse.jdt.core.compiler.problem.missingJavadocTagsOverriding=enabled +org.eclipse.jdt.core.compiler.problem.missingJavadocTagsVisibility=private +org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=error +org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=disabled +org.eclipse.jdt.core.compiler.problem.missingSerialVersion=ignore +org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=ignore +org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning +org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning +org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=ignore +org.eclipse.jdt.core.compiler.problem.nullReference=ignore +org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning +org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore +org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=warning +org.eclipse.jdt.core.compiler.problem.potentialNullReference=ignore +org.eclipse.jdt.core.compiler.problem.rawTypeReference=ignore +org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore +org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=ignore +org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled +org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning +org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors=disabled +org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled +org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore +org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning +org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning +org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore +org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=error +org.eclipse.jdt.core.compiler.problem.unnecessaryElse=warning +org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=ignore +org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore +org.eclipse.jdt.core.compiler.problem.unsafeTypeOperation=warning +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled +org.eclipse.jdt.core.compiler.problem.unusedImport=warning +org.eclipse.jdt.core.compiler.problem.unusedLabel=warning +org.eclipse.jdt.core.compiler.problem.unusedLocal=warning +org.eclipse.jdt.core.compiler.problem.unusedObjectAllocation=ignore +org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore +org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled +org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled +org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled +org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=ignore +org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning +org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning +org.eclipse.jdt.core.compiler.source=1.6 +org.eclipse.jdt.core.compiler.taskCaseSensitive=enabled +org.eclipse.jdt.core.compiler.taskPriorities=NORMAL,HIGH,NORMAL +org.eclipse.jdt.core.compiler.taskTags=TODO,FIXME,XXX +org.eclipse.jdt.core.formatter.align_type_members_on_columns=false +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16 +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=0 +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=0 +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16 +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16 +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16 +org.eclipse.jdt.core.formatter.alignment_for_assignment=0 +org.eclipse.jdt.core.formatter.alignment_for_binary_expression=16 +org.eclipse.jdt.core.formatter.alignment_for_compact_if=16 +org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80 +org.eclipse.jdt.core.formatter.alignment_for_enum_constants=48 +org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16 +org.eclipse.jdt.core.formatter.alignment_for_method_declaration=0 +org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16 +org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=16 +org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16 +org.eclipse.jdt.core.formatter.blank_lines_after_imports=1 +org.eclipse.jdt.core.formatter.blank_lines_after_package=1 +org.eclipse.jdt.core.formatter.blank_lines_before_field=0 +org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=1 +org.eclipse.jdt.core.formatter.blank_lines_before_imports=1 +org.eclipse.jdt.core.formatter.blank_lines_before_member_type=1 +org.eclipse.jdt.core.formatter.blank_lines_before_method=1 +org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1 +org.eclipse.jdt.core.formatter.blank_lines_before_package=0 +org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=1 +org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1 +org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_block=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line +org.eclipse.jdt.core.formatter.comment.clear_blank_lines=false +org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=false +org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=false +org.eclipse.jdt.core.formatter.comment.format_block_comments=true +org.eclipse.jdt.core.formatter.comment.format_comments=true +org.eclipse.jdt.core.formatter.comment.format_header=true +org.eclipse.jdt.core.formatter.comment.format_html=true +org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=true +org.eclipse.jdt.core.formatter.comment.format_line_comments=true +org.eclipse.jdt.core.formatter.comment.format_source_code=true +org.eclipse.jdt.core.formatter.comment.indent_parameter_description=true +org.eclipse.jdt.core.formatter.comment.indent_root_tags=true +org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert +org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=do not insert +org.eclipse.jdt.core.formatter.comment.line_length=120 +org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries=true +org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries=true +org.eclipse.jdt.core.formatter.compact_else_if=true +org.eclipse.jdt.core.formatter.continuation_indentation=4 +org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=4 +org.eclipse.jdt.core.formatter.disabling_tag=@formatter\:off +org.eclipse.jdt.core.formatter.enabling_tag=@formatter\:on +org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false +org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column=true +org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true +org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true +org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true +org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true +org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true +org.eclipse.jdt.core.formatter.indent_empty_lines=false +org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true +org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true +org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true +org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=true +org.eclipse.jdt.core.formatter.indentation.size=8 +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_member=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_after_label=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert +org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert +org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_binary_operator=insert +org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert +org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert +org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert +org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=insert +org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert +org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert +org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert +org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert +org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert +org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert +org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert +org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert +org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert +org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_binary_operator=insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=insert +org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert +org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=insert +org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert +org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert +org.eclipse.jdt.core.formatter.join_lines_in_comments=true +org.eclipse.jdt.core.formatter.join_wrapped_lines=true +org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false +org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=true +org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=false +org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false +org.eclipse.jdt.core.formatter.lineSplit=200 +org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=true +org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=true +org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0 +org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1 +org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true +org.eclipse.jdt.core.formatter.tabulation.char=space +org.eclipse.jdt.core.formatter.tabulation.size=4 +org.eclipse.jdt.core.formatter.use_on_off_tags=true +org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false +org.eclipse.jdt.core.formatter.wrap_before_binary_operator=false +org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested=true +org.eclipse.jdt.core.incompatibleJDKLevel=error +org.eclipse.jdt.core.incompleteClasspath=error diff -r 102466e70deb -r 91fe28b03d6a c1x4hotspotsrc/HotSpotVM/.settings/org.eclipse.jdt.ui.prefs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/c1x4hotspotsrc/HotSpotVM/.settings/org.eclipse.jdt.ui.prefs Wed Jan 26 18:17:37 2011 +0100 @@ -0,0 +1,75 @@ +#Fri Jul 23 17:15:05 PDT 2010 +comment_clear_blank_lines=false +comment_format_comments=true +comment_format_header=true +comment_format_html=true +comment_format_source_code=true +comment_indent_parameter_description=true +comment_indent_root_tags=true +comment_line_length=120 +comment_new_line_for_parameter=true +comment_separate_root_tags=true +eclipse.preferences.version=1 +editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true +formatter_profile=_MaxineJavaCodeStyle2 +formatter_settings_version=11 +org.eclipse.jdt.ui.exception.name=e +org.eclipse.jdt.ui.gettersetter.use.is=true +org.eclipse.jdt.ui.ignorelowercasenames=true +org.eclipse.jdt.ui.importorder=java;javax;org;com; +org.eclipse.jdt.ui.javadoc=false +org.eclipse.jdt.ui.keywordthis=false +org.eclipse.jdt.ui.ondemandthreshold=0 +org.eclipse.jdt.ui.overrideannotation=true +org.eclipse.jdt.ui.staticondemandthreshold=0 +org.eclipse.jdt.ui.text.custom_code_templates= +sp_cleanup.add_default_serial_version_id=true +sp_cleanup.add_generated_serial_version_id=false +sp_cleanup.add_missing_annotations=false +sp_cleanup.add_missing_deprecated_annotations=true +sp_cleanup.add_missing_methods=false +sp_cleanup.add_missing_nls_tags=false +sp_cleanup.add_missing_override_annotations=true +sp_cleanup.add_serial_version_id=false +sp_cleanup.always_use_blocks=true +sp_cleanup.always_use_parentheses_in_expressions=false +sp_cleanup.always_use_this_for_non_static_field_access=false +sp_cleanup.always_use_this_for_non_static_method_access=false +sp_cleanup.convert_to_enhanced_for_loop=false +sp_cleanup.correct_indentation=false +sp_cleanup.format_source_code=false +sp_cleanup.format_source_code_changes_only=false +sp_cleanup.make_local_variable_final=false +sp_cleanup.make_parameters_final=false +sp_cleanup.make_private_fields_final=true +sp_cleanup.make_variable_declarations_final=false +sp_cleanup.never_use_blocks=false +sp_cleanup.never_use_parentheses_in_expressions=true +sp_cleanup.on_save_use_additional_actions=true +sp_cleanup.organize_imports=false +sp_cleanup.qualify_static_field_accesses_with_declaring_class=false +sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true +sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true +sp_cleanup.qualify_static_member_accesses_with_declaring_class=false +sp_cleanup.qualify_static_method_accesses_with_declaring_class=false +sp_cleanup.remove_private_constructors=true +sp_cleanup.remove_trailing_whitespaces=true +sp_cleanup.remove_trailing_whitespaces_all=true +sp_cleanup.remove_trailing_whitespaces_ignore_empty=false +sp_cleanup.remove_unnecessary_casts=false +sp_cleanup.remove_unnecessary_nls_tags=false +sp_cleanup.remove_unused_imports=false +sp_cleanup.remove_unused_local_variables=false +sp_cleanup.remove_unused_private_fields=true +sp_cleanup.remove_unused_private_members=false +sp_cleanup.remove_unused_private_methods=true +sp_cleanup.remove_unused_private_types=true +sp_cleanup.sort_members=false +sp_cleanup.sort_members_all=false +sp_cleanup.use_blocks=false +sp_cleanup.use_blocks_only_for_return_and_throw=false +sp_cleanup.use_parentheses_in_expressions=false +sp_cleanup.use_this_for_non_static_field_access=false +sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true +sp_cleanup.use_this_for_non_static_method_access=false +sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true diff -r 102466e70deb -r 91fe28b03d6a c1x4hotspotsrc/HotSpotVM/README.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/c1x4hotspotsrc/HotSpotVM/README.txt Wed Jan 26 18:17:37 2011 +0100 @@ -0,0 +1,4 @@ +The classes from the projects C1X, CRI, and HotSpotVM have to be on the classpath. The classes of the HotSpotVM project have to be on the bootclasspath +Example command line arguments for HotSpot: +-XX:+UseC1X -XX:TraceC1X=5 -Xbootclasspath/a:THIS_DIRECTORY/bin;MAXINE_DIR/C1X/bin;MAXINE_DIR/CRI/bin SomeClass + diff -r 102466e70deb -r 91fe28b03d6a c1x4hotspotsrc/HotSpotVM/com_sun_hotspot_c1x_VMEntries.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/c1x4hotspotsrc/HotSpotVM/com_sun_hotspot_c1x_VMEntries.h Wed Jan 26 18:17:37 2011 +0100 @@ -0,0 +1,189 @@ +/* DO NOT EDIT THIS FILE - it is machine generated */ +#include +/* Header for class com_sun_hotspot_c1x_VMEntries */ + +#ifndef _Included_com_sun_hotspot_c1x_VMEntries +#define _Included_com_sun_hotspot_c1x_VMEntries +#ifdef __cplusplus +extern "C" { +#endif +/* + * Class: com_sun_hotspot_c1x_VMEntries + * Method: RiMethod_code + * Signature: (Ljava/lang/Object;)[B + */ +JNIEXPORT jbyteArray JNICALL Java_com_sun_hotspot_c1x_VMEntries_RiMethod_1code + (JNIEnv *, jclass, jobject); + +/* + * Class: com_sun_hotspot_c1x_VMEntries + * Method: RiMethod_maxStackSize + * Signature: (Ljava/lang/Object;)I + */ +JNIEXPORT jint JNICALL Java_com_sun_hotspot_c1x_VMEntries_RiMethod_1maxStackSize + (JNIEnv *, jclass, jobject); + +/* + * Class: com_sun_hotspot_c1x_VMEntries + * Method: RiMethod_maxLocals + * Signature: (Ljava/lang/Object;)I + */ +JNIEXPORT jint JNICALL Java_com_sun_hotspot_c1x_VMEntries_RiMethod_1maxLocals + (JNIEnv *, jclass, jobject); + +/* + * Class: com_sun_hotspot_c1x_VMEntries + * Method: RiMethod_holder + * Signature: (Ljava/lang/Object;)Lcom/sun/cri/ri/RiType; + */ +JNIEXPORT jobject JNICALL Java_com_sun_hotspot_c1x_VMEntries_RiMethod_1holder + (JNIEnv *, jclass, jobject); + +/* + * Class: com_sun_hotspot_c1x_VMEntries + * Method: RiMethod_signature + * Signature: (Ljava/lang/Object;)Ljava/lang/String; + */ +JNIEXPORT jstring JNICALL Java_com_sun_hotspot_c1x_VMEntries_RiMethod_1signature + (JNIEnv *, jclass, jobject); + +/* + * Class: com_sun_hotspot_c1x_VMEntries + * Method: RiMethod_name + * Signature: (Ljava/lang/Object;)Ljava/lang/String; + */ +JNIEXPORT jstring JNICALL Java_com_sun_hotspot_c1x_VMEntries_RiMethod_1name + (JNIEnv *, jclass, jobject); + +/* + * Class: com_sun_hotspot_c1x_VMEntries + * Method: RiSignature_lookupType + * Signature: (Ljava/lang/String;Ljava/lang/Object;)Lcom/sun/cri/ri/RiType; + */ +JNIEXPORT jobject JNICALL Java_com_sun_hotspot_c1x_VMEntries_RiSignature_1lookupType + (JNIEnv *, jclass, jstring, jobject); + +/* + * Class: com_sun_hotspot_c1x_VMEntries + * Method: RiSignature_symbolToString + * Signature: (Ljava/lang/Object;)Ljava/lang/String; + */ +JNIEXPORT jstring JNICALL Java_com_sun_hotspot_c1x_VMEntries_RiSignature_1symbolToString + (JNIEnv *, jclass, jobject); + +/* + * Class: com_sun_hotspot_c1x_VMEntries + * Method: RiType_javaClass + * Signature: (Ljava/lang/Object;)Ljava/lang/Class; + */ +JNIEXPORT jclass JNICALL Java_com_sun_hotspot_c1x_VMEntries_RiType_1javaClass + (JNIEnv *, jclass, jobject); + +/* + * Class: com_sun_hotspot_c1x_VMEntries + * Method: RiType_name + * Signature: (Ljava/lang/Object;)Ljava/lang/String; + */ +JNIEXPORT jstring JNICALL Java_com_sun_hotspot_c1x_VMEntries_RiType_1name + (JNIEnv *, jclass, jobject); + +/* + * Class: com_sun_hotspot_c1x_VMEntries + * Method: RiConstantPool_lookupConstant + * Signature: (Ljava/lang/Object;I)Ljava/lang/Object; + */ +JNIEXPORT jobject JNICALL Java_com_sun_hotspot_c1x_VMEntries_RiConstantPool_1lookupConstant + (JNIEnv *, jclass, jobject, jint); + +/* + * Class: com_sun_hotspot_c1x_VMEntries + * Method: RiConstantPool_lookupMethod + * Signature: (Ljava/lang/Object;IB)Lcom/sun/cri/ri/RiMethod; + */ +JNIEXPORT jobject JNICALL Java_com_sun_hotspot_c1x_VMEntries_RiConstantPool_1lookupMethod + (JNIEnv *, jclass, jobject, jint, jbyte); + +/* + * Class: com_sun_hotspot_c1x_VMEntries + * Method: RiConstantPool_lookupSignature + * Signature: (Ljava/lang/Object;I)Lcom/sun/cri/ri/RiSignature; + */ +JNIEXPORT jobject JNICALL Java_com_sun_hotspot_c1x_VMEntries_RiConstantPool_1lookupSignature + (JNIEnv *, jclass, jobject, jint); + +/* + * Class: com_sun_hotspot_c1x_VMEntries + * Method: RiConstantPool_lookupType + * Signature: (Ljava/lang/Object;I)Lcom/sun/cri/ri/RiType; + */ +JNIEXPORT jobject JNICALL Java_com_sun_hotspot_c1x_VMEntries_RiConstantPool_1lookupType + (JNIEnv *, jclass, jobject, jint); + +/* + * Class: com_sun_hotspot_c1x_VMEntries + * Method: RiConstantPool_lookupField + * Signature: (Ljava/lang/Object;I)Lcom/sun/cri/ri/RiField; + */ +JNIEXPORT jobject JNICALL Java_com_sun_hotspot_c1x_VMEntries_RiConstantPool_1lookupField + (JNIEnv *, jclass, jobject, jint); + +/* + * Class: com_sun_hotspot_c1x_VMEntries + * Method: findRiType + * Signature: (Ljava/lang/Object;)Lcom/sun/cri/ri/RiType; + */ +JNIEXPORT jobject JNICALL Java_com_sun_hotspot_c1x_VMEntries_findRiType + (JNIEnv *, jclass, jobject); + +/* + * Class: com_sun_hotspot_c1x_VMEntries + * Method: RiRuntime_getConstantPool + * Signature: (Ljava/lang/Object;)Lcom/sun/cri/ri/RiConstantPool; + */ +JNIEXPORT jobject JNICALL Java_com_sun_hotspot_c1x_VMEntries_RiRuntime_1getConstantPool + (JNIEnv *, jclass, jobject); + +/* + * Class: com_sun_hotspot_c1x_VMEntries + * Method: RiType_isArrayClass + * Signature: (Ljava/lang/Object;)Z + */ +JNIEXPORT jboolean JNICALL Java_com_sun_hotspot_c1x_VMEntries_RiType_1isArrayClass + (JNIEnv *, jclass, jobject); + +/* + * Class: com_sun_hotspot_c1x_VMEntries + * Method: RiType_isInstanceClass + * Signature: (Ljava/lang/Object;)Z + */ +JNIEXPORT jboolean JNICALL Java_com_sun_hotspot_c1x_VMEntries_RiType_1isInstanceClass + (JNIEnv *, jclass, jobject); + +/* + * Class: com_sun_hotspot_c1x_VMEntries + * Method: RiType_isInterface + * Signature: (Ljava/lang/Object;)Z + */ +JNIEXPORT jboolean JNICALL Java_com_sun_hotspot_c1x_VMEntries_RiType_1isInterface + (JNIEnv *, jclass, jobject); + +/* + * Class: com_sun_hotspot_c1x_VMEntries + * Method: RiMethod_accessFlags + * Signature: (Ljava/lang/Object;)I + */ +JNIEXPORT jint JNICALL Java_com_sun_hotspot_c1x_VMEntries_RiMethod_1accessFlags + (JNIEnv *, jclass, jobject); + +/* + * Class: com_sun_hotspot_c1x_VMEntries + * Method: installCode + * Signature: (Ljava/lang/Object;[BI)V + */ +JNIEXPORT void JNICALL Java_com_sun_hotspot_c1x_VMEntries_installCode + (JNIEnv *, jclass, jobject, jbyteArray, jint); + +#ifdef __cplusplus +} +#endif +#endif diff -r 102466e70deb -r 91fe28b03d6a c1x4hotspotsrc/HotSpotVM/create_native_header.bat --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/c1x4hotspotsrc/HotSpotVM/create_native_header.bat Wed Jan 26 18:17:37 2011 +0100 @@ -0,0 +1,1 @@ +javah -classpath c1x4hotspot.jar com.sun.hotspot.c1x.VMEntries \ No newline at end of file diff -r 102466e70deb -r 91fe28b03d6a c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/Compiler.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/Compiler.java Wed Jan 26 18:17:37 2011 +0100 @@ -0,0 +1,217 @@ +/* + * Copyright (c) 2010 Sun Microsystems, Inc. All rights reserved. + * + * Sun Microsystems, Inc. has intellectual property rights relating to technology embodied in the product + * that is described in this document. In particular, and without limitation, these intellectual property + * rights may include one or more of the U.S. patents listed at http://www.sun.com/patents and one or + * more additional patents or pending patent applications in the U.S. and in other countries. + * + * U.S. Government Rights - Commercial software. Government users are subject to the Sun + * Microsystems, Inc. standard license agreement and applicable provisions of the FAR and its + * supplements. + * + * Use is subject to license terms. Sun, Sun Microsystems, the Sun logo, Java and Solaris are trademarks or + * registered trademarks of Sun Microsystems, Inc. in the U.S. and other countries. All SPARC trademarks + * are used under license and are trademarks or registered trademarks of SPARC International, Inc. in the + * U.S. and other countries. + * + * UNIX is a registered trademark in the U.S. and other countries, exclusively licensed through X/Open + * Company, Ltd. + */ +package com.sun.hotspot.c1x; + +import java.lang.management.*; +import java.lang.reflect.Proxy; +import java.net.*; + +import com.sun.c1x.*; +import com.sun.c1x.target.amd64.*; +import com.sun.cri.ci.*; +import com.sun.cri.ri.*; +import com.sun.cri.xir.*; +import com.sun.hotspot.c1x.logging.*; +import com.sun.hotspot.c1x.server.CompilationServer.ReplacingInputStream; +import com.sun.hotspot.c1x.server.CompilationServer.ReplacingOutputStream; + +/** + * Singleton class holding the instance of the C1XCompiler. + * + * @author Thomas Wuerthinger, Lukas Stadler + */ +public final class Compiler { + + private static Compiler theInstance; + private static boolean PrintGCStats = false; + + public static Compiler getInstance() { + if (theInstance == null) { + theInstance = new Compiler(); + Runtime.getRuntime().addShutdownHook(new ShutdownThread()); + } + return theInstance; + } + + private static VMEntries vmEntries; + + + public static class ShutdownThread extends Thread { + @Override + public void run() { + VMExitsNative.compileMethods = false; + if (C1XOptions.PrintMetrics) { + C1XMetrics.print(); + } + if (C1XOptions.PrintTimers) { + C1XTimers.print(); + } + + if (PrintGCStats) { + printGCStats(); + } + } + } + + public static void printGCStats() { + long totalGarbageCollections = 0; + long garbageCollectionTime = 0; + + for (GarbageCollectorMXBean gc : ManagementFactory.getGarbageCollectorMXBeans()) { + long count = gc.getCollectionCount(); + if (count >= 0) { + totalGarbageCollections += count; + } + + long time = gc.getCollectionTime(); + if (time >= 0) { + garbageCollectionTime += time; + } + } + + System.out.println("Total Garbage Collections: " + totalGarbageCollections); + System.out.println("Total Garbage Collection Time (ms): " + garbageCollectionTime); + } + + public static VMExits initializeServer(VMEntries entries) { + if (Logger.ENABLED) { + vmEntries = LoggingProxy.getProxy(VMEntries.class, entries); + vmExits = LoggingProxy.getProxy(VMExits.class, new VMExitsNative()); + } else { + vmEntries = entries; + vmExits = new VMExitsNative(); + } + return vmExits; + } + + private static VMEntries initializeClient(VMExits exits) { + vmEntries = new VMEntriesNative(); + vmExits = exits; + return vmEntries; + } + + public static VMEntries getVMEntries() { + if (vmEntries == null) { + try { + vmEntries = new VMEntriesNative(); + if (CountingProxy.ENABLED) { + vmEntries = CountingProxy.getProxy(VMEntries.class, vmEntries); + } + if (Logger.ENABLED) { + vmEntries = LoggingProxy.getProxy(VMEntries.class, vmEntries); + } + } catch (Throwable t) { + t.printStackTrace(); + } + } + return vmEntries; + } + + private static VMExits vmExits; + + public static VMExits getVMExits() { + if (vmExits == null) { + String remote = System.getProperty("c1x.remote"); + assert theInstance == null; + assert vmEntries == null; + try { + if (remote != null) { + System.out.println("C1X compiler started in client/server mode, connection to server " + remote); + Socket socket = new Socket(remote, 1199); + ReplacingOutputStream output = new ReplacingOutputStream(socket.getOutputStream()); + ReplacingInputStream input = new ReplacingInputStream(socket.getInputStream()); + + InvocationSocket invocation = new InvocationSocket(output, input); + VMExits exits = (VMExits) Proxy.newProxyInstance(VMExits.class.getClassLoader(), new Class[] {VMExits.class}, invocation); + VMEntries entries = Compiler.initializeClient(exits); + invocation.setDelegate(entries); + } else { + vmExits = new VMExitsNative(); + if (CountingProxy.ENABLED) { + vmExits = CountingProxy.getProxy(VMExits.class, vmExits); + } + if (Logger.ENABLED) { + vmExits = LoggingProxy.getProxy(VMExits.class, vmExits); + } + } + } catch (Throwable t) { + t.printStackTrace(); + } + } + return vmExits; + } + + private final CiCompiler compiler; + private final HotSpotVMConfig config; + private final HotSpotRuntime runtime; + private final HotSpotRegisterConfig registerConfig; + private final CiTarget target; + private final RiXirGenerator generator; + + private Compiler() { + config = getVMEntries().getConfiguration(); + config.check(); + + runtime = new HotSpotRuntime(config); + final int wordSize = 8; + final int stackFrameAlignment = 16; + registerConfig = runtime.globalStubRegConfig; + target = new HotSpotTarget(new AMD64(), true, wordSize, stackFrameAlignment, config.vmPageSize, wordSize, true); + + if (Logger.ENABLED) { + generator = LoggingProxy.getProxy(RiXirGenerator.class, new HotSpotXirGenerator(config, target, registerConfig)); + } else { + generator = new HotSpotXirGenerator(config, target, registerConfig); + } + compiler = new C1XCompiler(runtime, target, generator, registerConfig); + + // these options are important - c1x4hotspot will not generate correct code without them + C1XOptions.GenSpecialDivChecks = true; + C1XOptions.NullCheckUniquePc = true; + C1XOptions.InvokeSnippetAfterArguments = true; + C1XOptions.StackShadowPages = config.stackShadowPages; + } + + public CiCompiler getCompiler() { + return compiler; + } + + public HotSpotVMConfig getConfig() { + return config; + } + + public HotSpotRuntime getRuntime() { + return runtime; + } + + public RiRegisterConfig getRegisterConfig() { + return registerConfig; + } + + public CiTarget getTarget() { + return target; + } + + public RiXirGenerator getGenerator() { + return generator; + } + +} diff -r 102466e70deb -r 91fe28b03d6a c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/CompilerObject.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/CompilerObject.java Wed Jan 26 18:17:37 2011 +0100 @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2010 Sun Microsystems, Inc. All rights reserved. + * + * Sun Microsystems, Inc. has intellectual property rights relating to technology embodied in the product + * that is described in this document. In particular, and without limitation, these intellectual property + * rights may include one or more of the U.S. patents listed at http://www.sun.com/patents and one or + * more additional patents or pending patent applications in the U.S. and in other countries. + * + * U.S. Government Rights - Commercial software. Government users are subject to the Sun + * Microsystems, Inc. standard license agreement and applicable provisions of the FAR and its + * supplements. + * + * Use is subject to license terms. Sun, Sun Microsystems, the Sun logo, Java and Solaris are trademarks or + * registered trademarks of Sun Microsystems, Inc. in the U.S. and other countries. All SPARC trademarks + * are used under license and are trademarks or registered trademarks of SPARC International, Inc. in the + * U.S. and other countries. + * + * UNIX is a registered trademark in the U.S. and other countries, exclusively licensed through X/Open + * Company, Ltd. + */ +package com.sun.hotspot.c1x; + +import java.io.*; + + +/** + * Parent class for all HotSpot Ri... types. + * + * @author Lukas Stadler + */ +public abstract class CompilerObject implements Serializable { +} diff -r 102466e70deb -r 91fe28b03d6a c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/HotSpotConstantPool.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/HotSpotConstantPool.java Wed Jan 26 18:17:37 2011 +0100 @@ -0,0 +1,144 @@ +/* + * Copyright (c) 2010 Sun Microsystems, Inc. All rights reserved. + * + * Sun Microsystems, Inc. has intellectual property rights relating to technology embodied in the product + * that is described in this document. In particular, and without limitation, these intellectual property + * rights may include one or more of the U.S. patents listed at http://www.sun.com/patents and one or + * more additional patents or pending patent applications in the U.S. and in other countries. + * + * U.S. Government Rights - Commercial software. Government users are subject to the Sun + * Microsystems, Inc. standard license agreement and applicable provisions of the FAR and its + * supplements. + * + * Use is subject to license terms. Sun, Sun Microsystems, the Sun logo, Java and Solaris are trademarks or + * registered trademarks of Sun Microsystems, Inc. in the U.S. and other countries. All SPARC trademarks + * are used under license and are trademarks or registered trademarks of SPARC International, Inc. in the + * U.S. and other countries. + * + * UNIX is a registered trademark in the U.S. and other countries, exclusively licensed through X/Open + * Company, Ltd. + */ +package com.sun.hotspot.c1x; + +import java.lang.reflect.*; +import java.util.*; + +import com.sun.cri.ri.*; + +/** + * Implementation of RiConstantPool for HotSpot. + * + * @author Thomas Wuerthinger, Lukas Stadler + */ +public class HotSpotConstantPool extends CompilerObject implements RiConstantPool { + + private final long vmId; + + private final FastLRUIntCache methodCache = new FastLRUIntCache(); + private final FastLRUIntCache fieldCache = new FastLRUIntCache(); + private final FastLRUIntCache typeCache = new FastLRUIntCache(); + + public static class FastLRUIntCache { + + private static final int InitialCapacity = 4; + private int lastKey; + private T lastObject; + + private int[] keys; + private Object[] objects; + private int count; + + @SuppressWarnings("unchecked") + private T access(int index) { + return (T) objects[index]; + } + + public T get(int key) { + if (key == lastKey) { + return lastObject; + } else if (count > 1) { + for (int i = 0; i < count; ++i) { + if (keys[i] == key) { + lastObject = access(i); + lastKey = key; + return lastObject; + } + } + } + return null; + } + + public void add(int key, T object) { + count++; + if (count == 1) { + lastKey = key; + lastObject = object; + } else { + ensureSize(); + keys[count - 1] = key; + objects[count - 1] = object; + if (count == 2) { + keys[0] = lastKey; + objects[0] = lastObject; + } + lastKey = key; + lastObject = object; + } + } + + private void ensureSize() { + if (keys == null) { + keys = new int[InitialCapacity]; + objects = new Object[InitialCapacity]; + } else if (count > keys.length) { + keys = Arrays.copyOf(keys, keys.length * 2); + objects = Arrays.copyOf(objects, objects.length * 2); + } + } + } + + public HotSpotConstantPool(long vmId) { + this.vmId = vmId; + } + + @Override + public Object lookupConstant(int cpi) { + Object constant = Compiler.getVMEntries().RiConstantPool_lookupConstant(vmId, cpi); + return constant; + } + + @Override + public RiSignature lookupSignature(int cpi) { + return Compiler.getVMEntries().RiConstantPool_lookupSignature(vmId, cpi); + } + + @Override + public RiMethod lookupMethod(int cpi, int byteCode) { + RiMethod result = methodCache.get(cpi); + if (result == null) { + result = Compiler.getVMEntries().RiConstantPool_lookupMethod(vmId, cpi, (byte) byteCode); + methodCache.add(cpi, result); + } + return result; + } + + @Override + public RiType lookupType(int cpi, int opcode) { + RiType result = typeCache.get(cpi); + if (result == null) { + result = Compiler.getVMEntries().RiConstantPool_lookupType(vmId, cpi); + typeCache.add(cpi, result); + } + return result; + } + + @Override + public RiField lookupField(int cpi, int opcode) { + RiField result = fieldCache.get(cpi); + if (result == null) { + result = Compiler.getVMEntries().RiConstantPool_lookupField(vmId, cpi, (byte) opcode); + fieldCache.add(cpi, result); + } + return result; + } +} diff -r 102466e70deb -r 91fe28b03d6a c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/HotSpotExceptionHandler.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/HotSpotExceptionHandler.java Wed Jan 26 18:17:37 2011 +0100 @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2010 Sun Microsystems, Inc. All rights reserved. + * + * Sun Microsystems, Inc. has intellectual property rights relating to technology embodied in the product + * that is described in this document. In particular, and without limitation, these intellectual property + * rights may include one or more of the U.S. patents listed at http://www.sun.com/patents and one or + * more additional patents or pending patent applications in the U.S. and in other countries. + * + * U.S. Government Rights - Commercial software. Government users are subject to the Sun + * Microsystems, Inc. standard license agreement and applicable provisions of the FAR and its + * supplements. + * + * Use is subject to license terms. Sun, Sun Microsystems, the Sun logo, Java and Solaris are trademarks or + * registered trademarks of Sun Microsystems, Inc. in the U.S. and other countries. All SPARC trademarks + * are used under license and are trademarks or registered trademarks of SPARC International, Inc. in the + * U.S. and other countries. + * + * UNIX is a registered trademark in the U.S. and other countries, exclusively licensed through X/Open + * Company, Ltd. + */ +package com.sun.hotspot.c1x; + +import com.sun.cri.ri.*; + + +public class HotSpotExceptionHandler extends CompilerObject implements RiExceptionHandler { + private int startBci; + private int endBci; + private int handlerBci; + private int catchClassIndex; + private RiType catchClass; + + @Override + public int startBCI() { + return startBci; + } + + @Override + public int endBCI() { + return endBci; + } + + @Override + public int handlerBCI() { + return handlerBci; + } + + @Override + public int catchClassIndex() { + return catchClassIndex; + } + + @Override + public boolean isCatchAll() { + return catchClassIndex == 0; + } + + @Override + public RiType catchKlass() { + return catchClass; + } + +} diff -r 102466e70deb -r 91fe28b03d6a c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/HotSpotField.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/HotSpotField.java Wed Jan 26 18:17:37 2011 +0100 @@ -0,0 +1,134 @@ +/* + * Copyright (c) 2010 Sun Microsystems, Inc. All rights reserved. + * + * Sun Microsystems, Inc. has intellectual property rights relating to technology embodied in the product + * that is described in this document. In particular, and without limitation, these intellectual property + * rights may include one or more of the U.S. patents listed at http://www.sun.com/patents and one or + * more additional patents or pending patent applications in the U.S. and in other countries. + * + * U.S. Government Rights - Commercial software. Government users are subject to the Sun + * Microsystems, Inc. standard license agreement and applicable provisions of the FAR and its + * supplements. + * + * Use is subject to license terms. Sun, Sun Microsystems, the Sun logo, Java and Solaris are trademarks or + * registered trademarks of Sun Microsystems, Inc. in the U.S. and other countries. All SPARC trademarks + * are used under license and are trademarks or registered trademarks of SPARC International, Inc. in the + * U.S. and other countries. + * + * UNIX is a registered trademark in the U.S. and other countries, exclusively licensed through X/Open + * Company, Ltd. + */ + +package com.sun.hotspot.c1x; + +import java.lang.reflect.*; + +import com.sun.c1x.*; +import com.sun.cri.ci.CiConstant; +import com.sun.cri.ci.CiKind; +import com.sun.cri.ri.RiField; +import com.sun.cri.ri.RiType; + +/** + * Represents a field in a HotSpot type. + * + * @author Thomas Wuerthinger, Lukas Stadler + */ +public class HotSpotField extends CompilerObject implements RiField { + + private final RiType holder; + private final String name; + private final RiType type; + private final int offset; + private CiConstant constant; + + public HotSpotField(RiType holder, String name, RiType type, int offset) { + this.holder = holder; + this.name = name; + this.type = type; + this.offset = offset; + } + + @Override + public int accessFlags() { + // TODO Auto-generated method stub + return 0; + } + + @Override + public CiConstant constantValue(Object object) { + if (object == null) { + if (constant == null && holder.isResolved() && holder.javaClass() == C1XOptions.class) { + Field f; + try { + f = C1XOptions.class.getField(name); + } catch (SecurityException e1) { + return null; + } catch (NoSuchFieldException e1) { + return null; + } + f.setAccessible(true); + if (Modifier.isStatic(f.getModifiers())) { + CiKind kind = CiKind.fromJavaClass(f.getType()); + Object value; + try { + value = f.get(null); + } catch (IllegalArgumentException e) { + return null; + } catch (IllegalAccessException e) { + return null; + } + constant = CiConstant.forBoxed(kind, value); + } + } + + // Constant part only valid for static fields. + return constant; + } + return null; + } + + @Override + public RiType holder() { + return holder; + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof HotSpotField) { + HotSpotField other = (HotSpotField) obj; + return other.offset == offset && other.holder.equals(holder()); + } + return false; + } + + @Override + public boolean isResolved() { + return offset != -1; + } + + @Override + public CiKind kind() { + return type().kind(); + } + + @Override + public String name() { + return name; + } + + @Override + public RiType type() { + return type; + } + + public int offset() { + return offset; + } + + @Override + public String toString() { + return "HotSpotField<" + holder.name() + "." + name + ">"; + } + +} diff -r 102466e70deb -r 91fe28b03d6a c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/HotSpotMethod.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/HotSpotMethod.java Wed Jan 26 18:17:37 2011 +0100 @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2010 Sun Microsystems, Inc. All rights reserved. + * + * Sun Microsystems, Inc. has intellectual property rights relating to technology embodied in the product + * that is described in this document. In particular, and without limitation, these intellectual property + * rights may include one or more of the U.S. patents listed at http://www.sun.com/patents and one or + * more additional patents or pending patent applications in the U.S. and in other countries. + * + * U.S. Government Rights - Commercial software. Government users are subject to the Sun + * Microsystems, Inc. standard license agreement and applicable provisions of the FAR and its + * supplements. + * + * Use is subject to license terms. Sun, Sun Microsystems, the Sun logo, Java and Solaris are trademarks or + * registered trademarks of Sun Microsystems, Inc. in the U.S. and other countries. All SPARC trademarks + * are used under license and are trademarks or registered trademarks of SPARC International, Inc. in the + * U.S. and other countries. + * + * UNIX is a registered trademark in the U.S. and other countries, exclusively licensed through X/Open + * Company, Ltd. + */ +package com.sun.hotspot.c1x; + +import com.sun.cri.ri.*; + + +public abstract class HotSpotMethod extends CompilerObject implements RiMethod { + + protected RiType holder; + protected String name; + + @Override + public final RiType holder() { + return holder; + } + + @Override + public final String name() { + return name; + } +} diff -r 102466e70deb -r 91fe28b03d6a c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/HotSpotMethodResolved.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/HotSpotMethodResolved.java Wed Jan 26 18:17:37 2011 +0100 @@ -0,0 +1,182 @@ +/* + * Copyright (c) 2010 Sun Microsystems, Inc. All rights reserved. + * + * Sun Microsystems, Inc. has intellectual property rights relating to technology embodied in the product + * that is described in this document. In particular, and without limitation, these intellectual property + * rights may include one or more of the U.S. patents listed at http://www.sun.com/patents and one or + * more additional patents or pending patent applications in the U.S. and in other countries. + * + * U.S. Government Rights - Commercial software. Government users are subject to the Sun + * Microsystems, Inc. standard license agreement and applicable provisions of the FAR and its + * supplements. + * + * Use is subject to license terms. Sun, Sun Microsystems, the Sun logo, Java and Solaris are trademarks or + * registered trademarks of Sun Microsystems, Inc. in the U.S. and other countries. All SPARC trademarks + * are used under license and are trademarks or registered trademarks of SPARC International, Inc. in the + * U.S. and other countries. + * + * UNIX is a registered trademark in the U.S. and other countries, exclusively licensed through X/Open + * Company, Ltd. + */ +package com.sun.hotspot.c1x; + +import java.lang.reflect.*; + +import com.sun.cri.ci.*; +import com.sun.cri.ri.*; + +/** + * Implementation of RiMethod for resolved HotSpot methods. + * + * @author Thomas Wuerthinger, Lukas Stadler + */ +public final class HotSpotMethodResolved extends HotSpotMethod { + + private final long vmId; + + // cached values + private byte[] code; + private int accessFlags = -1; + private int maxLocals = -1; + private int maxStackSize = -1; + private RiExceptionHandler[] exceptionHandlers; + private RiSignature signature; + private Boolean hasBalancedMonitors; + + public HotSpotMethodResolved(long vmId, String name) { + this.vmId = vmId; + this.name = name; + this.holder = Compiler.getVMEntries().RiMethod_holder(vmId); + } + + @Override + public int accessFlags() { + if (accessFlags == -1) { + accessFlags = Compiler.getVMEntries().RiMethod_accessFlags(vmId); + } + return accessFlags; + } + + @Override + public boolean canBeStaticallyBound() { + return isLeafMethod() || Modifier.isStatic(accessFlags()); + } + + @Override + public byte[] code() { + if (code == null) { + code = Compiler.getVMEntries().RiMethod_code(vmId); + } + return code; + } + + @Override + public RiExceptionHandler[] exceptionHandlers() { + if (exceptionHandlers == null) { + exceptionHandlers = Compiler.getVMEntries().RiMethod_exceptionHandlers(vmId); + } + return exceptionHandlers; + } + + @Override + public boolean hasBalancedMonitors() { + if (hasBalancedMonitors == null) { + hasBalancedMonitors = Compiler.getVMEntries().RiMethod_hasBalancedMonitors(vmId); + } + return hasBalancedMonitors; + } + + @Override + public boolean isClassInitializer() { + return "".equals(name); + } + + @Override + public boolean isConstructor() { + return "".equals(name); + } + + @Override + public boolean isLeafMethod() { + return Modifier.isFinal(accessFlags()) || Modifier.isPrivate(accessFlags()); + } + + @Override + public boolean isOverridden() { + throw new UnsupportedOperationException("isOverridden"); + } + + @Override + public boolean isResolved() { + return true; + } + + @Override + public String jniSymbol() { + throw new UnsupportedOperationException("jniSymbol"); + } + + public CiBitMap[] livenessMap() { + return null; + } + + @Override + public int maxLocals() { + if (maxLocals == -1) { + maxLocals = Compiler.getVMEntries().RiMethod_maxLocals(vmId); + } + return maxLocals; + } + + @Override + public int maxStackSize() { + if (maxStackSize == -1) { + maxStackSize = Compiler.getVMEntries().RiMethod_maxStackSize(vmId); + } + return maxStackSize; + } + + @Override + public RiMethodProfile methodData() { + return null; + } + + @Override + public StackTraceElement toStackTraceElement(int bci) { + return CiUtil.toStackTraceElement(this, bci); + } + + @Override + public RiMethod uniqueConcreteMethod() { + return Compiler.getVMEntries().RiMethod_uniqueConcreteMethod(vmId); + } + + @Override + public RiSignature signature() { + if (signature == null) { + signature = new HotSpotSignature(Compiler.getVMEntries().RiMethod_signature(vmId)); + } + return signature; + } + + @Override + public String toString() { + return "HotSpotMethod<" + holder().name() + ". " + name + ">"; + } + + public boolean hasCompiledCode() { + // TODO: needs a VMEntries to go cache the result of that method. + // This isn't used by GRAAL for now, so this is enough. + return false; + } + + @Override + public Class accessor() { + return null; + } + + @Override + public int intrinsic() { + return 0; + } +} diff -r 102466e70deb -r 91fe28b03d6a c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/HotSpotMethodUnresolved.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/HotSpotMethodUnresolved.java Wed Jan 26 18:17:37 2011 +0100 @@ -0,0 +1,152 @@ +/* + * Copyright (c) 2010 Sun Microsystems, Inc. All rights reserved. + * + * Sun Microsystems, Inc. has intellectual property rights relating to technology embodied in the product + * that is described in this document. In particular, and without limitation, these intellectual property + * rights may include one or more of the U.S. patents listed at http://www.sun.com/patents and one or + * more additional patents or pending patent applications in the U.S. and in other countries. + * + * U.S. Government Rights - Commercial software. Government users are subject to the Sun + * Microsystems, Inc. standard license agreement and applicable provisions of the FAR and its + * supplements. + * + * Use is subject to license terms. Sun, Sun Microsystems, the Sun logo, Java and Solaris are trademarks or + * registered trademarks of Sun Microsystems, Inc. in the U.S. and other countries. All SPARC trademarks + * are used under license and are trademarks or registered trademarks of SPARC International, Inc. in the + * U.S. and other countries. + * + * UNIX is a registered trademark in the U.S. and other countries, exclusively licensed through X/Open + * Company, Ltd. + */ +package com.sun.hotspot.c1x; + +import com.sun.cri.ci.*; +import com.sun.cri.ri.*; + +/** + * Implementation of RiMethod for unresolved HotSpot methods. + * + * @author Lukas Stadler + */ +public final class HotSpotMethodUnresolved extends HotSpotMethod { + private final RiSignature signature; + + public HotSpotMethodUnresolved(String name, String signature, RiType holder) { + this.name = name; + this.holder = holder; + this.signature = new HotSpotSignature(signature); + } + + @Override + public RiSignature signature() { + return signature; + } + + @Override + public boolean isResolved() { + return false; + } + + @Override + public byte[] code() { + throw unresolved("code"); + } + + @Override + public RiMethodProfile methodData() { + throw unresolved("methodData"); + } + + @Override + public String jniSymbol() { + throw unresolved("jniSymbol"); + } + + @Override + public int maxLocals() { + throw unresolved("maxLocals"); + } + + @Override + public int maxStackSize() { + throw unresolved("maxStackSize"); + } + + @Override + public boolean hasBalancedMonitors() { + throw unresolved("hasBalancedMonitors"); + } + + @Override + public RiMethod uniqueConcreteMethod() { + throw unresolved("uniqueConcreteMethod()"); + } + + @Override + public int accessFlags() { + throw unresolved("accessFlags"); + } + + @Override + public boolean isLeafMethod() { + throw unresolved("isLeafMethod"); + } + + @Override + public boolean isClassInitializer() { + return "".equals(name); + } + + @Override + public boolean isConstructor() { + return "".equals(name); + } + + @Override + public boolean isOverridden() { + throw unresolved("isOverridden"); + } + + @Override + public CiBitMap[] livenessMap() { + return null; + } + + @Override + public StackTraceElement toStackTraceElement(int bci) { + return CiUtil.toStackTraceElement(this, bci); + } + + @Override + public boolean canBeStaticallyBound() { + throw unresolved("canBeStaticallyBound"); + } + + @Override + public RiExceptionHandler[] exceptionHandlers() { + throw unresolved("exceptionHandlers"); + } + + private CiUnresolvedException unresolved(String operation) { + return new CiUnresolvedException(operation + " not defined for unresolved method " + name); + } + + @Override + public String toString() { + return "HotSpotMethod<" + holder.name() + ". " + name + ", unresolved>"; + } + + public boolean hasCompiledCode() { + return false; + } + + @Override + public Class accessor() { + return null; + } + + @Override + public int intrinsic() { + return 0; + } +} diff -r 102466e70deb -r 91fe28b03d6a c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/HotSpotProxy.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/HotSpotProxy.java Wed Jan 26 18:17:37 2011 +0100 @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2010 Sun Microsystems, Inc. All rights reserved. + * + * Sun Microsystems, Inc. has intellectual property rights relating to technology embodied in the product + * that is described in this document. In particular, and without limitation, these intellectual property + * rights may include one or more of the U.S. patents listed at http://www.sun.com/patents and one or + * more additional patents or pending patent applications in the U.S. and in other countries. + * + * U.S. Government Rights - Commercial software. Government users are subject to the Sun + * Microsystems, Inc. standard license agreement and applicable provisions of the FAR and its + * supplements. + * + * Use is subject to license terms. Sun, Sun Microsystems, the Sun logo, Java and Solaris are trademarks or + * registered trademarks of Sun Microsystems, Inc. in the U.S. and other countries. All SPARC trademarks + * are used under license and are trademarks or registered trademarks of SPARC International, Inc. in the + * U.S. and other countries. + * + * UNIX is a registered trademark in the U.S. and other countries, exclusively licensed through X/Open + * Company, Ltd. + */ +package com.sun.hotspot.c1x; + +/** + * Provides methods to classify the HotSpot-internal identifiers. + * + * @author Lukas Stadler + */ +public final class HotSpotProxy { + + private HotSpotProxy() { + } + + private enum CompilerObjectType { + // this enum needs to have the same values as the one in c1x_Compiler.hpp + STUB(0x100000000000000L), + METHOD(0x200000000000000L), + CLASS(0x300000000000000L), + SYMBOL(0x400000000000000L), + CONSTANT_POOL(0x500000000000000L), + CONSTANT(0x600000000000000L), + TYPE_MASK(0xf00000000000000L), + DUMMY_CONSTANT(0x6ffffffffffffffL); + + public final long bits; + + CompilerObjectType(long bits) { + this.bits = bits; + } + } + + public static final Long DUMMY_CONSTANT_OBJ = CompilerObjectType.DUMMY_CONSTANT.bits; + + private static boolean isType(long id, CompilerObjectType type) { + return (id & CompilerObjectType.TYPE_MASK.bits) == type.bits; + } + + public static boolean isStub(long id) { + return isType(id, CompilerObjectType.STUB); + } + + public static boolean isMethod(long id) { + return isType(id, CompilerObjectType.METHOD); + } + + public static boolean isClass(long id) { + return isType(id, CompilerObjectType.CLASS); + } + + public static boolean isSymbol(long id) { + return isType(id, CompilerObjectType.SYMBOL); + } + + public static boolean isConstantPool(long id) { + return isType(id, CompilerObjectType.CONSTANT_POOL); + } + + public static boolean isConstant(long id) { + return isType(id, CompilerObjectType.CONSTANT_POOL); + } + + public static String toString(long id) { + CompilerObjectType type = null; + for (CompilerObjectType t : CompilerObjectType.values()) { + if ((id & CompilerObjectType.TYPE_MASK.bits) == t.bits) { + type = t; + } + } + long num = id & ~CompilerObjectType.TYPE_MASK.bits; + return type + " " + num; + } + +} diff -r 102466e70deb -r 91fe28b03d6a c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/HotSpotRegisterConfig.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/HotSpotRegisterConfig.java Wed Jan 26 18:17:37 2011 +0100 @@ -0,0 +1,211 @@ +/* + * Copyright (c) 2010 Sun Microsystems, Inc. All rights reserved. + * + * Sun Microsystems, Inc. has intellectual property rights relating to technology embodied in the product + * that is described in this document. In particular, and without limitation, these intellectual property + * rights may include one or more of the U.S. patents listed at http://www.sun.com/patents and one or + * more additional patents or pending patent applications in the U.S. and in other countries. + * + * U.S. Government Rights - Commercial software. Government users are subject to the Sun + * Microsystems, Inc. standard license agreement and applicable provisions of the FAR and its + * supplements. + * + * Use is subject to license terms. Sun, Sun Microsystems, the Sun logo, Java and Solaris are trademarks or + * registered trademarks of Sun Microsystems, Inc. in the U.S. and other countries. All SPARC trademarks + * are used under license and are trademarks or registered trademarks of SPARC International, Inc. in the + * U.S. and other countries. + * + * UNIX is a registered trademark in the U.S. and other countries, exclusively licensed through X/Open + * Company, Ltd. + */ +package com.sun.hotspot.c1x; + +import static com.sun.c1x.target.amd64.AMD64.*; + +import java.util.*; + +import com.sun.c1x.target.amd64.*; +import com.sun.c1x.util.*; +import com.sun.cri.ci.*; +import com.sun.cri.ci.CiCallingConvention.Type; +import com.sun.cri.ci.CiRegister.RegisterFlag; +import com.sun.cri.ri.*; + +/** + * @author Thomas Wuerthinger + * + */ +public class HotSpotRegisterConfig implements RiRegisterConfig { + + // be careful - the contents of this array are duplicated in c1x_CodeInstaller.cpp + private final CiRegister[] allocatable = { + rax, rbx, rcx, rdx, rsi, rdi, r8, r9, /* r10, */r11, r12, r13, r14, /*r15*/ + xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7, + xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15 + }; + + private final EnumMap categorized = CiRegister.categorize(allocatable); + + private final RiRegisterAttributes[] attributesMap; + + @Override + public CiRegister[] getAllocatableRegisters() { + return allocatable; + } + + @Override + public EnumMap getCategorizedAllocatableRegisters() { + return categorized; + } + + @Override + public RiRegisterAttributes[] getAttributesMap() { + return attributesMap; + } + + private final CiRegister[] generalParameterRegisters; + private final CiRegister[] xmmParameterRegisters = {xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7}; + private final CiRegister[] allParameterRegisters; + + private final CiRegister[] rsaRegs = { + rax, rcx, rdx, rbx, rsp, rbp, rsi, rdi, + r8, r9, r10, r11, r12, r13, r14, r15, + xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7, + xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15 + }; + + private final CiCalleeSaveArea registerSaveArea; + + + public HotSpotRegisterConfig(HotSpotVMConfig config, boolean globalStubConfig) { + if (config.windowsOs) { + generalParameterRegisters = new CiRegister[] {rdx, r8, r9, rdi, rsi, rcx}; + } else { + generalParameterRegisters = new CiRegister[] {rsi, rdx, rcx, r8, r9, rdi}; + } + + if (globalStubConfig) { + registerSaveArea = new CiCalleeSaveArea(-1, 8, rsaRegs); + } else { + registerSaveArea = CiCalleeSaveArea.EMPTY; + } + + attributesMap = RiRegisterAttributes.createMap(this, AMD64.allRegisters); + allParameterRegisters = Arrays.copyOf(generalParameterRegisters, generalParameterRegisters.length + xmmParameterRegisters.length); + System.arraycopy(xmmParameterRegisters, 0, allParameterRegisters, generalParameterRegisters.length, xmmParameterRegisters.length); + } + + @Override + public CiRegister[] getCallerSaveRegisters() { + return getAllocatableRegisters(); + } + + @Override + public CiRegister getRegisterForRole(int index) { + throw new UnsupportedOperationException(); + } + + @Override + public CiCallingConvention getCallingConvention(Type type, CiKind[] parameters, CiTarget target) { + if (type == Type.NativeCall) { + throw new UnsupportedOperationException(); + } + return callingConvention(parameters, type, target); + } + + public CiRegister[] getCallingConventionRegisters(Type type, RegisterFlag flag) { + return allParameterRegisters; + } + + private CiCallingConvention callingConvention(CiKind[] types, Type type, CiTarget target) { + CiValue[] locations = new CiValue[types.length]; + + int currentGeneral = 0; + int currentXMM = 0; + int currentStackIndex = 0; + + for (int i = 0; i < types.length; i++) { + final CiKind kind = types[i]; + + switch (kind) { + case Byte: + case Boolean: + case Short: + case Char: + case Int: + case Long: + case Word: + case Object: + if (currentGeneral < generalParameterRegisters.length) { + CiRegister register = generalParameterRegisters[currentGeneral++]; + locations[i] = register.asValue(kind); + } + break; + case Float: + case Double: + if (currentXMM < xmmParameterRegisters.length) { + CiRegister register = xmmParameterRegisters[currentXMM++]; + locations[i] = register.asValue(kind); + } + break; + default: + throw Util.shouldNotReachHere(); + } + + if (locations[i] == null) { + // we need to adjust for the frame pointer stored on the stack, which shifts incoming arguments by one slot + locations[i] = CiStackSlot.get(kind.stackKind(), currentStackIndex + (type.out ? 0 : 1), !type.out); + currentStackIndex += target.spillSlots(kind); + } + } + + return new CiCallingConvention(locations, currentStackIndex * target.spillSlotSize); + } + + @Override + public CiRegister getReturnRegister(CiKind kind) { + switch (kind) { + case Boolean: + case Byte: + case Char: + case Short: + case Int: + case Long: + case Object: + case Word: + return rax; + case Float: + case Double: + return xmm0; + case Void: + case Illegal: + return null; + default: + throw new UnsupportedOperationException("no return register for type " + kind); + } + } + + @Override + public CiRegister getScratchRegister() { + return r10; + } + + @Override + public CiRegister getFrameRegister() { + return rsp; + } + + public CiCalleeSaveArea getCalleeSaveArea() { + return registerSaveArea; + } + + @Override + public String toString() { + String res = String.format( + "Allocatable: " + Arrays.toString(getAllocatableRegisters()) + "%n" + + "CallerSave: " + Arrays.toString(getCallerSaveRegisters()) + "%n" + + "CalleeSave: " + getCalleeSaveArea() + "%n" + + "Scratch: " + getScratchRegister() + "%n"); + return res; + } +} diff -r 102466e70deb -r 91fe28b03d6a c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/HotSpotRuntime.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/HotSpotRuntime.java Wed Jan 26 18:17:37 2011 +0100 @@ -0,0 +1,236 @@ +/* + * Copyright (c) 2010 Sun Microsystems, Inc. All rights reserved. + * + * Sun Microsystems, Inc. has intellectual property rights relating to technology embodied in the product + * that is described in this document. In particular, and without limitation, these intellectual property + * rights may include one or more of the U.S. patents listed at http://www.sun.com/patents and one or + * more additional patents or pending patent applications in the U.S. and in other countries. + * + * U.S. Government Rights - Commercial software. Government users are subject to the Sun + * Microsystems, Inc. standard license agreement and applicable provisions of the FAR and its + * supplements. + * + * Use is subject to license terms. Sun, Sun Microsystems, the Sun logo, Java and Solaris are trademarks or + * registered trademarks of Sun Microsystems, Inc. in the U.S. and other countries. All SPARC trademarks + * are used under license and are trademarks or registered trademarks of SPARC International, Inc. in the + * U.S. and other countries. + * + * UNIX is a registered trademark in the U.S. and other countries, exclusively licensed through X/Open + * Company, Ltd. + */ +package com.sun.hotspot.c1x; + +import java.io.*; +import java.lang.reflect.*; +import java.util.*; + +import com.sun.cri.ci.*; +import com.sun.cri.ci.CiTargetMethod.Call; +import com.sun.cri.ci.CiTargetMethod.DataPatch; +import com.sun.cri.ci.CiTargetMethod.Safepoint; +import com.sun.cri.ri.*; +import com.sun.max.asm.dis.*; +import com.sun.max.lang.*; + +/** + * CRI runtime implementation for the HotSpot VM. + * + * @author Thomas Wuerthinger, Lukas Stadler + */ +public class HotSpotRuntime implements RiRuntime { + + final HotSpotVMConfig config; + final HotSpotRegisterConfig regConfig; + final HotSpotRegisterConfig globalStubRegConfig; + + + public HotSpotRuntime(HotSpotVMConfig config) { + this.config = config; + regConfig = new HotSpotRegisterConfig(config, false); + globalStubRegConfig = new HotSpotRegisterConfig(config, true); + } + + @Override + public int codeOffset() { + return 0; + } + + @Override + public String disassemble(byte[] code, long address) { + return disassemble(code, new DisassemblyPrinter(false), address); + } + + private String disassemble(byte[] code, DisassemblyPrinter disassemblyPrinter, long address) { + final ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); + final ISA instructionSet = ISA.AMD64; + Disassembler.disassemble(byteArrayOutputStream, code, instructionSet, WordWidth.BITS_64, address, null, disassemblyPrinter); + return byteArrayOutputStream.toString(); + } + + @Override + public String disassemble(final CiTargetMethod targetMethod) { + + final DisassemblyPrinter disassemblyPrinter = new DisassemblyPrinter(false) { + + private String toString(Call call) { + if (call.runtimeCall != null) { + return "{" + call.runtimeCall.name() + "}"; + } else if (call.symbol != null) { + return "{" + call.symbol + "}"; + } else if (call.globalStubID != null) { + return "{" + call.globalStubID + "}"; + } else { + return "{" + call.method + "}"; + } + } + + private String siteInfo(int pcOffset) { + for (Call call : targetMethod.directCalls) { + if (call.pcOffset == pcOffset) { + return toString(call); + } + } + for (Call call : targetMethod.indirectCalls) { + if (call.pcOffset == pcOffset) { + return toString(call); + } + } + for (Safepoint site : targetMethod.safepoints) { + if (site.pcOffset == pcOffset) { + return "{safepoint}"; + } + } + for (DataPatch site : targetMethod.dataReferences) { + if (site.pcOffset == pcOffset) { + return "{" + site.constant + "}"; + } + } + return null; + } + + @Override + protected String disassembledObjectString(Disassembler disassembler, DisassembledObject disassembledObject) { + final String string = super.disassembledObjectString(disassembler, disassembledObject); + + String site = siteInfo(disassembledObject.startPosition()); + if (site != null) { + return string + " " + site; + } + return string; + } + }; + final byte[] code = Arrays.copyOf(targetMethod.targetCode(), targetMethod.targetCodeSize()); + return disassemble(code, disassemblyPrinter, 0L); + } + + @Override + public String disassemble(RiMethod method) { + return "No disassembler available"; + } + + @Override + public RiConstantPool getConstantPool(RiMethod method) { + return ((HotSpotTypeResolved) method.holder()).constantPool(); + } + + @Override + public RiOsrFrame getOsrFrame(RiMethod method, int bci) { + return null; + } + + @Override + public RiType getRiType(Class javaClass) { + assert javaClass != null; + return Compiler.getVMEntries().getType(javaClass); + } + + @Override + public RiSnippets getSnippets() { + throw new UnsupportedOperationException("getSnippets"); + } + + @Override + public boolean mustInline(RiMethod method) { + return false; + } + + @Override + public boolean mustNotCompile(RiMethod method) { + return false; + } + + @Override + public boolean mustNotInline(RiMethod method) { + return Modifier.isNative(method.accessFlags()); + } + + @Override + public Object registerGlobalStub(CiTargetMethod targetMethod, String name) { + return HotSpotTargetMethod.installStub(targetMethod, name); + } + + @Override + public int sizeOfBasicObjectLock() { + // TODO shouldn't be hard coded + return 2 * 8; + } + + @Override + public int basicObjectLockOffsetInBytes() { + return 8; + } + + @Override + public RiField getRiField(Field javaField) { + throw new UnsupportedOperationException("getRiField"); + } + + @Override + public RiMethod getRiMethod(Method javaMethod) { + throw new UnsupportedOperationException("getRiMethod"); + } + + @Override + public RiMethod getRiMethod(Constructor javaConstructor) { + throw new UnsupportedOperationException("getRiMethod"); + } + + @Override + public CiConstant invoke(RiMethod method, CiMethodInvokeArguments args) { + return null; + } + + @Override + public CiConstant foldWordOperation(int opcode, CiMethodInvokeArguments args) { + throw new UnsupportedOperationException("foldWordOperation"); + } + + @Override + public boolean compareConstantObjects(Object x, Object y) { + return x == y; + } + + @Override + public boolean recordLeafMethodAssumption(RiMethod method) { + System.out.println("Trying to record leaf method assumption: " + method.toString()); + return false; + } + + @Override + public RiRegisterConfig getRegisterConfig(RiMethod method) { + return regConfig; + } + + /** + * HotSpots needs an area suitable for storing a program counter for temporary use during the deoptimization process. + */ + @Override + public int getCustomStackAreaSize() { + return 8; + } + + @Override + public boolean supportsArrayIntrinsics() { + return true; + } +} diff -r 102466e70deb -r 91fe28b03d6a c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/HotSpotSignature.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/HotSpotSignature.java Wed Jan 26 18:17:37 2011 +0100 @@ -0,0 +1,148 @@ +/* + * Copyright (c) 2010 Sun Microsystems, Inc. All rights reserved. + * + * Sun Microsystems, Inc. has intellectual property rights relating to technology embodied in the product + * that is described in this document. In particular, and without limitation, these intellectual property + * rights may include one or more of the U.S. patents listed at http://www.sun.com/patents and one or + * more additional patents or pending patent applications in the U.S. and in other countries. + * + * U.S. Government Rights - Commercial software. Government users are subject to the Sun + * Microsystems, Inc. standard license agreement and applicable provisions of the FAR and its + * supplements. + * + * Use is subject to license terms. Sun, Sun Microsystems, the Sun logo, Java and Solaris are trademarks or + * registered trademarks of Sun Microsystems, Inc. in the U.S. and other countries. All SPARC trademarks + * are used under license and are trademarks or registered trademarks of SPARC International, Inc. in the + * U.S. and other countries. + * + * UNIX is a registered trademark in the U.S. and other countries, exclusively licensed through X/Open + * Company, Ltd. + */ +package com.sun.hotspot.c1x; + +import java.util.*; + +import com.sun.cri.ci.*; +import com.sun.cri.ri.*; + +/** + * Represents a method signature. + * + * @author Thomas Wuerthinger, Lukas Stadler + */ +public class HotSpotSignature extends CompilerObject implements RiSignature { + + private final List arguments = new ArrayList(); + private final String returnType; + private final String originalString; + private RiType[] argumentTypes; + private RiType returnTypeCache; + + public HotSpotSignature(String signature) { + assert signature.length() > 0; + this.originalString = signature; + + if (signature.charAt(0) == '(') { + int cur = 1; + while (cur < signature.length() && signature.charAt(cur) != ')') { + int nextCur = parseSignature(signature, cur); + arguments.add(signature.substring(cur, nextCur)); + cur = nextCur; + } + + cur++; + int nextCur = parseSignature(signature, cur); + returnType = signature.substring(cur, nextCur); + assert nextCur == signature.length(); + } else { + returnType = null; + } + } + + private int parseSignature(String signature, int cur) { + char first; + do { + first = signature.charAt(cur++); + } while (first == '['); + + switch (first) { + case 'L': + while (signature.charAt(cur) != ';') { + cur++; + } + cur++; + break; + case 'V': + case 'I': + case 'B': + case 'C': + case 'D': + case 'F': + case 'J': + case 'S': + case 'Z': + break; + default: + assert false; + } + return cur; + } + + @Override + public int argumentCount(boolean withReceiver) { + return arguments.size() + (withReceiver ? 1 : 0); + } + + @Override + public CiKind argumentKindAt(int index) { + return CiKind.fromTypeString(arguments.get(index)); + } + + @Override + public int argumentSlots(boolean withReceiver) { + + int argSlots = 0; + for (int i = 0; i < argumentCount(false); i++) { + argSlots += argumentKindAt(i).sizeInSlots(); + } + + return argSlots + (withReceiver ? 1 : 0); + } + + @Override + public RiType argumentTypeAt(int index, RiType accessingClass) { + if (argumentTypes == null) { + argumentTypes = new RiType[arguments.size()]; + } + RiType type = argumentTypes[index]; + if (type == null) { + type = Compiler.getVMEntries().RiSignature_lookupType(arguments.get(index), (HotSpotTypeResolved) accessingClass); + argumentTypes[index] = type; + } + return type; + } + + @Override + public String asString() { + return originalString; + } + + @Override + public CiKind returnKind() { + return CiKind.fromTypeString(returnType); + } + + @Override + public RiType returnType(RiType accessingClass) { + if (returnTypeCache == null) { + returnTypeCache = Compiler.getVMEntries().RiSignature_lookupType(returnType, (HotSpotTypeResolved) accessingClass); + } + return returnTypeCache; + } + + @Override + public String toString() { + return "HotSpotSignature<" + originalString + ">"; + } + +} diff -r 102466e70deb -r 91fe28b03d6a c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/HotSpotTarget.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/HotSpotTarget.java Wed Jan 26 18:17:37 2011 +0100 @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2010 Sun Microsystems, Inc. All rights reserved. + * + * Sun Microsystems, Inc. has intellectual property rights relating to technology embodied in the product + * that is described in this document. In particular, and without limitation, these intellectual property + * rights may include one or more of the U.S. patents listed at http://www.sun.com/patents and one or + * more additional patents or pending patent applications in the U.S. and in other countries. + * + * U.S. Government Rights - Commercial software. Government users are subject to the Sun + * Microsystems, Inc. standard license agreement and applicable provisions of the FAR and its + * supplements. + * + * Use is subject to license terms. Sun, Sun Microsystems, the Sun logo, Java and Solaris are trademarks or + * registered trademarks of Sun Microsystems, Inc. in the U.S. and other countries. All SPARC trademarks + * are used under license and are trademarks or registered trademarks of SPARC International, Inc. in the + * U.S. and other countries. + * + * UNIX is a registered trademark in the U.S. and other countries, exclusively licensed through X/Open + * Company, Ltd. + */ +package com.sun.hotspot.c1x; + +import com.sun.cri.ci.*; + +/** + * HotSpot-specific CiTarget that provides the correct stack frame size alignment. + * + * @author Lukas Stadler + */ +public class HotSpotTarget extends CiTarget { + + public HotSpotTarget(CiArchitecture arch, boolean isMP, int spillSlotSize, int stackAlignment, int pageSize, int cacheAlignment, boolean inlineObjects) { + super(arch, isMP, spillSlotSize, stackAlignment, pageSize, cacheAlignment, inlineObjects, true); + } + + @Override + public int alignFrameSize(int frameSize) { + // account for the stored rbp value + return super.alignFrameSize(frameSize + wordSize) - wordSize; + } +} diff -r 102466e70deb -r 91fe28b03d6a c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/HotSpotTargetMethod.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/HotSpotTargetMethod.java Wed Jan 26 18:17:37 2011 +0100 @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2010 Sun Microsystems, Inc. All rights reserved. + * + * Sun Microsystems, Inc. has intellectual property rights relating to technology embodied in the product + * that is described in this document. In particular, and without limitation, these intellectual property + * rights may include one or more of the U.S. patents listed at http://www.sun.com/patents and one or + * more additional patents or pending patent applications in the U.S. and in other countries. + * + * U.S. Government Rights - Commercial software. Government users are subject to the Sun + * Microsystems, Inc. standard license agreement and applicable provisions of the FAR and its + * supplements. + * + * Use is subject to license terms. Sun, Sun Microsystems, the Sun logo, Java and Solaris are trademarks or + * registered trademarks of Sun Microsystems, Inc. in the U.S. and other countries. All SPARC trademarks + * are used under license and are trademarks or registered trademarks of SPARC International, Inc. in the + * U.S. and other countries. + * + * UNIX is a registered trademark in the U.S. and other countries, exclusively licensed through X/Open + * Company, Ltd. + */ +package com.sun.hotspot.c1x; + +import java.util.*; + +import com.sun.cri.ci.*; +import com.sun.cri.ci.CiTargetMethod.*; +import com.sun.hotspot.c1x.logging.*; + +/** + * CiTargetMethod augmented with HotSpot-specific information. + * + * @author Lukas Stadler + */ +public final class HotSpotTargetMethod extends CompilerObject { + + public final CiTargetMethod targetMethod; + public final HotSpotMethodResolved method; // used only for methods + public final String name; // used only for stubs + + public final Site[] sites; + public final ExceptionHandler[] exceptionHandlers; + + private HotSpotTargetMethod(HotSpotMethodResolved method, CiTargetMethod targetMethod) { + this.method = method; + this.targetMethod = targetMethod; + this.name = null; + + sites = getSortedSites(targetMethod); + if (targetMethod.exceptionHandlers == null) { + exceptionHandlers = null; + } else { + exceptionHandlers = targetMethod.exceptionHandlers.toArray(new ExceptionHandler[targetMethod.exceptionHandlers.size()]); + } + } + + private HotSpotTargetMethod(CiTargetMethod targetMethod, String name) { + this.method = null; + this.targetMethod = targetMethod; + this.name = name; + + sites = getSortedSites(targetMethod); + assert targetMethod.exceptionHandlers == null || targetMethod.exceptionHandlers.size() == 0; + exceptionHandlers = null; + } + + private Site[] getSortedSites(CiTargetMethod target) { + List[] lists = new List[] {target.directCalls, target.indirectCalls, target.safepoints, target.dataReferences, target.marks}; + int count = 0; + for (List list : lists) { + count += list.size(); + } + Site[] result = new Site[count]; + int pos = 0; + for (List list : lists) { + for (Object elem : list) { + result[pos++] = (Site) elem; + } + } + Arrays.sort(result, new Comparator() { + + public int compare(Site s1, Site s2) { + if (s1.pcOffset == s2.pcOffset && (s1 instanceof Mark ^ s2 instanceof Mark)) { + return s1 instanceof Mark ? -1 : 1; + } + return s1.pcOffset - s2.pcOffset; + } + }); + if (Logger.ENABLED) { + for (Site site : result) { + Logger.log(site.pcOffset + ": " + site); + } + } + return result; + } + + public static void installMethod(HotSpotMethodResolved method, CiTargetMethod targetMethod) { + Compiler.getVMEntries().installMethod(new HotSpotTargetMethod(method, targetMethod)); + } + + public static Object installStub(CiTargetMethod targetMethod, String name) { + return Compiler.getVMEntries().installStub(new HotSpotTargetMethod(targetMethod, name)); + } + +} diff -r 102466e70deb -r 91fe28b03d6a c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/HotSpotType.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/HotSpotType.java Wed Jan 26 18:17:37 2011 +0100 @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2010 Sun Microsystems, Inc. All rights reserved. + * + * Sun Microsystems, Inc. has intellectual property rights relating to technology embodied in the product + * that is described in this document. In particular, and without limitation, these intellectual property + * rights may include one or more of the U.S. patents listed at http://www.sun.com/patents and one or + * more additional patents or pending patent applications in the U.S. and in other countries. + * + * U.S. Government Rights - Commercial software. Government users are subject to the Sun + * Microsystems, Inc. standard license agreement and applicable provisions of the FAR and its + * supplements. + * + * Use is subject to license terms. Sun, Sun Microsystems, the Sun logo, Java and Solaris are trademarks or + * registered trademarks of Sun Microsystems, Inc. in the U.S. and other countries. All SPARC trademarks + * are used under license and are trademarks or registered trademarks of SPARC International, Inc. in the + * U.S. and other countries. + * + * UNIX is a registered trademark in the U.S. and other countries, exclusively licensed through X/Open + * Company, Ltd. + */ +package com.sun.hotspot.c1x; + +import com.sun.cri.ri.*; + +/** + * Common interface for all HotSpot RiType-implementations. + * + * @author Lukas Stadler + */ +public abstract class HotSpotType extends CompilerObject implements RiType { + protected String name; + + @Override + public final String name() { + return name; + } +} diff -r 102466e70deb -r 91fe28b03d6a c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/HotSpotTypePrimitive.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/HotSpotTypePrimitive.java Wed Jan 26 18:17:37 2011 +0100 @@ -0,0 +1,156 @@ +/* + * Copyright (c) 2010 Sun Microsystems, Inc. All rights reserved. + * + * Sun Microsystems, Inc. has intellectual property rights relating to technology embodied in the product + * that is described in this document. In particular, and without limitation, these intellectual property + * rights may include one or more of the U.S. patents listed at http://www.sun.com/patents and one or + * more additional patents or pending patent applications in the U.S. and in other countries. + * + * U.S. Government Rights - Commercial software. Government users are subject to the Sun + * Microsystems, Inc. standard license agreement and applicable provisions of the FAR and its + * supplements. + * + * Use is subject to license terms. Sun, Sun Microsystems, the Sun logo, Java and Solaris are trademarks or + * registered trademarks of Sun Microsystems, Inc. in the U.S. and other countries. All SPARC trademarks + * are used under license and are trademarks or registered trademarks of SPARC International, Inc. in the + * U.S. and other countries. + * + * UNIX is a registered trademark in the U.S. and other countries, exclusively licensed through X/Open + * Company, Ltd. + */ +package com.sun.hotspot.c1x; + +import com.sun.c1x.util.*; +import com.sun.cri.ci.*; +import com.sun.cri.ri.*; + +/** + * Implementation of RiType for primitive HotSpot types. + * + * @author Thomas Wuerthinger, Lukas Stadler + */ +public final class HotSpotTypePrimitive extends HotSpotType { + + private CiKind kind; + + public static final HotSpotTypePrimitive Boolean = new HotSpotTypePrimitive(CiKind.Boolean); + public static final HotSpotTypePrimitive Char = new HotSpotTypePrimitive(CiKind.Char); + public static final HotSpotTypePrimitive Float = new HotSpotTypePrimitive(CiKind.Float); + public static final HotSpotTypePrimitive Double = new HotSpotTypePrimitive(CiKind.Double); + public static final HotSpotTypePrimitive Byte = new HotSpotTypePrimitive(CiKind.Byte); + public static final HotSpotTypePrimitive Short = new HotSpotTypePrimitive(CiKind.Short); + public static final HotSpotTypePrimitive Int = new HotSpotTypePrimitive(CiKind.Int); + public static final HotSpotTypePrimitive Long = new HotSpotTypePrimitive(CiKind.Long); + public static final HotSpotTypePrimitive Void = new HotSpotTypePrimitive(CiKind.Void); + + private HotSpotTypePrimitive(CiKind kind) { + this.kind = kind; + this.name = kind.toString(); + } + + @Override + public int accessFlags() { + return javaClass().getModifiers(); + } + + @Override + public RiType arrayOf() { + return Compiler.getVMEntries().getPrimitiveArrayType(kind); + } + + @Override + public RiType componentType() { + return null; + } + + @Override + public RiType exactType() { + return this; + } + + @Override + public CiConstant getEncoding(Representation r) { + throw Util.unimplemented("HotSpotTypePrimitive.getEncoding"); + } + + @Override + public CiKind getRepresentationKind(Representation r) { + return kind; + } + + @Override + public boolean hasFinalizableSubclass() { + return false; + } + + @Override + public boolean hasFinalizer() { + return false; + } + + @Override + public boolean hasSubclass() { + return false; + } + + @Override + public boolean isArrayClass() { + return false; + } + + @Override + public boolean isInitialized() { + return true; + } + + @Override + public boolean isInstance(Object obj) { + return false; + } + + @Override + public boolean isInstanceClass() { + return false; + } + + @Override + public boolean isInterface() { + return false; + } + + @Override + public boolean isResolved() { + return true; + } + + @Override + public boolean isSubtypeOf(RiType other) { + return false; + } + + @Override + public Class javaClass() { + return kind.toJavaClass(); + } + + @Override + public CiKind kind() { + return kind; + } + + @Override + public RiMethod resolveMethodImpl(RiMethod method) { + return null; + } + + @Override + public String toString() { + return "HotSpotTypePrimitive<" + kind + ">"; + } + + @Override + public RiType uniqueConcreteSubtype() { + return this; + } + +} diff -r 102466e70deb -r 91fe28b03d6a c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/HotSpotTypeResolved.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/HotSpotTypeResolved.java Wed Jan 26 18:17:37 2011 +0100 @@ -0,0 +1,202 @@ +/* + * Copyright (c) 2010 Sun Microsystems, Inc. All rights reserved. + * + * Sun Microsystems, Inc. has intellectual property rights relating to technology embodied in the product + * that is described in this document. In particular, and without limitation, these intellectual property + * rights may include one or more of the U.S. patents listed at http://www.sun.com/patents and one or + * more additional patents or pending patent applications in the U.S. and in other countries. + * + * U.S. Government Rights - Commercial software. Government users are subject to the Sun + * Microsystems, Inc. standard license agreement and applicable provisions of the FAR and its + * supplements. + * + * Use is subject to license terms. Sun, Sun Microsystems, the Sun logo, Java and Solaris are trademarks or + * registered trademarks of Sun Microsystems, Inc. in the U.S. and other countries. All SPARC trademarks + * are used under license and are trademarks or registered trademarks of SPARC International, Inc. in the + * U.S. and other countries. + * + * UNIX is a registered trademark in the U.S. and other countries, exclusively licensed through X/Open + * Company, Ltd. + */ +package com.sun.hotspot.c1x; + +import java.lang.reflect.*; +import java.util.*; + +import com.sun.cri.ci.*; +import com.sun.cri.ri.*; + +/** + * Implementation of RiType for resolved non-primitive HotSpot classes. + * + * @author Thomas Wuerthinger, Lukas Stadler + */ +public class HotSpotTypeResolved extends HotSpotType { + + private Class javaMirror; + private String simpleName; + private int accessFlags; + private boolean hasFinalizer; + private boolean hasSubclass; + private boolean hasFinalizableSubclass; + private boolean isInitialized; + private boolean isArrayClass; + private boolean isInstanceClass; + private boolean isInterface; + private int instanceSize; + private RiType componentType; + private HashMap fieldCache; + private RiConstantPool pool; + + @Override + public int accessFlags() { + return accessFlags; + } + + @Override + public RiType arrayOf() { + return Compiler.getVMEntries().RiType_arrayOf(this); + } + + @Override + public RiType componentType() { + return Compiler.getVMEntries().RiType_componentType(this); + } + + @Override + public RiType uniqueConcreteSubtype() { + return Compiler.getVMEntries().RiType_uniqueConcreteSubtype(this); + } + + @Override + public RiType exactType() { + if (Modifier.isFinal(accessFlags)) { + return this; + } + return null; + } + + @Override + public CiConstant getEncoding(Representation r) { + switch (r) { + case JavaClass: + return CiConstant.forObject(javaClass()); + case ObjectHub: + return CiConstant.forObject(this); + case StaticFields: + return CiConstant.forObject(this); + case TypeInfo: + return CiConstant.forObject(this); + default: + return null; + } + } + + @Override + public CiKind getRepresentationKind(Representation r) { + return CiKind.Object; + } + + @Override + public boolean hasFinalizableSubclass() { + return hasFinalizableSubclass; + } + + @Override + public boolean hasFinalizer() { + return hasFinalizer; + } + + @Override + public boolean hasSubclass() { + return hasSubclass; + } + + @Override + public boolean isArrayClass() { + return isArrayClass; + } + + @Override + public boolean isInitialized() { + return isInitialized; + } + + @Override + public boolean isInstance(Object obj) { + return javaMirror.isInstance(obj); + } + + @Override + public boolean isInstanceClass() { + return isInstanceClass; + } + + @Override + public boolean isInterface() { + return isInterface; + } + + @Override + public boolean isResolved() { + return true; + } + + @Override + public boolean isSubtypeOf(RiType other) { + if (other instanceof HotSpotTypeResolved) { + return Compiler.getVMEntries().RiType_isSubtypeOf(this, other); + } + // No resolved type is a subtype of an unresolved type. + return false; + } + + @Override + public Class javaClass() { + return javaMirror; + } + + @Override + public CiKind kind() { + return CiKind.Object; + } + + @Override + public RiMethod resolveMethodImpl(RiMethod method) { + assert method instanceof HotSpotMethod; + return Compiler.getVMEntries().RiType_resolveMethodImpl(this, method.name(), method.signature().asString()); + } + + @Override + public String toString() { + return "HotSpotType<" + simpleName + ", resolved>"; + } + + public RiConstantPool constantPool() { + // TODO: Implement constant pool without the need for VmId and cache the constant pool. + return Compiler.getVMEntries().RiType_constantPool(this); + } + + public int instanceSize() { + return instanceSize; + } + + public RiField createRiField(String name, RiType type, int offset) { + RiField result = null; + + // (tw) Must cache the fields, because the local load elimination only works if the objects from two field lookups are equal. + if (fieldCache == null) { + fieldCache = new HashMap(8); + } else { + result = fieldCache.get(offset); + } + + if (result == null) { + result = new HotSpotField(this, name, type, offset); + fieldCache.put(offset, result); + } + + return result; + } + +} diff -r 102466e70deb -r 91fe28b03d6a c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/HotSpotTypeUnresolved.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/HotSpotTypeUnresolved.java Wed Jan 26 18:17:37 2011 +0100 @@ -0,0 +1,197 @@ +/* + * Copyright (c) 2010 Sun Microsystems, Inc. All rights reserved. + * + * Sun Microsystems, Inc. has intellectual property rights relating to technology embodied in the product + * that is described in this document. In particular, and without limitation, these intellectual property + * rights may include one or more of the U.S. patents listed at http://www.sun.com/patents and one or + * more additional patents or pending patent applications in the U.S. and in other countries. + * + * U.S. Government Rights - Commercial software. Government users are subject to the Sun + * Microsystems, Inc. standard license agreement and applicable provisions of the FAR and its + * supplements. + * + * Use is subject to license terms. Sun, Sun Microsystems, the Sun logo, Java and Solaris are trademarks or + * registered trademarks of Sun Microsystems, Inc. in the U.S. and other countries. All SPARC trademarks + * are used under license and are trademarks or registered trademarks of SPARC International, Inc. in the + * U.S. and other countries. + * + * UNIX is a registered trademark in the U.S. and other countries, exclusively licensed through X/Open + * Company, Ltd. + */ +package com.sun.hotspot.c1x; + +import com.sun.cri.ci.*; +import com.sun.cri.ri.*; + +/** + * Implementation of RiType for unresolved HotSpot classes. + * + * @author Thomas Wuerthinger, Lukas Stadler + */ +public class HotSpotTypeUnresolved extends HotSpotType { + + public final String simpleName; + public final int dimensions; + + /** + * Creates a new unresolved type for a specified type descriptor. + */ + public HotSpotTypeUnresolved(String name) { + assert name.length() > 0 : "name cannot be empty"; + + int dimensions = 0; + // Decode name if necessary. + if (name.charAt(name.length() - 1) == ';') { + int startIndex = 0; + while (name.charAt(startIndex) == '[') { + startIndex++; + dimensions++; + } + assert name.charAt(startIndex) == 'L'; + this.simpleName = name.substring(startIndex + 1, name.length() - 1); + this.name = name; + } else { + this.simpleName = name; + this.name = getFullName(name, dimensions); + } + + this.dimensions = dimensions; + } + + public HotSpotTypeUnresolved(String name, int dimensions) { + assert dimensions >= 0; + this.simpleName = name; + this.dimensions = dimensions; + this.name = getFullName(name, dimensions); + } + + private String getFullName(String name, int dimensions) { + StringBuilder str = new StringBuilder(); + for (int i = 0; i < dimensions; i++) { + str.append('['); + } + str.append('L').append(simpleName).append(';'); + return str.toString(); + } + + @Override + public RiType uniqueConcreteSubtype() { + throw unresolved("uniqueConcreteSubtype"); + } + + @Override + public Class javaClass() { + throw unresolved("javaClass"); + } + + @Override + public boolean hasSubclass() { + throw unresolved("hasSubclass()"); + } + + @Override + public boolean hasFinalizer() { + throw unresolved("hasFinalizer()"); + } + + @Override + public boolean hasFinalizableSubclass() { + throw unresolved("hasFinalizableSubclass()"); + } + + @Override + public boolean isInterface() { + throw unresolved("isInterface()"); + } + + @Override + public boolean isArrayClass() { + return dimensions > 0; + } + + @Override + public boolean isInstanceClass() { + throw unresolved("isInstanceClass()"); + } + + @Override + public int accessFlags() { + throw unresolved("accessFlags()"); + } + + @Override + public boolean isResolved() { + return false; + } + + @Override + public boolean isInitialized() { + throw unresolved("isInitialized()"); + } + + @Override + public boolean isSubtypeOf(RiType other) { + throw unresolved("isSubtypeOf()"); + } + + @Override + public boolean isInstance(Object obj) { + throw unresolved("isInstance()"); + } + + @Override + public RiType componentType() { + assert isArrayClass() : "no array class" + name(); + return new HotSpotTypeUnresolved(simpleName, dimensions - 1); + } + + @Override + public RiType exactType() { + throw unresolved("exactType()"); + } + + @Override + public RiType arrayOf() { + return new HotSpotTypeUnresolved(simpleName, dimensions + 1); + } + + @Override + public RiMethod resolveMethodImpl(RiMethod method) { + throw unresolved("resolveMethodImpl()"); + } + + @Override + public CiKind kind() { + return CiKind.Object; + } + + private CiUnresolvedException unresolved(String operation) { + throw new CiUnresolvedException(operation + " not defined for unresolved class " + simpleName); + } + + @Override + public int hashCode() { + return simpleName.hashCode(); + } + + @Override + public boolean equals(Object o) { + return o == this; + } + + @Override + public String toString() { + return "HotSpotType<" + simpleName + ", unresolved>"; + } + + @Override + public CiConstant getEncoding(RiType.Representation r) { + throw unresolved("getEncoding()"); + } + + @Override + public CiKind getRepresentationKind(RiType.Representation r) { + return CiKind.Object; + } + +} diff -r 102466e70deb -r 91fe28b03d6a c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/HotSpotVMConfig.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/HotSpotVMConfig.java Wed Jan 26 18:17:37 2011 +0100 @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2010 Sun Microsystems, Inc. All rights reserved. + * + * Sun Microsystems, Inc. has intellectual property rights relating to technology embodied in the product + * that is described in this document. In particular, and without limitation, these intellectual property + * rights may include one or more of the U.S. patents listed at http://www.sun.com/patents and one or + * more additional patents or pending patent applications in the U.S. and in other countries. + * + * U.S. Government Rights - Commercial software. Government users are subject to the Sun + * Microsystems, Inc. standard license agreement and applicable provisions of the FAR and its + * supplements. + * + * Use is subject to license terms. Sun, Sun Microsystems, the Sun logo, Java and Solaris are trademarks or + * registered trademarks of Sun Microsystems, Inc. in the U.S. and other countries. All SPARC trademarks + * are used under license and are trademarks or registered trademarks of SPARC International, Inc. in the + * U.S. and other countries. + * + * UNIX is a registered trademark in the U.S. and other countries, exclusively licensed through X/Open + * Company, Ltd. + */ +package com.sun.hotspot.c1x; + +import com.sun.cri.ci.*; + +/** + * Used to communicate configuration details, runtime offsets, etc. to c1x upon compileMethod. + * + * @author Lukas Stadler + */ +public class HotSpotVMConfig extends CompilerObject { + + // os information, register layout, code generation, ... + public boolean windowsOs; + public int codeEntryAlignment; + public boolean verifyPointers; + public boolean useFastLocking; + public boolean useFastNewObjectArray; + public boolean useFastNewTypeArray; + + // offsets, ... + public int vmPageSize; + public int stackShadowPages; + public int hubOffset; + public int arrayLengthOffset; + public int klassStateOffset; + public int klassStateFullyInitialized; + public int[] arrayOffsets; + public int arrayClassElementOffset; + public int threadTlabTopOffset; + public int threadTlabEndOffset; + public int threadObjectOffset; + public int instanceHeaderPrototypeOffset; + public int threadExceptionOopOffset; + public int threadExceptionPcOffset; + public int threadMultiNewArrayStorage; + public long cardtableStartAddress; + public int cardtableShift; + public long safepointPollingAddress; + public int classMirrorOffset; + + // runtime stubs + public long debugStub; + public long instanceofStub; + public long newInstanceStub; + public long unresolvedNewInstanceStub; + public long newTypeArrayStub; + public long newObjectArrayStub; + public long newMultiArrayStub; + public long loadKlassStub; + public long accessFieldStub; + public long resolveStaticCallStub; + public long inlineCacheMissStub; + public long unwindExceptionStub; + public long handleExceptionStub; + public long handleDeoptStub; + public long throwClassCastException; + public long throwArrayStoreException; + public long throwArrayIndexException; + public long monitorEnterStub; + public long monitorExitStub; + public long fastMonitorEnterStub; + public long fastMonitorExitStub; + public long verifyPointerStub; + + public void check() { + assert vmPageSize >= 16; + assert codeEntryAlignment > 0; + assert stackShadowPages > 0; + } + + public int getArrayOffset(CiKind kind) { + return arrayOffsets[getKindNumber(kind)]; + } + + private int getKindNumber(CiKind kind) { + if (kind == CiKind.Boolean) { + return 0; + } else if (kind == CiKind.Byte) { + return 1; + } else if (kind == CiKind.Short) { + return 2; + } else if (kind == CiKind.Char) { + return 3; + } else if (kind == CiKind.Int) { + return 4; + } else if (kind == CiKind.Float) { + return 5; + } else if (kind == CiKind.Long) { + return 6; + } else if (kind == CiKind.Double) { + return 7; + } else if (kind == CiKind.Object) { + return 8; + } else { + throw new RuntimeException(kind + " is not a Java kind"); + } + } +} diff -r 102466e70deb -r 91fe28b03d6a c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/HotSpotXirGenerator.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/HotSpotXirGenerator.java Wed Jan 26 18:17:37 2011 +0100 @@ -0,0 +1,1568 @@ +/* + * Copyright (c) 2010 Sun Microsystems, Inc. All rights reserved. + * + * Sun Microsystems, Inc. has intellectual property rights relating to technology embodied in the product + * that is described in this document. In particular, and without limitation, these intellectual property + * rights may include one or more of the U.S. patents listed at http://www.sun.com/patents and one or + * more additional patents or pending patent applications in the U.S. and in other countries. + * + * U.S. Government Rights - Commercial software. Government users are subject to the Sun + * Microsystems, Inc. standard license agreement and applicable provisions of the FAR and its + * supplements. + * + * Use is subject to license terms. Sun, Sun Microsystems, the Sun logo, Java and Solaris are trademarks or + * registered trademarks of Sun Microsystems, Inc. in the U.S. and other countries. All SPARC trademarks + * are used under license and are trademarks or registered trademarks of SPARC International, Inc. in the + * U.S. and other countries. + * + * UNIX is a registered trademark in the U.S. and other countries, exclusively licensed through X/Open + * Company, Ltd. + */ +package com.sun.hotspot.c1x; + +import static com.sun.cri.ci.CiCallingConvention.Type.*; +import static com.sun.hotspot.c1x.TemplateFlag.*; + +import java.lang.reflect.*; +import java.util.*; +import java.util.concurrent.*; + +import com.sun.c1x.target.amd64.*; +import com.sun.cri.ci.CiAddress.Scale; +import com.sun.cri.ci.*; +import com.sun.cri.ri.*; +import com.sun.cri.ri.RiType.Representation; +import com.sun.cri.xir.*; +import com.sun.cri.xir.CiXirAssembler.XirLabel; +import com.sun.cri.xir.CiXirAssembler.XirMark; +import com.sun.cri.xir.CiXirAssembler.XirOperand; +import com.sun.cri.xir.CiXirAssembler.XirParameter; + +/** + * + * @author Thomas Wuerthinger, Lukas Stadler + */ +public class HotSpotXirGenerator implements RiXirGenerator { + + // this needs to correspond to c1x_CodeInstaller.hpp + // @formatter:off + private static final Integer MARK_VERIFIED_ENTRY = 0x0001; + private static final Integer MARK_UNVERIFIED_ENTRY = 0x0002; + private static final Integer MARK_OSR_ENTRY = 0x0003; + private static final Integer MARK_UNWIND_ENTRY = 0x0004; + private static final Integer MARK_EXCEPTION_HANDLER_ENTRY = 0x0005; + private static final Integer MARK_DEOPT_HANDLER_ENTRY = 0x0006; + + private static final Integer MARK_STATIC_CALL_STUB = 0x1000; + + private static final Integer MARK_INVOKE_INVALID = 0x2000; + private static final Integer MARK_INVOKEINTERFACE = 0x2001; + private static final Integer MARK_INVOKESTATIC = 0x2002; + private static final Integer MARK_INVOKESPECIAL = 0x2003; + private static final Integer MARK_INVOKEVIRTUAL = 0x2004; + + private static final Integer MARK_IMPLICIT_NULL = 0x3000; + + private static final Integer MARK_KLASS_PATCHING = 0x4000; + private static final Integer MARK_DUMMY_OOP_RELOCATION = 0x4001; + private static final Integer MARK_ACCESS_FIELD_PATCHING = 0x4002; + // @formatter:on + + private final HotSpotVMConfig config; + private final CiTarget target; + private final RiRegisterConfig registerConfig; + + private CiXirAssembler asm; + + public HotSpotXirGenerator(HotSpotVMConfig config, CiTarget target, RiRegisterConfig registerConfig) { + this.config = config; + this.target = target; + this.registerConfig = registerConfig; + } + + private SimpleTemplates prologueTemplates = new SimpleTemplates(STATIC_METHOD) { + + @Override + protected XirTemplate create(CiXirAssembler asm, long flags) { + asm.restart(CiKind.Void); + XirOperand framePointer = asm.createRegisterTemp("frame pointer", CiKind.Word, AMD64.rbp); + XirOperand stackPointer = asm.createRegisterTemp("stack pointer", CiKind.Word, AMD64.rsp); + XirLabel unverifiedStub = null; + + asm.mark(MARK_OSR_ENTRY); + asm.mark(MARK_UNVERIFIED_ENTRY); + if (!is(STATIC_METHOD, flags)) { + unverifiedStub = asm.createOutOfLineLabel("unverified"); + + XirOperand temp = asm.createRegisterTemp("temp (r10)", CiKind.Word, AMD64.r10); + XirOperand cache = asm.createRegisterTemp("cache (rax)", CiKind.Word, AMD64.rax); + + CiCallingConvention conventions = registerConfig.getCallingConvention(JavaCallee, new CiKind[] {CiKind.Object}, target); + XirOperand receiver = asm.createRegisterTemp("receiver", CiKind.Word, conventions.locations[0].asRegister()); + + asm.pload(CiKind.Word, temp, receiver, asm.i(config.hubOffset), false); + asm.jneq(unverifiedStub, cache, temp); + } + asm.align(config.codeEntryAlignment); + asm.mark(MARK_VERIFIED_ENTRY); + asm.stackOverflowCheck(); + asm.push(framePointer); + asm.mov(framePointer, stackPointer); + asm.pushFrame(); + + // -- out of line ------------------------------------------------------- + XirOperand thread = asm.createRegisterTemp("thread", CiKind.Word, AMD64.r15); + XirOperand exceptionOop = asm.createTemp("exception oop", CiKind.Object); + XirLabel unwind = asm.createOutOfLineLabel("unwind"); + asm.bindOutOfLine(unwind); + + asm.mark(MARK_UNWIND_ENTRY); + + asm.pload(CiKind.Object, exceptionOop, thread, asm.i(config.threadExceptionOopOffset), false); + asm.pstore(CiKind.Object, thread, asm.i(config.threadExceptionOopOffset), asm.createConstant(CiConstant.NULL_OBJECT), false); + asm.pstore(CiKind.Long, thread, asm.i(config.threadExceptionPcOffset), asm.l(0), false); + + asm.callRuntime(config.unwindExceptionStub, null, exceptionOop); + asm.shouldNotReachHere(); + + asm.mark(MARK_EXCEPTION_HANDLER_ENTRY); + asm.callRuntime(config.handleExceptionStub, null); + asm.shouldNotReachHere(); + + asm.nop(1); + asm.mark(MARK_DEOPT_HANDLER_ENTRY); + asm.callRuntime(config.handleDeoptStub, null); + asm.shouldNotReachHere(); + + if (!is(STATIC_METHOD, flags)) { + asm.bindOutOfLine(unverifiedStub); + asm.jmpRuntime(config.inlineCacheMissStub); + } + + return asm.finishTemplate(is(STATIC_METHOD, flags) ? "static prologue" : "prologue"); + } + }; + + private SimpleTemplates epilogueTemplates = new SimpleTemplates(STATIC_METHOD, SYNCHRONIZED) { + + @Override + protected XirTemplate create(CiXirAssembler asm, long flags) { + asm.restart(CiKind.Void); + XirOperand framePointer = asm.createRegisterTemp("frame pointer", CiKind.Word, AMD64.rbp); + + asm.popFrame(); + asm.pop(framePointer); + + // TODO safepoint check + + return asm.finishTemplate("epilogue"); + } + }; + + private SimpleTemplates safepointTemplates = new SimpleTemplates() { + + @Override + protected XirTemplate create(CiXirAssembler asm, long flags) { + asm.restart(CiKind.Void); + + // XirOperand temp = asm.createRegister("temp", CiKind.Word, AMD64.rax); + // asm.pload(CiKind.Word, temp, asm.w(config.safepointPollingAddress), true); + + return asm.finishTemplate("safepoint"); + } + }; + + private SimpleTemplates exceptionObjectTemplates = new SimpleTemplates() { + + @Override + protected XirTemplate create(CiXirAssembler asm, long flags) { + XirOperand result = asm.restart(CiKind.Object); + XirOperand thread = asm.createRegisterTemp("thread", CiKind.Word, AMD64.r15); + + asm.pload(CiKind.Object, result, thread, asm.i(config.threadExceptionOopOffset), false); + asm.pstore(CiKind.Object, thread, asm.i(config.threadExceptionOopOffset), asm.o(null), false); + asm.pstore(CiKind.Long, thread, asm.i(config.threadExceptionPcOffset), asm.l(0), false); + + return asm.finishTemplate("exception object"); + } + }; + + private SimpleTemplates resolveClassTemplates = new SimpleTemplates(UNRESOLVED) { + + @Override + protected XirTemplate create(CiXirAssembler asm, long flags) { + XirOperand result = asm.restart(CiKind.Word); + if (is(UNRESOLVED, flags)) { + UnresolvedClassPatching patching = new UnresolvedClassPatching(asm, result, config); + patching.emitInline(); + // -- out of line ------------------------------------------------------- + patching.emitOutOfLine(); + } else { + XirOperand type = asm.createConstantInputParameter("type", CiKind.Object); + asm.mov(result, type); + } + return asm.finishTemplate(is(UNRESOLVED, flags) ? "resolve class (unresolved)" : "resolve class"); + } + }; + + private SimpleTemplates invokeInterfaceTemplates = new SimpleTemplates(NULL_CHECK) { + + @Override + protected XirTemplate create(CiXirAssembler asm, long flags) { + asm.restart(); + XirParameter receiver = asm.createInputParameter("receiver", CiKind.Object); + XirParameter addr = asm.createConstantInputParameter("addr", CiKind.Word); + XirOperand temp = asm.createRegisterTemp("temp", CiKind.Word, AMD64.rax); + + if (is(NULL_CHECK, flags)) { + asm.nop(1); + asm.mark(MARK_IMPLICIT_NULL); + asm.pload(CiKind.Word, temp, receiver, true); + } + asm.mark(MARK_INVOKEINTERFACE); + asm.mov(temp, asm.createConstant(CiConstant.forObject(HotSpotProxy.DUMMY_CONSTANT_OBJ))); + + return asm.finishTemplate(addr, "invokeinterface"); + } + }; + + private SimpleTemplates invokeVirtualTemplates = new SimpleTemplates(NULL_CHECK) { + + @Override + protected XirTemplate create(CiXirAssembler asm, long flags) { + asm.restart(); + XirParameter receiver = asm.createInputParameter("receiver", CiKind.Object); + XirParameter addr = asm.createConstantInputParameter("addr", CiKind.Word); + XirOperand temp = asm.createRegisterTemp("temp", CiKind.Word, AMD64.rax); + + if (is(NULL_CHECK, flags)) { + asm.nop(1); + asm.mark(MARK_IMPLICIT_NULL); + asm.pload(CiKind.Word, temp, receiver, true); + } + asm.mark(MARK_INVOKEVIRTUAL); + asm.mov(temp, asm.createConstant(CiConstant.forObject(HotSpotProxy.DUMMY_CONSTANT_OBJ))); + + return asm.finishTemplate(addr, "invokevirtual"); + } + }; + + private SimpleTemplates invokeSpecialTemplates = new SimpleTemplates(NULL_CHECK) { + + @Override + protected XirTemplate create(CiXirAssembler asm, long flags) { + asm.restart(); + XirParameter receiver = asm.createInputParameter("receiver", CiKind.Object); + XirParameter addr = asm.createConstantInputParameter("addr", CiKind.Word); + XirOperand temp = asm.createRegisterTemp("temp", CiKind.Word, AMD64.rax); + XirLabel stub = asm.createOutOfLineLabel("call stub"); + + if (is(NULL_CHECK, flags)) { + asm.nop(1); + asm.mark(MARK_IMPLICIT_NULL); + asm.pload(CiKind.Word, temp, receiver, true); + } + asm.mark(MARK_INVOKESPECIAL); + + // -- out of line ------------------------------------------------------- + asm.bindOutOfLine(stub); + XirOperand method = asm.createRegisterTemp("method", CiKind.Word, AMD64.rbx); + asm.mark(MARK_STATIC_CALL_STUB, XirMark.CALLSITE); + asm.mov(method, asm.w(0L)); + XirLabel dummy = asm.createOutOfLineLabel("dummy"); + asm.jmp(dummy); + asm.bindOutOfLine(dummy); + + return asm.finishTemplate(addr, "invokespecial"); + } + }; + + private SimpleTemplates invokeStaticTemplates = new SimpleTemplates() { + + @Override + protected XirTemplate create(CiXirAssembler asm, long flags) { + asm.restart(); + XirParameter addr = asm.createConstantInputParameter("addr", CiKind.Word); + + XirLabel stub = asm.createOutOfLineLabel("call stub"); + asm.mark(MARK_INVOKESTATIC); + + // -- out of line ------------------------------------------------------- + asm.bindOutOfLine(stub); + XirOperand method = asm.createRegisterTemp("method", CiKind.Word, AMD64.rbx); + asm.mark(MARK_STATIC_CALL_STUB, XirMark.CALLSITE); + asm.mov(method, asm.w(0L)); + XirLabel dummy = asm.createOutOfLineLabel("dummy"); + asm.jmp(dummy); + asm.bindOutOfLine(dummy); + + return asm.finishTemplate(addr, "invokestatic"); + } + }; + + private SimpleTemplates monitorEnterTemplates = new SimpleTemplates(NULL_CHECK) { + + @Override + protected XirTemplate create(CiXirAssembler asm, long flags) { + asm.restart(CiKind.Void); + XirParameter object = asm.createInputParameter("object", CiKind.Object); + XirParameter lock = asm.createInputParameter("lock", CiKind.Word); + + if (is(NULL_CHECK, flags)) { + asm.nop(1); + asm.mark(MARK_IMPLICIT_NULL); + asm.pload(CiKind.Word, asm.createTemp("temp", CiKind.Word), object, true); + } + + + // (tw) It is important to use for this runtime call the debug info AFTER the monitor enter. Otherwise the monitor object + // is not correctly garbage collected. + final boolean useInfoAfter = true; + + if (config.useFastLocking) { + useRegisters(asm, AMD64.rbx, AMD64.rsi, AMD64.rdx, AMD64.rax); + asm.callRuntime(config.fastMonitorEnterStub, null, useInfoAfter, object, lock); + } else { + asm.reserveOutgoingStack(target.wordSize * 2); + asm.pstore(CiKind.Object, asm.createRegister("rsp", CiKind.Word, AMD64.RSP.asRegister()), asm.i(target.wordSize), object, false); + asm.pstore(CiKind.Word, asm.createRegister("rsp", CiKind.Word, AMD64.RSP.asRegister()), asm.i(0), lock, false); + asm.callRuntime(config.monitorEnterStub, null, useInfoAfter); + } + + return asm.finishTemplate("monitorEnter"); + } + }; + + private SimpleTemplates monitorExitTemplates = new SimpleTemplates(NULL_CHECK) { + + @Override + protected XirTemplate create(CiXirAssembler asm, long flags) { + asm.restart(CiKind.Void); + XirParameter object = asm.createInputParameter("object", CiKind.Object); + XirParameter lock = asm.createInputParameter("lock", CiKind.Word); + + if (config.useFastLocking) { + useRegisters(asm, AMD64.rbx, AMD64.rsi, AMD64.rdx, AMD64.rax); + asm.callRuntime(config.fastMonitorExitStub, null, object, lock); + } else { + asm.reserveOutgoingStack(target.wordSize); + asm.pstore(CiKind.Word, asm.createRegister("rsp", CiKind.Word, AMD64.RSP.asRegister()), asm.i(0), lock, false); + asm.callRuntime(config.monitorExitStub, null); + } + + return asm.finishTemplate("monitorExit"); + } + }; + + private KindTemplates getFieldTemplates = new KindTemplates(NULL_CHECK, UNRESOLVED) { + + @Override + protected XirTemplate create(CiXirAssembler asm, long flags, CiKind kind) { + XirOperand result = asm.restart(kind); + XirParameter object = asm.createInputParameter("object", CiKind.Object); + + if (is(UNRESOLVED, flags)) { + UnresolvedFieldPatching fieldPatching = new UnresolvedFieldPatching(asm, object, result, false, is(NULL_CHECK, flags), config); + fieldPatching.emitInline(); + // -- out of line ------------------------------------------------------- + fieldPatching.emitOutOfLine(); + return asm.finishTemplate("getfield<" + kind + ">"); + } + XirParameter fieldOffset = asm.createConstantInputParameter("fieldOffset", CiKind.Int); + if (is(NULL_CHECK, flags)) { + asm.nop(1); + asm.mark(MARK_IMPLICIT_NULL); + } + asm.pload(kind, result, object, fieldOffset, is(NULL_CHECK, flags)); + return asm.finishTemplate("getfield<" + kind + ">"); + } + }; + + private KindTemplates writeBarrierTemplate = new KindTemplates() { + + @Override + protected XirTemplate create(CiXirAssembler asm, long flags, CiKind kind) { + asm.restart(CiKind.Void); + XirParameter object = asm.createInputParameter("object", CiKind.Object); + + // Need temp operand, because the write barrier destroys the object pointer. + XirOperand temp = asm.createTemp("temp", CiKind.Object); + asm.mov(temp, object); + + writeBarrier(asm, temp); + return asm.finishTemplate("writeBarrier"); + } + }; + + private KindTemplates putFieldTemplates = new KindTemplates(WRITE_BARRIER, NULL_CHECK, UNRESOLVED) { + + @Override + protected XirTemplate create(CiXirAssembler asm, long flags, CiKind kind) { + asm.restart(CiKind.Void); + XirParameter object = asm.createInputParameter("object", CiKind.Object); + XirParameter value = asm.createInputParameter("value", kind); + + if (is(UNRESOLVED, flags)) { + UnresolvedFieldPatching fieldPatching = new UnresolvedFieldPatching(asm, object, value, true, is(NULL_CHECK, flags), config); + fieldPatching.emitInline(); + // -- out of line ------------------------------------------------------- + fieldPatching.emitOutOfLine(); + return asm.finishTemplate("putfield<" + kind + ">"); + } + XirParameter fieldOffset = asm.createConstantInputParameter("fieldOffset", CiKind.Int); + if (kind == CiKind.Object) { + verifyPointer(asm, value); + } + if (is(NULL_CHECK, flags)) { + asm.nop(1); + asm.mark(MARK_IMPLICIT_NULL); + } + asm.pstore(kind, object, fieldOffset, value, is(NULL_CHECK, flags)); + if (is(WRITE_BARRIER, flags)) { + XirOperand temp = asm.createTemp("temp", CiKind.Word); + asm.mov(temp, object); + writeBarrier(asm, temp); + } + return asm.finishTemplate("putfield<" + kind + ">"); + } + }; + + private final IndexTemplates newInstanceTemplates = new IndexTemplates() { + + @Override + protected XirTemplate create(CiXirAssembler asm, long flags, int size) { + XirOperand result = asm.restart(CiKind.Word); + XirOperand type = asm.createInputParameter("type", CiKind.Object); + + XirOperand temp1 = asm.createRegisterTemp("temp1", CiKind.Word, AMD64.rcx); + XirOperand temp2 = asm.createRegisterTemp("temp2", CiKind.Word, AMD64.rbx); + XirOperand temp2i = asm.createRegisterTemp("temp2i", CiKind.Int, AMD64.rbx); + useRegisters(asm, AMD64.rsi); + XirLabel tlabFull = asm.createOutOfLineLabel("tlab full"); + XirLabel resume = asm.createInlineLabel("resume"); + + // check if the class is already initialized + asm.pload(CiKind.Int, temp2i, type, asm.i(config.klassStateOffset), false); + asm.jneq(tlabFull, temp2i, asm.i(config.klassStateFullyInitialized)); + + XirOperand thread = asm.createRegisterTemp("thread", CiKind.Word, AMD64.r15); + asm.pload(CiKind.Word, result, thread, asm.i(config.threadTlabTopOffset), false); + asm.add(temp1, result, asm.w(size)); + asm.pload(CiKind.Word, temp2, thread, asm.i(config.threadTlabEndOffset), false); + + asm.jgt(tlabFull, temp1, temp2); + asm.pstore(CiKind.Word, thread, asm.i(config.threadTlabTopOffset), temp1, false); + + asm.bindInline(resume); + + asm.pload(CiKind.Word, temp1, type, asm.i(config.instanceHeaderPrototypeOffset), false); + asm.pstore(CiKind.Word, result, temp1, false); + asm.pstore(CiKind.Object, result, asm.i(config.hubOffset), type, false); + + if (size > 2 * target.wordSize) { + asm.mov(temp1, asm.w(0)); + for (int offset = 2 * target.wordSize; offset < size; offset += target.wordSize) { + asm.pstore(CiKind.Word, result, asm.i(offset), temp1, false); + } + } + + // -- out of line ------------------------------------------------------- + asm.bindOutOfLine(tlabFull); + XirOperand arg = asm.createRegisterTemp("runtime call argument", CiKind.Object, AMD64.rdx); + asm.mov(arg, type); + useRegisters(asm, AMD64.rax); + asm.callRuntime(config.newInstanceStub, result); + asm.jmp(resume); + + return asm.finishTemplate("new instance"); + } + }; + + private SimpleTemplates newInstanceUnresolvedTemplates = new SimpleTemplates() { + + @Override + protected XirTemplate create(CiXirAssembler asm, long flags) { + XirOperand result = asm.restart(CiKind.Word); + XirOperand arg = asm.createRegisterTemp("runtime call argument", CiKind.Object, AMD64.rdx); + + UnresolvedClassPatching patching = new UnresolvedClassPatching(asm, arg, config); + + patching.emitInline(); + useRegisters(asm, AMD64.rbx, AMD64.rcx, AMD64.rsi, AMD64.rax); + asm.callRuntime(config.unresolvedNewInstanceStub, result); + + // -- out of line ------------------------------------------------------- + patching.emitOutOfLine(); + + return asm.finishTemplate("new instance"); + } + }; + + private SimpleTemplates newObjectArrayCloneTemplates = new SimpleTemplates() { + + @Override + protected XirTemplate create(CiXirAssembler asm, long flags) { + XirOperand result = asm.restart(CiKind.Object); + XirParameter lengthParam = asm.createInputParameter("length", CiKind.Int, true); + XirParameter src = asm.createInputParameter("src", CiKind.Object); + + // Set up length and hub. + XirOperand length = asm.createRegisterTemp("length", CiKind.Int, AMD64.rbx); + XirOperand hub = asm.createRegisterTemp("hub", CiKind.Object, AMD64.rdx); + asm.pload(CiKind.Object, hub, src, asm.i(config.hubOffset), false); + asm.mov(length, lengthParam); + + useRegisters(asm, AMD64.rsi, AMD64.rcx, AMD64.rdi, AMD64.rax); + asm.callRuntime(config.newObjectArrayStub, result); + return asm.finishTemplate("objectArrayClone"); + } + }; + + private SimpleTemplates newObjectArrayTemplates = new SimpleTemplates(UNRESOLVED) { + + @Override + protected XirTemplate create(CiXirAssembler asm, long flags) { + emitNewTypeArray(asm, flags, CiKind.Object, config.useFastNewObjectArray, config.newObjectArrayStub); + return asm.finishTemplate(is(UNRESOLVED, flags) ? "newObjectArray (unresolved)" : "newObjectArray"); + } + }; + + private void emitNewTypeArray(CiXirAssembler asm, long flags, CiKind kind, boolean useFast, long slowPathStub) { + XirOperand result = asm.restart(CiKind.Word); + + XirParameter lengthParam = asm.createInputParameter("length", CiKind.Int, true); + + XirOperand length = asm.createRegisterTemp("length", CiKind.Int, AMD64.rbx); + XirOperand hub = asm.createRegisterTemp("hub", CiKind.Object, AMD64.rdx); + + // Registers rsi, rcx, rdi, and rax are needed by the runtime call. + // Hub needs to be on rdx, length on rbx. + XirOperand temp1 = asm.createRegisterTemp("temp1", CiKind.Word, AMD64.rcx); + XirOperand temp2 = asm.createRegisterTemp("temp2", CiKind.Word, AMD64.rax); + XirOperand temp3 = asm.createRegisterTemp("temp3", CiKind.Word, AMD64.rdi); + XirOperand size = asm.createRegisterTemp("size", CiKind.Int, AMD64.rsi); + + UnresolvedClassPatching patching = null; + if (is(UNRESOLVED, flags)) { + // insert the patching code for class resolving - the hub will end up in "hub" + patching = new UnresolvedClassPatching(asm, hub, config); + patching.emitInline(); + } else { + asm.mov(hub, asm.createConstantInputParameter("hub", CiKind.Object)); + } + + asm.mov(length, lengthParam); + + if (useFast) { + + XirLabel slowPath = asm.createOutOfLineLabel("slowPath"); + + XirLabel done = asm.createInlineLabel("done"); + + // Check for negative array size. + // TODO: Also check for upper bound + asm.jlt(slowPath, length, asm.i(0)); + + final int aligning = target.wordSize; + final int arrayLengthOffset = target.wordSize * 2; + final int arrayElementOffset = config.getArrayOffset(kind); + + // Calculate aligned size + asm.mov(size, length); + int scale = CiUtil.log2(kind.sizeInBytes(target.wordSize)); + if (scale != 0) { + asm.shl(size, size, asm.i(scale)); + } + asm.add(size, size, asm.i(arrayElementOffset + aligning - 1)); + long mask = 0xFFFFFFFFL; + mask <<= CiUtil.log2(aligning); + asm.and(size, size, asm.i((int) mask)); + + // Try tlab allocation + XirOperand thread = asm.createRegisterTemp("thread", CiKind.Word, AMD64.r15); + asm.pload(CiKind.Word, result, thread, asm.i(config.threadTlabTopOffset), false); + asm.add(temp1, result, size); + asm.pload(CiKind.Word, temp2, thread, asm.i(config.threadTlabEndOffset), false); + asm.jgt(slowPath, temp1, temp2); + asm.pstore(CiKind.Word, thread, asm.i(config.threadTlabTopOffset), temp1, false); + + // Now the new object is in result, store mark word and klass + asm.pload(CiKind.Word, temp1, hub, asm.i(config.instanceHeaderPrototypeOffset), false); + asm.pstore(CiKind.Word, result, temp1, false); + asm.pstore(CiKind.Object, result, asm.i(config.hubOffset), hub, false); + + // Store array length + asm.pstore(CiKind.Int, result, asm.i(arrayLengthOffset), length, false); + + // Initialize with 0 + XirLabel top = asm.createInlineLabel("top"); + asm.sub(size, size, asm.i(arrayElementOffset)); + asm.shr(size, size, asm.i(Scale.Times8.log2)); + asm.jeq(done, size, asm.i(0)); + asm.xor(temp3, temp3, temp3); + asm.bindInline(top); + asm.pstore(CiKind.Word, result, size, temp3, arrayElementOffset - target.wordSize, Scale.Times8, false); + asm.decAndJumpNotZero(top, size); + + asm.bindInline(done); + + // Slow path + asm.bindOutOfLine(slowPath); + asm.callRuntime(slowPathStub, result); + asm.jmp(done); + } else { + asm.callRuntime(slowPathStub, result); + } + + if (patching != null) { + patching.emitOutOfLine(); + } + } + + private KindTemplates newTypeArrayTemplates = new KindTemplates() { + @Override + protected XirTemplate create(CiXirAssembler asm, long flags, CiKind kind) { + emitNewTypeArray(asm, flags, kind, config.useFastNewTypeArray, config.newTypeArrayStub); + return asm.finishTemplate("newTypeArray<" + kind.toString() + ">"); + } + }; + + private final IndexTemplates multiNewArrayTemplate = new IndexTemplates(UNRESOLVED) { + + @Override + protected XirTemplate create(CiXirAssembler asm, long flags, int dimensions) { + XirOperand result = asm.restart(CiKind.Object); + + XirOperand hub = asm.createRegisterTemp("hub", CiKind.Object, AMD64.rax); + XirOperand rank = asm.createRegisterTemp("rank", CiKind.Int, AMD64.rbx); + XirOperand sizes = asm.createRegisterTemp("sizes", CiKind.Long, AMD64.rcx); + XirOperand thread = asm.createRegisterTemp("thread", CiKind.Long, AMD64.r15); + asm.add(sizes, thread, asm.l(config.threadMultiNewArrayStorage)); + for (int i = 0; i < dimensions; i++) { + XirParameter length = asm.createInputParameter("length" + i, CiKind.Int, true); + asm.pstore(CiKind.Int, sizes, asm.i(i * target.sizeInBytes(CiKind.Int)), length, false); + } + + UnresolvedClassPatching patching = null; + if (is(UNRESOLVED, flags)) { + // insert the patching code for class resolving - the hub will end up in "hub" + patching = new UnresolvedClassPatching(asm, hub, config); + patching.emitInline(); + } else { + asm.mov(hub, asm.createConstantInputParameter("hub", CiKind.Object)); + } + + asm.mov(rank, asm.i(dimensions)); + useRegisters(asm, AMD64.rax); + asm.callRuntime(config.newMultiArrayStub, result); + if (is(UNRESOLVED, flags)) { + patching.emitOutOfLine(); + } + return asm.finishTemplate(is(UNRESOLVED, flags) ? "multiNewArray" + dimensions + " (unresolved)" : "multiNewArray" + dimensions); + } + }; + + private SimpleTemplates checkCastTemplates = new SimpleTemplates(NULL_CHECK, UNRESOLVED) { + + @Override + protected XirTemplate create(CiXirAssembler asm, long flags) { + asm.restart(); + XirParameter object = asm.createInputParameter("object", CiKind.Object); + final XirOperand hub; + final UnresolvedClassPatching patching; + if (is(UNRESOLVED, flags)) { + hub = asm.createTemp("hub", CiKind.Object); + // insert the patching code for class resolving - the hub will end up in "hub" + patching = new UnresolvedClassPatching(asm, hub, config); + patching.emitInline(); + } else { + hub = asm.createConstantInputParameter("hub", CiKind.Object); + patching = null; + } + + XirOperand objHub = asm.createTemp("objHub", CiKind.Object); + + XirLabel end = asm.createInlineLabel("end"); + XirLabel slowPath = asm.createOutOfLineLabel("slow path"); + + if (is(NULL_CHECK, flags)) { + // null can be cast to anything + asm.jeq(end, object, asm.o(null)); + } + + asm.pload(CiKind.Object, objHub, object, asm.i(config.hubOffset), false); + // if we get an exact match: succeed immediately + asm.jneq(slowPath, objHub, hub); + asm.bindInline(end); + + // -- out of line ------------------------------------------------------- + asm.bindOutOfLine(slowPath); + checkSubtype(asm, objHub, objHub, hub); + asm.jneq(end, objHub, asm.o(null)); + XirOperand scratch = asm.createRegisterTemp("scratch", CiKind.Object, AMD64.r10); + asm.mov(scratch, object); + asm.callRuntime(config.throwClassCastException, null); + asm.shouldNotReachHere(); + + if (is(UNRESOLVED, flags)) { + patching.emitOutOfLine(); + } + + return asm.finishTemplate(object, "instanceof"); + } + }; + + private SimpleTemplates instanceOfTemplates = new SimpleTemplates(NULL_CHECK, UNRESOLVED) { + + @Override + protected XirTemplate create(CiXirAssembler asm, long flags) { + XirOperand result = asm.restart(CiKind.Boolean); + XirParameter object = asm.createInputParameter("object", CiKind.Object); + final XirOperand hub; + final UnresolvedClassPatching patching; + if (is(UNRESOLVED, flags)) { + hub = asm.createTemp("hub", CiKind.Object); + // insert the patching code for class resolving - the hub will end up in "hub" + patching = new UnresolvedClassPatching(asm, hub, config); + patching.emitInline(); + } else { + hub = asm.createConstantInputParameter("hub", CiKind.Object); + patching = null; + } + + XirOperand objHub = asm.createTemp("objHub", CiKind.Object); + + XirLabel end = asm.createInlineLabel("end"); + XirLabel slowPath = asm.createOutOfLineLabel("slow path"); + + if (is(NULL_CHECK, flags)) { + // null isn't "instanceof" anything + asm.mov(result, asm.b(false)); + asm.jeq(end, object, asm.o(null)); + } + + asm.pload(CiKind.Object, objHub, object, asm.i(config.hubOffset), false); + // if we get an exact match: succeed immediately + asm.mov(result, asm.b(true)); + asm.jneq(slowPath, objHub, hub); + asm.bindInline(end); + + // -- out of line ------------------------------------------------------- + asm.bindOutOfLine(slowPath); + checkSubtype(asm, result, objHub, hub); + asm.jmp(end); + + if (is(UNRESOLVED, flags)) { + patching.emitOutOfLine(); + } + + return asm.finishTemplate("instanceof"); + } + }; + + private XirOperand genArrayLength(XirOperand array, boolean implicitNullException) { + XirOperand length = asm.createTemp("length", CiKind.Int); + genArrayLength(asm, length, array, implicitNullException); + return length; + } + + private void genArrayLength(CiXirAssembler asm, XirOperand length, XirOperand array, boolean implicitNullException) { + if (implicitNullException) { + // asm.nop(1); + asm.mark(MARK_IMPLICIT_NULL); + } + asm.pload(CiKind.Int, length, array, asm.i(config.arrayLengthOffset), implicitNullException); + } + + private KindTemplates arrayLoadTemplates = new KindTemplates(NULL_CHECK, READ_BARRIER, BOUNDS_CHECK, GIVEN_LENGTH) { + + @Override + protected XirTemplate create(CiXirAssembler asm, long flags, CiKind kind) { + XirOperand result = asm.restart(kind); + XirParameter array = asm.createInputParameter("array", CiKind.Object); + XirParameter index = asm.createInputParameter("index", CiKind.Int, true); + XirLabel failBoundsCheck = null; + // if the length is known the array cannot be null + boolean implicitNullException = is(NULL_CHECK, flags); + + if (is(BOUNDS_CHECK, flags)) { + // load the array length and check the index + failBoundsCheck = asm.createOutOfLineLabel("failBoundsCheck"); + XirOperand length; + if (is(GIVEN_LENGTH, flags)) { + length = asm.createInputParameter("length", CiKind.Int, true); + } else { + length = genArrayLength(array, implicitNullException); + } + asm.jugteq(failBoundsCheck, index, length); + implicitNullException = false; + } + int elemSize = target.sizeInBytes(kind); + if (implicitNullException) { + asm.nop(1); + asm.mark(MARK_IMPLICIT_NULL); + } + asm.pload(kind, result, array, index, config.getArrayOffset(kind), Scale.fromInt(elemSize), implicitNullException); + if (is(BOUNDS_CHECK, flags)) { + asm.bindOutOfLine(failBoundsCheck); + asm.callRuntime(config.throwArrayIndexException, null); + asm.shouldNotReachHere(); + } + return asm.finishTemplate("arrayload<" + kind + ">"); + } + }; + + private SimpleTemplates getClassTemplates = new SimpleTemplates() { + @Override + protected XirTemplate create(CiXirAssembler asm, long flags) { + XirOperand result = asm.restart(CiKind.Object); + XirOperand object = asm.createInputParameter("object", CiKind.Object); + asm.pload(CiKind.Object, result, object, asm.i(config.hubOffset), is(NULL_CHECK, flags)); + asm.pload(CiKind.Object, result, result, asm.i(config.classMirrorOffset), false); + return asm.finishTemplate("currentThread"); + } + }; + + private SimpleTemplates currentThreadTemplates = new SimpleTemplates() { + @Override + protected XirTemplate create(CiXirAssembler asm, long flags) { + XirOperand result = asm.restart(CiKind.Object); + XirOperand thread = asm.createRegisterTemp("thread", CiKind.Word, AMD64.r15); + asm.pload(CiKind.Object, result, thread, asm.i(config.threadObjectOffset), false); + return asm.finishTemplate("currentThread"); + } + }; + + @Override + public XirSnippet genCurrentThread(XirSite site) { + return new XirSnippet(currentThreadTemplates.get(site)); + } + + @Override + public XirSnippet genGetClass(XirSite site, XirArgument object) { + return new XirSnippet(getClassTemplates.get(site), object); + } + + private KindTemplates arrayCopyTemplates = new KindTemplates() { + + @Override + protected XirTemplate create(CiXirAssembler asm, long flags, CiKind kind) { + asm.restart(CiKind.Void); + XirParameter src = asm.createInputParameter("src", CiKind.Object); + XirParameter srcPos = asm.createInputParameter("srcPos", CiKind.Int, true); + XirParameter dest = asm.createInputParameter("dest", CiKind.Object); + XirParameter destPos = asm.createInputParameter("destPos", CiKind.Int, true); + XirParameter length = asm.createInputParameter("length", CiKind.Int, true); + + XirOperand tempSrc = asm.createTemp("tempSrc", CiKind.Word); + XirOperand tempDest = asm.createTemp("tempDest", CiKind.Word); + XirOperand lengthOperand = asm.createRegisterTemp("lengthOperand", CiKind.Int, AMD64.rax); + + XirOperand compHub = null; + XirOperand valueHub = null; + XirOperand temp = null; + XirLabel store = null; + XirLabel slowStoreCheck = null; + + if (is(STORE_CHECK, flags)) { + valueHub = asm.createRegisterTemp("valueHub", CiKind.Word, AMD64.rdi); + compHub = asm.createRegisterTemp("compHub", CiKind.Word, AMD64.rsi); + temp = asm.createRegisterTemp("temp", CiKind.Word, AMD64.r10); + } + + // Calculate the factor for the repeat move instruction. + int elementSize = kind.sizeInBytes(target.wordSize); + int factor; + boolean wordSize; + if (elementSize >= target.wordSize) { + assert elementSize % target.wordSize == 0; + wordSize = true; + factor = elementSize / target.wordSize; + } else { + factor = elementSize; + wordSize = false; + } + + // Adjust the length if the factor is not 1. + if (factor != 1) { + asm.shl(lengthOperand, length, asm.i(CiUtil.log2(factor))); + } else { + asm.mov(lengthOperand, length); + } + + // Set the start and the end pointer. + asm.lea(tempSrc, src, srcPos, config.getArrayOffset(kind), Scale.fromInt(elementSize)); + asm.lea(tempDest, dest, destPos, config.getArrayOffset(kind), Scale.fromInt(elementSize)); + + XirLabel reverse = null; + XirLabel normal = null; + + if (is(STORE_CHECK, flags)) { + reverse = asm.createInlineLabel("reverse"); + asm.jneq(reverse, src, dest); + } + + if (!is(STORE_CHECK, flags) && !is(INPUTS_DIFFERENT, flags) && !is(INPUTS_SAME, flags)) { + normal = asm.createInlineLabel("normal"); + asm.jneq(normal, src, dest); + } + + if (!is(INPUTS_DIFFERENT, flags)) { + if (reverse == null) { + reverse = asm.createInlineLabel("reverse"); + } + asm.jlt(reverse, srcPos, destPos); + } + + if (!is(STORE_CHECK, flags) && !is(INPUTS_DIFFERENT, flags) && !is(INPUTS_SAME, flags)) { + asm.bindInline(normal); + } + + // Everything set up => repeat mov. + if (wordSize) { + asm.repmov(tempSrc, tempDest, lengthOperand); + } else { + asm.repmovb(tempSrc, tempDest, lengthOperand); + } + + if (!is(INPUTS_DIFFERENT, flags) || is(STORE_CHECK, flags)) { + + XirLabel end = asm.createInlineLabel("end"); + asm.jmp(end); + + // Implement reverse copy, because srcPos < destPos and src == dest. + asm.bindInline(reverse); + + if (is(STORE_CHECK, flags)) { + asm.pload(CiKind.Object, compHub, dest, asm.i(config.hubOffset), false); + asm.pload(CiKind.Object, compHub, compHub, asm.i(config.arrayClassElementOffset), false); + } + + CiKind copyKind = wordSize ? CiKind.Object : CiKind.Byte; + XirOperand tempValue = asm.createTemp("tempValue", copyKind); + XirLabel start = asm.createInlineLabel("start"); + asm.bindInline(start); + asm.sub(lengthOperand, lengthOperand, asm.i(1)); + asm.jlt(end, lengthOperand, asm.i(0)); + + Scale scale = wordSize ? Scale.fromInt(target.wordSize) : Scale.Times1; + asm.pload(copyKind, tempValue, tempSrc, lengthOperand, 0, scale, false); + + if (is(STORE_CHECK, flags)) { + slowStoreCheck = asm.createOutOfLineLabel("slowStoreCheck"); + store = asm.createInlineLabel("store"); + asm.jeq(store, tempValue, asm.o(null)); // first check if value is null + asm.pload(CiKind.Object, valueHub, tempValue, asm.i(config.hubOffset), false); + asm.jneq(slowStoreCheck, compHub, valueHub); // then check component hub matches value hub + asm.bindInline(store); + } + + asm.pstore(copyKind, tempDest, lengthOperand, tempValue, 0, scale, false); + + asm.jmp(start); + asm.bindInline(end); + } + + if (kind == CiKind.Object) { + // Do write barriers + asm.lea(tempDest, dest, destPos, config.getArrayOffset(kind), Scale.fromInt(elementSize)); + asm.shr(tempDest, tempDest, asm.i(config.cardtableShift)); + asm.pstore(CiKind.Boolean, asm.w(config.cardtableStartAddress), tempDest, asm.b(false), false); + + XirOperand tempDestEnd = tempSrc; // Reuse src temp + asm.lea(tempDestEnd, dest, destPos, config.getArrayOffset(kind), Scale.fromInt(elementSize)); + asm.add(tempDestEnd, tempDestEnd, length); + asm.shr(tempDestEnd, tempDestEnd, asm.i(config.cardtableShift)); + + // Jump to out-of-line write barrier loop if the array is big. + XirLabel writeBarrierLoop = asm.createOutOfLineLabel("writeBarrierLoop"); + asm.jneq(writeBarrierLoop, tempDest, tempSrc); + XirLabel back = asm.createInlineLabel("back"); + asm.bindInline(back); + + asm.bindOutOfLine(writeBarrierLoop); + asm.pstore(CiKind.Boolean, asm.w(config.cardtableStartAddress), tempDestEnd, asm.b(false), false); + asm.sub(tempDestEnd, tempDestEnd, asm.i(1)); + asm.jneq(writeBarrierLoop, tempDestEnd, tempDest); + asm.jmp(back); + } + + if (is(STORE_CHECK, flags)) { + assert kind == CiKind.Object; + useRegisters(asm, AMD64.rax); + asm.bindOutOfLine(slowStoreCheck); + checkSubtype(asm, temp, valueHub, compHub); + asm.jneq(store, temp, asm.w(0)); + asm.callRuntime(config.throwArrayStoreException, null); + asm.jmp(store); + } + + return asm.finishTemplate("arraycopy<" + kind + ">"); + } + }; + + private KindTemplates arrayStoreTemplates = new KindTemplates(NULL_CHECK, WRITE_BARRIER, BOUNDS_CHECK, STORE_CHECK, GIVEN_LENGTH) { + + @Override + protected XirTemplate create(CiXirAssembler asm, long flags, CiKind kind) { + asm.restart(CiKind.Void); + XirParameter array = asm.createInputParameter("array", CiKind.Object); + XirParameter index = asm.createInputParameter("index", CiKind.Int, true); + XirParameter value = asm.createInputParameter("value", kind, kind != CiKind.Object); + XirOperand temp = asm.createTemp("temp", CiKind.Word); + XirOperand valueHub = null; + XirOperand compHub = null; + XirLabel store = asm.createInlineLabel("store"); + XirLabel failBoundsCheck = null; + XirLabel slowStoreCheck = null; + // if the length is known the array cannot be null + boolean implicitNullException = is(NULL_CHECK, flags); + + if (is(BOUNDS_CHECK, flags)) { + // load the array length and check the index + failBoundsCheck = asm.createOutOfLineLabel("failBoundsCheck"); + XirOperand length; + if (is(GIVEN_LENGTH, flags)) { + length = asm.createInputParameter("length", CiKind.Int); + } else { + length = asm.createTemp("length", CiKind.Int); + if (implicitNullException) { + asm.nop(1); + asm.mark(MARK_IMPLICIT_NULL); + } + asm.pload(CiKind.Int, length, array, asm.i(config.arrayLengthOffset), implicitNullException); + implicitNullException = false; + } + asm.jugteq(failBoundsCheck, index, length); + + } + if (is(STORE_CHECK, flags) && kind == CiKind.Object) { + slowStoreCheck = asm.createOutOfLineLabel("slowStoreCheck"); + asm.jeq(store, value, asm.o(null)); // first check if value is null + valueHub = asm.createTemp("valueHub", CiKind.Object); + compHub = asm.createTemp("compHub", CiKind.Object); + if (implicitNullException) { + asm.mark(MARK_IMPLICIT_NULL); + } + asm.pload(CiKind.Object, compHub, array, asm.i(config.hubOffset), implicitNullException); + asm.pload(CiKind.Object, compHub, compHub, asm.i(config.arrayClassElementOffset), false); + asm.pload(CiKind.Object, valueHub, value, asm.i(config.hubOffset), false); + asm.jneq(slowStoreCheck, compHub, valueHub); // then check component hub matches value hub + + implicitNullException = false; + } + asm.bindInline(store); + int elemSize = target.sizeInBytes(kind); + + if (implicitNullException) { + asm.mark(MARK_IMPLICIT_NULL); + } + int disp = config.getArrayOffset(kind); + Scale scale = Scale.fromInt(elemSize); + if (kind == CiKind.Object) { + verifyPointer(asm, value); + } + if (is(WRITE_BARRIER, flags)) { + asm.lea(temp, array, index, disp, scale); + asm.pstore(kind, temp, value, implicitNullException); + writeBarrier(asm, temp); + } else { + asm.pstore(kind, array, index, value, disp, scale, implicitNullException); + } + + // -- out of line ------------------------------------------------------- + if (is(BOUNDS_CHECK, flags)) { + asm.bindOutOfLine(failBoundsCheck); + asm.callRuntime(config.throwArrayIndexException, null); + asm.shouldNotReachHere(); + } + if (is(STORE_CHECK, flags) && kind == CiKind.Object) { + useRegisters(asm, AMD64.rax); + asm.bindOutOfLine(slowStoreCheck); + checkSubtype(asm, temp, valueHub, compHub); + asm.jneq(store, temp, asm.w(0)); + asm.callRuntime(config.throwArrayStoreException, null); + asm.jmp(store); + } + return asm.finishTemplate("arraystore<" + kind + ">"); + } + }; + + private SimpleTemplates arrayLengthTemplates = new SimpleTemplates(NULL_CHECK) { + + @Override + protected XirTemplate create(CiXirAssembler asm, long flags) { + XirOperand result = asm.restart(CiKind.Int); + XirParameter object = asm.createInputParameter("object", CiKind.Object); + if (is(NULL_CHECK, flags)) { + asm.nop(1); + asm.mark(MARK_IMPLICIT_NULL); + } + verifyPointer(asm, object); + asm.pload(CiKind.Int, result, object, asm.i(config.arrayLengthOffset), true); + return asm.finishTemplate("arrayLength"); + } + }; + + @Override + public XirSnippet genPrologue(XirSite site, RiMethod method) { + boolean staticMethod = Modifier.isStatic(method.accessFlags()); + return new XirSnippet(staticMethod ? prologueTemplates.get(site, STATIC_METHOD) : prologueTemplates.get(site)); + } + + @Override + public XirSnippet genEpilogue(XirSite site, RiMethod method) { + return new XirSnippet(epilogueTemplates.get(site)); + } + + @Override + public XirSnippet genSafepoint(XirSite site) { + return new XirSnippet(safepointTemplates.get(site)); + } + + @Override + public XirSnippet genExceptionObject(XirSite site) { + return new XirSnippet(exceptionObjectTemplates.get(site)); + } + + @Override + public XirSnippet genResolveClass(XirSite site, RiType type, Representation rep) { + assert rep == Representation.ObjectHub || rep == Representation.StaticFields || rep == Representation.JavaClass : "unexpected representation: " + rep; + if (type instanceof HotSpotTypeResolved) { + return new XirSnippet(resolveClassTemplates.get(site), XirArgument.forObject(type)); + } + return new XirSnippet(resolveClassTemplates.get(site, UNRESOLVED)); + } + + @Override + public XirSnippet genIntrinsic(XirSite site, XirArgument[] arguments, RiMethod method) { + return null; + } + + @Override + public XirSnippet genInvokeInterface(XirSite site, XirArgument receiver, RiMethod method) { + return new XirSnippet(invokeInterfaceTemplates.get(site), receiver, XirArgument.forWord(0)); + } + + @Override + public XirSnippet genInvokeVirtual(XirSite site, XirArgument receiver, RiMethod method) { + return new XirSnippet(invokeVirtualTemplates.get(site), receiver, XirArgument.forWord(0)); + } + + @Override + public XirSnippet genInvokeSpecial(XirSite site, XirArgument receiver, RiMethod method) { + return new XirSnippet(invokeSpecialTemplates.get(site), receiver, XirArgument.forWord(0)); + } + + @Override + public XirSnippet genInvokeStatic(XirSite site, RiMethod method) { + return new XirSnippet(invokeStaticTemplates.get(site), XirArgument.forWord(0)); + } + + @Override + public XirSnippet genMonitorEnter(XirSite site, XirArgument receiver, XirArgument lockAddress) { + return new XirSnippet(monitorEnterTemplates.get(site), receiver, lockAddress); + } + + @Override + public XirSnippet genMonitorExit(XirSite site, XirArgument receiver, XirArgument lockAddress) { + return new XirSnippet(monitorExitTemplates.get(site), receiver, lockAddress); + } + + @Override + public XirSnippet genGetField(XirSite site, XirArgument object, RiField field) { + if (field.isResolved()) { + return new XirSnippet(getFieldTemplates.get(site, field.kind()), object, XirArgument.forInt(((HotSpotField) field).offset())); + } + return new XirSnippet(getFieldTemplates.get(site, field.kind(), UNRESOLVED), object); + } + + @Override + public XirSnippet genWriteBarrier(XirArgument object) { + return new XirSnippet(writeBarrierTemplate.get(null, CiKind.Void), object); + } + + @Override + public XirSnippet genPutField(XirSite site, XirArgument object, RiField field, XirArgument value) { + if (field.isResolved()) { + return new XirSnippet(putFieldTemplates.get(site, field.kind()), object, value, XirArgument.forInt(((HotSpotField) field).offset())); + } + return new XirSnippet(putFieldTemplates.get(site, field.kind(), UNRESOLVED), object, value); + } + + @Override + public XirSnippet genGetStatic(XirSite site, XirArgument object, RiField field) { + if (field.isResolved()) { + return new XirSnippet(getFieldTemplates.get(site, field.kind()), object, XirArgument.forInt(((HotSpotField) field).offset())); + } + return new XirSnippet(getFieldTemplates.get(site, field.kind(), UNRESOLVED), object); + } + + @Override + public XirSnippet genPutStatic(XirSite site, XirArgument object, RiField field, XirArgument value) { + if (field.isResolved()) { + return new XirSnippet(putFieldTemplates.get(site, field.kind()), object, value, XirArgument.forInt(((HotSpotField) field).offset())); + } + return new XirSnippet(putFieldTemplates.get(site, field.kind(), UNRESOLVED), object, value); + } + + @Override + public XirSnippet genNewInstance(XirSite site, RiType type) { + if (type instanceof HotSpotTypeResolved) { + int instanceSize = ((HotSpotTypeResolved) type).instanceSize(); + return new XirSnippet(newInstanceTemplates.get(site, instanceSize), XirArgument.forObject(type)); + } + return new XirSnippet(newInstanceUnresolvedTemplates.get(site)); + } + + @Override + public XirSnippet genNewArray(XirSite site, XirArgument length, CiKind elementKind, RiType componentType, RiType arrayType) { + if (elementKind == CiKind.Object) { + if (arrayType instanceof HotSpotTypeResolved) { + return new XirSnippet(newObjectArrayTemplates.get(site), length, XirArgument.forObject(arrayType)); + } + return new XirSnippet(newObjectArrayTemplates.get(site, UNRESOLVED), length); + } + assert arrayType == null; + arrayType = Compiler.getVMEntries().getPrimitiveArrayType(elementKind); + return new XirSnippet(newTypeArrayTemplates.get(site, elementKind), length, XirArgument.forObject(arrayType)); + } + + @Override + public XirSnippet genNewObjectArrayClone(XirSite site, XirArgument newLength, XirArgument referenceArray) { + return new XirSnippet(newObjectArrayCloneTemplates.get(site), newLength, referenceArray); + } + + @Override + public XirSnippet genNewMultiArray(XirSite site, XirArgument[] lengths, RiType type) { + if (type instanceof HotSpotTypeResolved) { + XirArgument[] params = Arrays.copyOf(lengths, lengths.length + 1); + params[lengths.length] = XirArgument.forObject(type); + return new XirSnippet(multiNewArrayTemplate.get(site, lengths.length), params); + } + return new XirSnippet(multiNewArrayTemplate.get(site, lengths.length, UNRESOLVED), lengths); + } + + @Override + public XirSnippet genCheckCast(XirSite site, XirArgument receiver, XirArgument hub, RiType type) { + if (type.isResolved()) { + return new XirSnippet(checkCastTemplates.get(site), receiver, hub); + } + return new XirSnippet(checkCastTemplates.get(site, UNRESOLVED), receiver); + } + + @Override + public XirSnippet genInstanceOf(XirSite site, XirArgument object, XirArgument hub, RiType type) { + if (type.isResolved()) { + return new XirSnippet(instanceOfTemplates.get(site), object, hub); + } + return new XirSnippet(instanceOfTemplates.get(site, UNRESOLVED), object); + } + + @Override + public XirSnippet genArrayLoad(XirSite site, XirArgument array, XirArgument index, XirArgument length, CiKind elementKind, RiType elementType) { + if (length == null || !site.requiresBoundsCheck()) { + return new XirSnippet(arrayLoadTemplates.get(site, elementKind), array, index); + } + return new XirSnippet(arrayLoadTemplates.get(site, elementKind, GIVEN_LENGTH), array, index, length); + } + + @Override + public XirSnippet genArrayStore(XirSite site, XirArgument array, XirArgument index, XirArgument length, XirArgument value, CiKind elementKind, RiType elementType) { + if (length == null || !site.requiresBoundsCheck()) { + return new XirSnippet(arrayStoreTemplates.get(site, elementKind), array, index, value); + } + return new XirSnippet(arrayStoreTemplates.get(site, elementKind, GIVEN_LENGTH), array, index, value, length); + } + + @Override + public XirSnippet genArrayCopy(XirSite site, XirArgument src, XirArgument srcPos, XirArgument dest, XirArgument destPos, XirArgument length, RiType elementType, boolean inputsSame, boolean inputsDifferent) { + if (elementType == null) { + return null; + } + assert !inputsDifferent || !inputsSame; + XirTemplate template = null; + if (inputsDifferent) { + template = arrayCopyTemplates.get(site, elementType.kind(), INPUTS_DIFFERENT); + } else if (inputsSame) { + template = arrayCopyTemplates.get(site, elementType.kind(), INPUTS_SAME); + } else { + template = arrayCopyTemplates.get(site, elementType.kind()); + } + return new XirSnippet(template, src, srcPos, dest, destPos, length); + } + + @Override + public XirSnippet genArrayLength(XirSite site, XirArgument array) { + return new XirSnippet(arrayLengthTemplates.get(site), array); + } + + @Override + public List buildTemplates(CiXirAssembler asm) { + this.asm = asm; + List templates = new ArrayList(); + return templates; + } + + private static class UnresolvedClassPatching { + + private final XirLabel patchSite; + private final XirLabel replacement; + private final XirLabel patchStub; + private final CiXirAssembler asm; + private final HotSpotVMConfig config; + private final XirOperand arg; + private State state; + + private enum State { + New, Inline, Finished + } + + public UnresolvedClassPatching(CiXirAssembler asm, XirOperand arg, HotSpotVMConfig config) { + this.asm = asm; + this.arg = arg; + this.config = config; + patchSite = asm.createInlineLabel("patch site"); + replacement = asm.createOutOfLineLabel("replacement"); + patchStub = asm.createOutOfLineLabel("patch stub"); + + state = State.New; + } + + public void emitInline() { + assert state == State.New; + + asm.bindInline(patchSite); + asm.mark(MARK_DUMMY_OOP_RELOCATION); + + asm.jmp(patchStub); + + // TODO: make this more generic & safe - this is needed to create space for patching + asm.nop(5); + + state = State.Inline; + } + + public void emitOutOfLine() { + assert state == State.Inline; + + asm.bindOutOfLine(replacement); + XirMark begin = asm.mark(null); + asm.mov(arg, asm.createConstant(CiConstant.NULL_OBJECT)); + XirMark end = asm.mark(null); + // make this piece of data look like an instruction + asm.rawBytes(new byte[] {(byte) 0xb8, 0, 0, 0x05, 0}); + asm.mark(MARK_KLASS_PATCHING, begin, end); + asm.bindOutOfLine(patchStub); + asm.callRuntime(config.loadKlassStub, null); + asm.jmp(patchSite); + + state = State.Finished; + } + } + + private static class UnresolvedFieldPatching { + + private final XirLabel patchSite; + private final XirLabel replacement; + private final XirLabel patchStub; + private final CiXirAssembler asm; + private final HotSpotVMConfig config; + private State state; + private final XirOperand receiver; + private final XirOperand value; + private final boolean put; + private final boolean nullCheck; + + private enum State { + New, Inline, Finished + } + + public UnresolvedFieldPatching(CiXirAssembler asm, XirOperand receiver, XirOperand value, boolean put, boolean nullCheck, HotSpotVMConfig config) { + this.asm = asm; + this.receiver = receiver; + this.value = value; + this.put = put; + this.nullCheck = nullCheck; + this.config = config; + patchSite = asm.createInlineLabel("patch site"); + replacement = asm.createOutOfLineLabel("replacement"); + patchStub = asm.createOutOfLineLabel("patch stub"); + + state = State.New; + } + + public void emitInline() { + assert state == State.New; + if (nullCheck) { + asm.nop(1); + } + asm.bindInline(patchSite); + asm.mark(MARK_DUMMY_OOP_RELOCATION); + if (nullCheck) { + asm.mark(MARK_IMPLICIT_NULL); + } + asm.safepoint(); + asm.jmp(patchStub); + + // TODO: make this more generic & safe - this is needed to create space for patching + asm.nop(5); + + state = State.Inline; + } + + public void emitOutOfLine() { + assert state == State.Inline; + + asm.bindOutOfLine(replacement); + XirMark begin = asm.mark(null); + if (put) { + asm.pstore(value.kind, receiver, asm.i(Integer.MAX_VALUE), value, false); + } else { + asm.pload(value.kind, value, receiver, asm.i(Integer.MAX_VALUE), false); + } + XirMark end = asm.mark(null); + // make this piece of data look like an instruction + asm.rawBytes(new byte[] {(byte) 0xb8, 0, 0, 0x05, 0}); + asm.mark(MARK_ACCESS_FIELD_PATCHING, begin, end); + asm.bindOutOfLine(patchStub); + asm.callRuntime(config.accessFieldStub, null); + asm.jmp(patchSite); + + // Check if we need NOP instructions like in C1 to "not destroy the world". + + state = State.Finished; + } + } + + private void verifyPointer(CiXirAssembler asm, XirOperand pointer) { + if (config.verifyPointers) { + // The verify pointer stub wants the argument in a fixed register. + XirOperand fixed = asm.createRegisterTemp("fixed", CiKind.Object, AMD64.r13); + asm.push(fixed); + asm.mov(fixed, pointer); + asm.callRuntime(config.verifyPointerStub, null); + asm.pop(fixed); + } + } + + private void checkSubtype(CiXirAssembler asm, XirOperand result, XirOperand objHub, XirOperand hub) { + asm.push(objHub); + asm.push(hub); + asm.callRuntime(config.instanceofStub, null); + asm.pop(result); + asm.pop(result); + } + + private void useRegisters(CiXirAssembler asm, CiRegister... registers) { + if (registers != null) { + for (CiRegister register : registers) { + asm.createRegisterTemp("reg", CiKind.Illegal, register); + } + } + } + + private void writeBarrier(CiXirAssembler asm, XirOperand base) { + asm.shr(base, base, asm.i(config.cardtableShift)); + asm.pstore(CiKind.Boolean, asm.w(config.cardtableStartAddress), base, asm.b(false), false); + } + + public boolean is(TemplateFlag check, long flags) { + return (flags & check.bits()) == check.bits(); + } + + /** + * Base class for all the ondemand template generators. It is not normally subclassed directly, but through one of + * its subclasses (SimpleTemplates, KindTemplates, IndexTemplates). + * + * @author Lukas Stadler + */ + private abstract class Templates { + + private ConcurrentHashMap templates = new ConcurrentHashMap(); + private final long mask; + + /** + * Each flag passed to this method will cause templates with and without it to be generated. + */ + public Templates(TemplateFlag... flags) { + this.mask = getBits((int) INDEX_MASK, null, flags); + } + + protected abstract XirTemplate create(CiXirAssembler asm, long flags); + + protected long getBits(int index, XirSite site, TemplateFlag... flags) { + long bits = index; + if (site != null) { + bits |= site.requiresNullCheck() ? NULL_CHECK.bits() : 0; + bits |= site.requiresReadBarrier() ? READ_BARRIER.bits() : 0; + bits |= site.requiresWriteBarrier() ? WRITE_BARRIER.bits() : 0; + bits |= site.requiresArrayStoreCheck() ? STORE_CHECK.bits() : 0; + bits |= site.requiresBoundsCheck() ? BOUNDS_CHECK.bits() : 0; + } + if (flags != null) { + for (TemplateFlag flag : flags) { + bits |= flag.bits(); + } + } + return bits; + } + + protected XirTemplate getInternal(long flags) { + flags = flags & mask; + XirTemplate template = templates.get(flags); + if (template == null) { + template = create(HotSpotXirGenerator.this.asm.copy(), flags); + templates.put(flags, template); + } + return template; + } + } + + private abstract class SimpleTemplates extends Templates { + + public SimpleTemplates(TemplateFlag... flags) { + super(flags); + } + + public XirTemplate get(XirSite site, TemplateFlag... flags) { + return getInternal(getBits(0, site, flags)); + } + } + + private abstract class IndexTemplates extends Templates { + + public IndexTemplates(TemplateFlag... flags) { + super(flags); + } + + @Override + protected final XirTemplate create(CiXirAssembler asm, long flags) { + return create(asm, flags & FLAGS_MASK, (int) (flags & INDEX_MASK)); + } + + protected abstract XirTemplate create(CiXirAssembler asm, long flags, int index); + + public XirTemplate get(XirSite site, int size, TemplateFlag... flags) { + return getInternal(getBits(size, site, flags)); + } + } + + private abstract class KindTemplates extends Templates { + + public KindTemplates(TemplateFlag... flags) { + super(flags); + } + + @Override + protected final XirTemplate create(CiXirAssembler asm, long flags) { + return create(asm, flags & FLAGS_MASK, CiKind.VALUES[(int) (flags & INDEX_MASK)]); + } + + protected abstract XirTemplate create(CiXirAssembler asm, long flags, CiKind kind); + + public XirTemplate get(XirSite site, CiKind kind, TemplateFlag... flags) { + return getInternal(getBits(kind.ordinal(), site, flags)); + } + } +} diff -r 102466e70deb -r 91fe28b03d6a c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/InvocationSocket.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/InvocationSocket.java Wed Jan 26 18:17:37 2011 +0100 @@ -0,0 +1,142 @@ +/* + * Copyright (c) 2010 Sun Microsystems, Inc. All rights reserved. + * + * Sun Microsystems, Inc. has intellectual property rights relating to technology embodied in the product + * that is described in this document. In particular, and without limitation, these intellectual property + * rights may include one or more of the U.S. patents listed at http://www.sun.com/patents and one or + * more additional patents or pending patent applications in the U.S. and in other countries. + * + * U.S. Government Rights - Commercial software. Government users are subject to the Sun + * Microsystems, Inc. standard license agreement and applicable provisions of the FAR and its + * supplements. + * + * Use is subject to license terms. Sun, Sun Microsystems, the Sun logo, Java and Solaris are trademarks or + * registered trademarks of Sun Microsystems, Inc. in the U.S. and other countries. All SPARC trademarks + * are used under license and are trademarks or registered trademarks of SPARC International, Inc. in the + * U.S. and other countries. + * + * UNIX is a registered trademark in the U.S. and other countries, exclusively licensed through X/Open + * Company, Ltd. + */ +package com.sun.hotspot.c1x; + +import java.io.*; +import java.lang.reflect.*; + +import com.sun.hotspot.c1x.logging.*; + +/** + * A java.lang.reflect proxy that communicates over a socket connection. + * + * Calling a method sends the method name and the parameters through the socket. Afterwards this class waits for a result. + * While waiting for a result three types of objects can arrive through the socket: a method invocation, a method result or an exception. + * Method invocation can thus be recursive. + * + * @author Lukas Stadler + */ +public class InvocationSocket implements InvocationHandler { + + private final ObjectOutputStream output; + private final ObjectInputStream input; + private Object delegate; + + public InvocationSocket(ObjectOutputStream output, ObjectInputStream input) { + this.output = output; + this.input = input; + } + + public void setDelegate(Object delegate) { + this.delegate = delegate; + } + + private static class Invocation implements Serializable { + + public String methodName; + public Object[] args; + + public Invocation(String methodName, Object[] args) { + this.methodName = methodName; + this.args = args; + } + } + + private static class Result implements Serializable { + + public Object result; + + public Result(Object result) { + this.result = result; + } + } + + @Override + public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { + try { + Logger.startScope("invoking remote " + method.getName()); + output.writeObject(new Invocation(method.getName(), args)); + output.flush(); + return waitForResult(); + } catch (Throwable t) { + t.printStackTrace(); + throw t; + } finally { + Logger.endScope(""); + } + } + + public Object waitForResult() throws IOException, ClassNotFoundException { + while (true) { + Object in = input.readObject(); + if (in instanceof Result) { + return ((Result) in).result; + } else if (in instanceof RuntimeException) { + throw (RuntimeException) in; + } else if (in instanceof Throwable) { + throw new RuntimeException((Throwable) in); + } + + Invocation invoke = (Invocation) in; + Method method = null; + for (Method m : delegate.getClass().getDeclaredMethods()) { + if (invoke.methodName.equals(m.getName())) { + method = m; + break; + } + } + if (method == null) { + Exception e = new UnsupportedOperationException("unknown method " + invoke.methodName); + e.printStackTrace(); + output.writeObject(e); + output.flush(); + } else { + Object result; + try { + Logger.startScope("invoking local " + invoke.methodName); + if (invoke.args == null) { + result = method.invoke(delegate); + } else { + result = method.invoke(delegate, invoke.args); + } + result = new Result(result); + } catch (IllegalArgumentException e) { + System.out.println("error while invoking " + invoke.methodName); + e.getCause().printStackTrace(); + result = e.getCause(); + } catch (InvocationTargetException e) { + System.out.println("error while invoking " + invoke.methodName); + e.getCause().printStackTrace(); + result = e.getCause(); + } catch (IllegalAccessException e) { + System.out.println("error while invoking " + invoke.methodName); + e.getCause().printStackTrace(); + result = e.getCause(); + } finally { + Logger.endScope(""); + } + output.writeObject(result); + output.flush(); + } + } + } + +} diff -r 102466e70deb -r 91fe28b03d6a c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/TemplateFlag.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/TemplateFlag.java Wed Jan 26 18:17:37 2011 +0100 @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2010 Sun Microsystems, Inc. All rights reserved. + * + * Sun Microsystems, Inc. has intellectual property rights relating to technology embodied in the product + * that is described in this document. In particular, and without limitation, these intellectual property + * rights may include one or more of the U.S. patents listed at http://www.sun.com/patents and one or + * more additional patents or pending patent applications in the U.S. and in other countries. + * + * U.S. Government Rights - Commercial software. Government users are subject to the Sun + * Microsystems, Inc. standard license agreement and applicable provisions of the FAR and its + * supplements. + * + * Use is subject to license terms. Sun, Sun Microsystems, the Sun logo, Java and Solaris are trademarks or + * registered trademarks of Sun Microsystems, Inc. in the U.S. and other countries. All SPARC trademarks + * are used under license and are trademarks or registered trademarks of SPARC International, Inc. in the + * U.S. and other countries. + * + * UNIX is a registered trademark in the U.S. and other countries, exclusively licensed through X/Open + * Company, Ltd. + */ +package com.sun.hotspot.c1x; + +enum TemplateFlag { + NULL_CHECK, UNRESOLVED, READ_BARRIER, WRITE_BARRIER, STORE_CHECK, BOUNDS_CHECK, GIVEN_LENGTH, INPUTS_DIFFERENT, INPUTS_SAME, STATIC_METHOD, SYNCHRONIZED; + + private static final long FIRST_FLAG = 0x0000000100000000L; + public static final long FLAGS_MASK = 0x0000FFFF00000000L; + public static final long INDEX_MASK = 0x00000000FFFFFFFFL; + + public long bits() { + assert ((FIRST_FLAG << ordinal()) & FLAGS_MASK) != 0; + return FIRST_FLAG << ordinal(); + } +} diff -r 102466e70deb -r 91fe28b03d6a c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/VMEntries.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/VMEntries.java Wed Jan 26 18:17:37 2011 +0100 @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2010 Sun Microsystems, Inc. All rights reserved. + * + * Sun Microsystems, Inc. has intellectual property rights relating to technology embodied in the product + * that is described in this document. In particular, and without limitation, these intellectual property + * rights may include one or more of the U.S. patents listed at http://www.sun.com/patents and one or + * more additional patents or pending patent applications in the U.S. and in other countries. + * + * U.S. Government Rights - Commercial software. Government users are subject to the Sun + * Microsystems, Inc. standard license agreement and applicable provisions of the FAR and its + * supplements. + * + * Use is subject to license terms. Sun, Sun Microsystems, the Sun logo, Java and Solaris are trademarks or + * registered trademarks of Sun Microsystems, Inc. in the U.S. and other countries. All SPARC trademarks + * are used under license and are trademarks or registered trademarks of SPARC International, Inc. in the + * U.S. and other countries. + * + * UNIX is a registered trademark in the U.S. and other countries, exclusively licensed through X/Open + * Company, Ltd. + */ + +package com.sun.hotspot.c1x; + +import com.sun.cri.ci.*; +import com.sun.cri.ri.*; + +/** + * Entries into the HotSpot VM from Java code. + * + * @author Thomas Wuerthinger, Lukas Stadler + */ +public interface VMEntries { + + // Checkstyle: stop + + byte[] RiMethod_code(long vmId); + + int RiMethod_maxStackSize(long vmId); + + int RiMethod_maxLocals(long vmId); + + RiType RiMethod_holder(long vmId); + + String RiMethod_signature(long vmId); + + int RiMethod_accessFlags(long vmId); + + RiType RiSignature_lookupType(String returnType, HotSpotTypeResolved accessingClass); + + Object RiConstantPool_lookupConstant(long vmId, int cpi); + + RiMethod RiConstantPool_lookupMethod(long vmId, int cpi, byte byteCode); + + RiSignature RiConstantPool_lookupSignature(long vmId, int cpi); + + RiType RiConstantPool_lookupType(long vmId, int cpi); + + RiField RiConstantPool_lookupField(long vmId, int cpi, byte byteCode); + + RiConstantPool RiType_constantPool(HotSpotTypeResolved klass); + + void installMethod(HotSpotTargetMethod targetMethod); + + long installStub(HotSpotTargetMethod targetMethod); + + HotSpotVMConfig getConfiguration(); + + RiExceptionHandler[] RiMethod_exceptionHandlers(long vmId); + + RiMethod RiType_resolveMethodImpl(HotSpotTypeResolved klass, String name, String signature); + + boolean RiType_isSubtypeOf(HotSpotTypeResolved klass, RiType other); + + RiType getPrimitiveArrayType(CiKind kind); + + RiType RiType_arrayOf(HotSpotTypeResolved klass); + + RiType RiType_componentType(HotSpotTypeResolved klass); + + RiType getType(Class javaClass); + + boolean RiMethod_hasBalancedMonitors(long vmId); + + RiMethod RiMethod_uniqueConcreteMethod(long vmId); + + void recordBailout(String reason); + + RiType RiType_uniqueConcreteSubtype(HotSpotTypeResolved hotSpotTypeResolved); + // Checkstyle: resume +} diff -r 102466e70deb -r 91fe28b03d6a c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/VMEntriesNative.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/VMEntriesNative.java Wed Jan 26 18:17:37 2011 +0100 @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2010 Sun Microsystems, Inc. All rights reserved. + * + * Sun Microsystems, Inc. has intellectual property rights relating to technology embodied in the product + * that is described in this document. In particular, and without limitation, these intellectual property + * rights may include one or more of the U.S. patents listed at http://www.sun.com/patents and one or + * more additional patents or pending patent applications in the U.S. and in other countries. + * + * U.S. Government Rights - Commercial software. Government users are subject to the Sun + * Microsystems, Inc. standard license agreement and applicable provisions of the FAR and its + * supplements. + * + * Use is subject to license terms. Sun, Sun Microsystems, the Sun logo, Java and Solaris are trademarks or + * registered trademarks of Sun Microsystems, Inc. in the U.S. and other countries. All SPARC trademarks + * are used under license and are trademarks or registered trademarks of SPARC International, Inc. in the + * U.S. and other countries. + * + * UNIX is a registered trademark in the U.S. and other countries, exclusively licensed through X/Open + * Company, Ltd. + */ + +package com.sun.hotspot.c1x; + +import com.sun.cri.ci.*; +import com.sun.cri.ri.*; + +/** + * Entries into the HotSpot VM from Java code. + * + * @author Thomas Wuerthinger, Lukas Stadler + */ +public class VMEntriesNative implements VMEntries { + + // Checkstyle: stop + @Override + public native byte[] RiMethod_code(long vmId); + + @Override + public native int RiMethod_maxStackSize(long vmId); + + @Override + public native int RiMethod_maxLocals(long vmId); + + @Override + public native RiType RiMethod_holder(long vmId); + + @Override + public native String RiMethod_signature(long vmId); + + @Override + public native int RiMethod_accessFlags(long vmId); + + @Override + public native RiType RiSignature_lookupType(String returnType, HotSpotTypeResolved accessingClass); + + @Override + public native Object RiConstantPool_lookupConstant(long vmId, int cpi); + + @Override + public native RiMethod RiConstantPool_lookupMethod(long vmId, int cpi, byte byteCode); + + @Override + public native RiSignature RiConstantPool_lookupSignature(long vmId, int cpi); + + @Override + public native RiType RiConstantPool_lookupType(long vmId, int cpi); + + @Override + public native RiField RiConstantPool_lookupField(long vmId, int cpi, byte byteCode); + + @Override + public native RiConstantPool RiType_constantPool(HotSpotTypeResolved klass); + + @Override + public native void installMethod(HotSpotTargetMethod targetMethod); + + @Override + public native long installStub(HotSpotTargetMethod targetMethod); + + @Override + public native HotSpotVMConfig getConfiguration(); + + @Override + public native RiExceptionHandler[] RiMethod_exceptionHandlers(long vmId); + + @Override + public native RiMethod RiType_resolveMethodImpl(HotSpotTypeResolved klass, String name, String signature); + + @Override + public native boolean RiType_isSubtypeOf(HotSpotTypeResolved klass, RiType other); + + @Override + public native RiType getPrimitiveArrayType(CiKind kind); + + @Override + public native RiType RiType_arrayOf(HotSpotTypeResolved klass); + + @Override + public native RiType RiType_componentType(HotSpotTypeResolved klass); + + @Override + public native RiType RiType_uniqueConcreteSubtype(HotSpotTypeResolved klass); + + @Override + public native RiType getType(Class javaClass); + + @Override + public native boolean RiMethod_hasBalancedMonitors(long vmId); + + @Override + public native void recordBailout(String reason); + + @Override + public native RiMethod RiMethod_uniqueConcreteMethod(long vmId); + + // Checkstyle: resume +} diff -r 102466e70deb -r 91fe28b03d6a c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/VMExits.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/VMExits.java Wed Jan 26 18:17:37 2011 +0100 @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2010 Sun Microsystems, Inc. All rights reserved. + * + * Sun Microsystems, Inc. has intellectual property rights relating to technology embodied in the product + * that is described in this document. In particular, and without limitation, these intellectual property + * rights may include one or more of the U.S. patents listed at http://www.sun.com/patents and one or + * more additional patents or pending patent applications in the U.S. and in other countries. + * + * U.S. Government Rights - Commercial software. Government users are subject to the Sun + * Microsystems, Inc. standard license agreement and applicable provisions of the FAR and its + * supplements. + * + * Use is subject to license terms. Sun, Sun Microsystems, the Sun logo, Java and Solaris are trademarks or + * registered trademarks of Sun Microsystems, Inc. in the U.S. and other countries. All SPARC trademarks + * are used under license and are trademarks or registered trademarks of SPARC International, Inc. in the + * U.S. and other countries. + * + * UNIX is a registered trademark in the U.S. and other countries, exclusively licensed through X/Open + * Company, Ltd. + */ + +package com.sun.hotspot.c1x; + +import com.sun.cri.ci.*; +import com.sun.cri.ri.*; + +/** + * Exits from the HotSpot VM into Java code. + * + * @author Thomas Wuerthinger, Lukas Stadler + */ +public interface VMExits { + + boolean setOption(String option); + + void compileMethod(long methodVmId, String name, int entryBCI) throws Throwable; + + RiMethod createRiMethodResolved(long vmId, String name); + + RiMethod createRiMethodUnresolved(String name, String signature, RiType holder); + + RiSignature createRiSignature(String signature); + + RiField createRiField(RiType holder, String name, RiType type, int offset); + + RiType createRiType(long vmId, String name); + + RiType createRiTypePrimitive(int basicType); + + RiType createRiTypeUnresolved(String name); + + RiConstantPool createRiConstantPool(long vmId); + + CiConstant createCiConstant(CiKind kind, long value); + + CiConstant createCiConstantFloat(float value); + + CiConstant createCiConstantDouble(double value); + + CiConstant createCiConstantObject(Object object); + +} diff -r 102466e70deb -r 91fe28b03d6a c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/VMExitsNative.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/VMExitsNative.java Wed Jan 26 18:17:37 2011 +0100 @@ -0,0 +1,269 @@ +/* + * Copyright (c) 2010 Sun Microsystems, Inc. All rights reserved. + * + * Sun Microsystems, Inc. has intellectual property rights relating to technology embodied in the product + * that is described in this document. In particular, and without limitation, these intellectual property + * rights may include one or more of the U.S. patents listed at http://www.sun.com/patents and one or + * more additional patents or pending patent applications in the U.S. and in other countries. + * + * U.S. Government Rights - Commercial software. Government users are subject to the Sun + * Microsystems, Inc. standard license agreement and applicable provisions of the FAR and its + * supplements. + * + * Use is subject to license terms. Sun, Sun Microsystems, the Sun logo, Java and Solaris are trademarks or + * registered trademarks of Sun Microsystems, Inc. in the U.S. and other countries. All SPARC trademarks + * are used under license and are trademarks or registered trademarks of SPARC International, Inc. in the + * U.S. and other countries. + * + * UNIX is a registered trademark in the U.S. and other countries, exclusively licensed through X/Open + * Company, Ltd. + */ + +package com.sun.hotspot.c1x; + +import java.io.*; +import java.lang.reflect.*; +import java.util.*; + +import com.sun.c1x.*; +import com.sun.c1x.debug.*; +import com.sun.cri.ci.*; +import com.sun.cri.ri.*; +import com.sun.hotspot.c1x.logging.*; + +/** + * Exits from the HotSpot VM into Java code. + * + * @author Thomas Wuerthinger, Lukas Stadler + */ +public class VMExitsNative implements VMExits { + + public static final boolean LogCompiledMethods = false; + public static boolean compileMethods = true; + + /** + * Default option configuration for C1X. + */ + static { + C1XOptions.setOptimizationLevel(3); + C1XOptions.OptInlineExcept = false; + C1XOptions.OptInlineSynchronized = false; + C1XOptions.DetailedAsserts = false; + C1XOptions.CommentedAssembly = false; + C1XOptions.MethodEndBreakpointGuards = 2; + } + + @Override + public boolean setOption(String option) { + if (option.length() == 0) { + return false; + } + + Object value = null; + String fieldName = null; + String valueString = null; + + char first = option.charAt(0); + if (first == '+' || first == '-') { + fieldName = option.substring(1); + value = (first == '+'); + } else { + int index = option.indexOf('='); + if (index == -1) { + return false; + } + fieldName = option.substring(0, index); + valueString = option.substring(index + 1); + } + + Field f; + try { + f = C1XOptions.class.getField(fieldName); + + if (value == null) { + if (f.getType() == Float.TYPE) { + value = Float.parseFloat(valueString); + } else if (f.getType() == Double.TYPE) { + value = Double.parseDouble(valueString); + } else if (f.getType() == Integer.TYPE) { + value = Integer.parseInt(valueString); + } else if (f.getType() == Boolean.TYPE) { + value = Boolean.parseBoolean(valueString); + } else if (f.getType() == String.class) { + value = valueString; + } + } + if (value != null) { + f.set(null, value); + Logger.info("Set option " + fieldName + " to " + value); + } else { + Logger.info("Wrong value \"" + valueString + "\" for option " + fieldName); + return false; + } + } catch (SecurityException e) { + Logger.info("Security exception when setting option " + option); + return false; + } catch (NoSuchFieldException e) { + Logger.info("Could not find option " + fieldName); + return false; + } catch (IllegalArgumentException e) { + Logger.info("Illegal value for option " + option); + return false; + } catch (IllegalAccessException e) { + Logger.info("Illegal access exception when setting option " + option); + return false; + } + + return true; + } + + private static Set compiledMethods = new HashSet(); + + @Override + public void compileMethod(long methodVmId, String name, int entryBCI) throws Throwable { + + if (!compileMethods) { + return; + } + + try { + Compiler compiler = Compiler.getInstance(); + HotSpotMethodResolved riMethod = new HotSpotMethodResolved(methodVmId, name); + CiResult result = compiler.getCompiler().compileMethod(riMethod, -1, null); + if (LogCompiledMethods) { + String qualifiedName = CiUtil.toJavaName(riMethod.holder()) + "::" + riMethod.name(); + compiledMethods.add(qualifiedName); + } + + if (result.bailout() != null) { + StringWriter out = new StringWriter(); + result.bailout().printStackTrace(new PrintWriter(out)); + Throwable cause = result.bailout().getCause(); + TTY.println("Bailout:\n" + out.toString()); + if (cause != null) { + Logger.info("Trace for cause: "); + for (StackTraceElement e : cause.getStackTrace()) { + String current = e.getClassName() + "::" + e.getMethodName(); + String type = ""; + if (compiledMethods.contains(current)) { + type = "compiled"; + } + Logger.info(String.format("%-10s %3d %s", type, e.getLineNumber(), current)); + } + } + System.out.println("BAILOUT:" + result.bailout().getMessage()); + String s = result.bailout().getMessage(); + if (cause != null) { + s = cause.getMessage(); + } + Compiler.getVMEntries().recordBailout(s); + } else { + HotSpotTargetMethod.installMethod(riMethod, result.targetMethod()); + } + } catch (Throwable t) { + StringWriter out = new StringWriter(); + t.printStackTrace(new PrintWriter(out)); + TTY.println("Compilation interrupted:\n" + out.toString()); + throw t; + } + } + + @Override + public RiMethod createRiMethodResolved(long vmId, String name) { + return new HotSpotMethodResolved(vmId, name); + } + + @Override + public RiMethod createRiMethodUnresolved(String name, String signature, RiType holder) { + return new HotSpotMethodUnresolved(name, signature, holder); + } + + @Override + public RiSignature createRiSignature(String signature) { + return new HotSpotSignature(signature); + } + + @Override + public RiField createRiField(RiType holder, String name, RiType type, int offset) { + if (offset != -1) { + HotSpotTypeResolved resolved = (HotSpotTypeResolved) holder; + return resolved.createRiField(name, type, offset); + } + return new HotSpotField(holder, name, type, offset); + } + + @Override + public RiType createRiType(long vmId, String name) { + throw new RuntimeException("not implemented"); + } + + @Override + public RiType createRiTypePrimitive(int basicType) { + switch (basicType) { + case 4: + return HotSpotTypePrimitive.Boolean; + case 5: + return HotSpotTypePrimitive.Char; + case 6: + return HotSpotTypePrimitive.Float; + case 7: + return HotSpotTypePrimitive.Double; + case 8: + return HotSpotTypePrimitive.Byte; + case 9: + return HotSpotTypePrimitive.Short; + case 10: + return HotSpotTypePrimitive.Int; + case 11: + return HotSpotTypePrimitive.Long; + case 14: + return HotSpotTypePrimitive.Void; + default: + throw new IllegalArgumentException("Unknown basic type: " + basicType); + } + } + + @Override + public RiType createRiTypeUnresolved(String name) { + return new HotSpotTypeUnresolved(name); + } + + @Override + public RiConstantPool createRiConstantPool(long vmId) { + return new HotSpotConstantPool(vmId); + } + + @Override + public CiConstant createCiConstant(CiKind kind, long value) { + if (kind == CiKind.Long) { + return CiConstant.forLong(value); + } else if (kind == CiKind.Int) { + return CiConstant.forInt((int) value); + } else if (kind == CiKind.Short) { + return CiConstant.forShort((short) value); + } else if (kind == CiKind.Char) { + return CiConstant.forChar((char) value); + } else if (kind == CiKind.Byte) { + return CiConstant.forByte((byte) value); + } else if (kind == CiKind.Boolean) { + return (value == 0) ? CiConstant.FALSE : CiConstant.TRUE; + } else { + throw new IllegalArgumentException(); + } + } + + @Override + public CiConstant createCiConstantFloat(float value) { + return CiConstant.forFloat(value); + } + + @Override + public CiConstant createCiConstantDouble(double value) { + return CiConstant.forDouble(value); + } + + @Override + public CiConstant createCiConstantObject(Object object) { + return CiConstant.forObject(object); + } +} diff -r 102466e70deb -r 91fe28b03d6a c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/logging/CountingProxy.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/logging/CountingProxy.java Wed Jan 26 18:17:37 2011 +0100 @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2010 Sun Microsystems, Inc. All rights reserved. + * + * Sun Microsystems, Inc. has intellectual property rights relating to technology embodied in the product + * that is described in this document. In particular, and without limitation, these intellectual property + * rights may include one or more of the U.S. patents listed at http://www.sun.com/patents and one or + * more additional patents or pending patent applications in the U.S. and in other countries. + * + * U.S. Government Rights - Commercial software. Government users are subject to the Sun + * Microsystems, Inc. standard license agreement and applicable provisions of the FAR and its + * supplements. + * + * Use is subject to license terms. Sun, Sun Microsystems, the Sun logo, Java and Solaris are trademarks or + * registered trademarks of Sun Microsystems, Inc. in the U.S. and other countries. All SPARC trademarks + * are used under license and are trademarks or registered trademarks of SPARC International, Inc. in the + * U.S. and other countries. + * + * UNIX is a registered trademark in the U.S. and other countries, exclusively licensed through X/Open + * Company, Ltd. + */ +package com.sun.hotspot.c1x.logging; + +import java.lang.reflect.*; +import java.util.*; + +/** + * A java.lang.reflect proxy that hierarchically logs all method invocations along with their parameters and return + * values. + * + * @author Lukas Stadler + */ +public class CountingProxy implements InvocationHandler { + + public static final boolean ENABLED = Boolean.valueOf(System.getProperty("c1x.countcalls")); + + private T delegate; + + private Map calls = new HashMap(); + + public CountingProxy(T delegate) { + assert ENABLED; + System.out.println("Counting proxy for " + delegate.getClass().getSimpleName() + " created"); + this.delegate = delegate; + proxies.add(this); + } + + @Override + public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { + int argCount = args == null ? 0 : args.length; + if (method.getParameterTypes().length != argCount) { + throw new RuntimeException("wrong parameter count"); + } + final Object result; + long count = calls.containsKey(method) ? calls.get(method) : 0; + calls.put(method, count + 1); + try { + if (args == null) { + result = method.invoke(delegate); + } else { + result = method.invoke(delegate, args); + } + } catch (InvocationTargetException e) { + throw e.getCause(); + } + return result; + } + + public static T getProxy(Class interf, T delegate) { + Object obj = Proxy.newProxyInstance(interf.getClassLoader(), new Class[] {interf}, new CountingProxy(delegate)); + return interf.cast(obj); + } + + private static ArrayList proxies = new ArrayList(); + + static { + if (ENABLED) { + Runtime.getRuntime().addShutdownHook(new Thread() { + + @Override + public void run() { + for (CountingProxy proxy : proxies) { + proxy.print(); + } + } + }); + } + } + + protected void print() { + long sum = 0; + for (Map.Entry entry : calls.entrySet()) { + Method method = entry.getKey(); + long count = entry.getValue(); + sum += count; + System.out.println(delegate.getClass().getSimpleName() + "." + method.getName() + ": " + count); + } + System.out.println(delegate.getClass().getSimpleName() + " calls: " + sum); + } +} diff -r 102466e70deb -r 91fe28b03d6a c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/logging/Logger.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/logging/Logger.java Wed Jan 26 18:17:37 2011 +0100 @@ -0,0 +1,170 @@ +/* + * Copyright (c) 2010 Sun Microsystems, Inc. All rights reserved. + * + * Sun Microsystems, Inc. has intellectual property rights relating to technology embodied in the product + * that is described in this document. In particular, and without limitation, these intellectual property + * rights may include one or more of the U.S. patents listed at http://www.sun.com/patents and one or + * more additional patents or pending patent applications in the U.S. and in other countries. + * + * U.S. Government Rights - Commercial software. Government users are subject to the Sun + * Microsystems, Inc. standard license agreement and applicable provisions of the FAR and its + * supplements. + * + * Use is subject to license terms. Sun, Sun Microsystems, the Sun logo, Java and Solaris are trademarks or + * registered trademarks of Sun Microsystems, Inc. in the U.S. and other countries. All SPARC trademarks + * are used under license and are trademarks or registered trademarks of SPARC International, Inc. in the + * U.S. and other countries. + * + * UNIX is a registered trademark in the U.S. and other countries, exclusively licensed through X/Open + * Company, Ltd. + */ +package com.sun.hotspot.c1x.logging; + +import java.io.*; +import java.lang.reflect.*; +import java.util.*; + +/** + * Scoped logging class used to display the call hierarchy of VMEntries/VMExits calls. + * + * @author Lukas Stadler + */ +public class Logger { + + public static final boolean ENABLED = Boolean.valueOf(System.getProperty("c1x.debug")); + private static final int SPACING = 4; + private static Deque openStack = new LinkedList(); + private static boolean open = false; + private static int level = 0; + + private static final PrintStream out; + + static { + PrintStream ps = null; + String filename = System.getProperty("c1x.info_file"); + if (filename != null && !"".equals(filename)) { + try { + ps = new PrintStream(new FileOutputStream(filename)); + } catch (FileNotFoundException e) { + e.printStackTrace(); + ps = null; + } + } + out = ps; + if (out != null) { + out.println("start: " + new Date()); + } + } + + public static void info(String message) { + if (ENABLED) { + log(message); + } else { + System.out.println(message); + } + if (out != null) { + out.println(message); + out.flush(); + } + } + + public static void log(String message) { + if (ENABLED) { + for (String line : message.split("\n")) { + if (open) { + System.out.println("..."); + open = false; + } + System.out.print(space(level)); + System.out.println(line); + } + } + } + + public static void startScope(String message) { + if (ENABLED) { + if (open) { + System.out.println("..."); + open = false; + } + System.out.print(space(level)); + System.out.print(message); + openStack.push(open); + open = true; + level++; + } + } + + public static void endScope(String message) { + if (ENABLED) { + level--; + if (open) { + System.out.println(message); + } else { + System.out.println(space(level) + "..." + message); + } + open = openStack.pop(); + } + } + + private static String[] spaces = new String[50]; + + private static String space(int count) { + assert count >= 0; + String result; + if (count >= spaces.length || spaces[count] == null) { + StringBuilder str = new StringBuilder(); + for (int i = 0; i < count * SPACING; i++) { + str.append(' '); + } + result = str.toString(); + if (count < spaces.length) { + spaces[count] = result; + } + } else { + result = spaces[count]; + } + return result; + } + + public static String pretty(Object value) { + if (value == null) { + return "null"; + } + + Class klass = value.getClass(); + if (value instanceof Void) { + return "void"; + } else if (value instanceof String) { + return "\"" + value + "\""; + } else if (value instanceof Method) { + return "method \"" + ((Method) value).getName() + "\""; + } else if (value instanceof Class) { + return "class \"" + ((Class) value).getSimpleName() + "\""; + } else if (value instanceof Integer) { + if ((Integer) value < 10) { + return value.toString(); + } + return value + " (0x" + Integer.toHexString((Integer) value) + ")"; + } else if (value instanceof Long) { + if ((Long) value < 10) { + return value + "l"; + } + return value + "l (0x" + Long.toHexString((Long) value) + "l)"; + } else if (klass.isArray()) { + StringBuilder str = new StringBuilder(); + int dimensions = 0; + while (klass.isArray()) { + dimensions++; + klass = klass.getComponentType(); + } + str.append(klass.getSimpleName()).append('[').append(Array.getLength(value)).append(']'); + for (int i = 1; i < dimensions; i++) { + str.append("[]"); + } + return str.toString(); + } + + return value.toString(); + } +} diff -r 102466e70deb -r 91fe28b03d6a c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/logging/LoggingProxy.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/logging/LoggingProxy.java Wed Jan 26 18:17:37 2011 +0100 @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2010 Sun Microsystems, Inc. All rights reserved. + * + * Sun Microsystems, Inc. has intellectual property rights relating to technology embodied in the product + * that is described in this document. In particular, and without limitation, these intellectual property + * rights may include one or more of the U.S. patents listed at http://www.sun.com/patents and one or + * more additional patents or pending patent applications in the U.S. and in other countries. + * + * U.S. Government Rights - Commercial software. Government users are subject to the Sun + * Microsystems, Inc. standard license agreement and applicable provisions of the FAR and its + * supplements. + * + * Use is subject to license terms. Sun, Sun Microsystems, the Sun logo, Java and Solaris are trademarks or + * registered trademarks of Sun Microsystems, Inc. in the U.S. and other countries. All SPARC trademarks + * are used under license and are trademarks or registered trademarks of SPARC International, Inc. in the + * U.S. and other countries. + * + * UNIX is a registered trademark in the U.S. and other countries, exclusively licensed through X/Open + * Company, Ltd. + */ +package com.sun.hotspot.c1x.logging; + +import java.lang.reflect.*; + +/** + * A java.lang.reflect proxy that hierarchically logs all method invocations along with their parameters and return values. + * + * @author Lukas Stadler + */ +public class LoggingProxy implements InvocationHandler { + + private T delegate; + + public LoggingProxy(T delegate) { + this.delegate = delegate; + } + + @Override + public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { + int argCount = args == null ? 0 : args.length; + if (method.getParameterTypes().length != argCount) { + throw new RuntimeException("wrong parameter count"); + } + StringBuilder str = new StringBuilder(); + str.append(method.getReturnType().getSimpleName() + " " + method.getDeclaringClass().getSimpleName() + "." + method.getName() + "("); + for (int i = 0; i < argCount; i++) { + str.append(i == 0 ? "" : ", "); + str.append(Logger.pretty(args[i])); + } + str.append(")"); + Logger.startScope(str.toString()); + final Object result; + try { + if (args == null) { + result = method.invoke(delegate); + } else { + result = method.invoke(delegate, args); + } + } catch (InvocationTargetException e) { + Logger.endScope(" = Exception " + e.getMessage()); + throw e.getCause(); + } + Logger.endScope(" = " + Logger.pretty(result)); + return result; + } + + public static T getProxy(Class interf, T delegate) { + Object obj = Proxy.newProxyInstance(interf.getClassLoader(), new Class[] {interf}, new LoggingProxy(delegate)); + return interf.cast(obj); + } +} diff -r 102466e70deb -r 91fe28b03d6a c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/logging/package-info.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/logging/package-info.java Wed Jan 26 18:17:37 2011 +0100 @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2010 Sun Microsystems, Inc. All rights reserved. + * + * Sun Microsystems, Inc. has intellectual property rights relating to technology embodied in the product + * that is described in this document. In particular, and without limitation, these intellectual property + * rights may include one or more of the U.S. patents listed at http://www.sun.com/patents and one or + * more additional patents or pending patent applications in the U.S. and in other countries. + * + * U.S. Government Rights - Commercial software. Government users are subject to the Sun + * Microsystems, Inc. standard license agreement and applicable provisions of the FAR and its + * supplements. + * + * Use is subject to license terms. Sun, Sun Microsystems, the Sun logo, Java and Solaris are trademarks or + * registered trademarks of Sun Microsystems, Inc. in the U.S. and other countries. All SPARC trademarks + * are used under license and are trademarks or registered trademarks of SPARC International, Inc. in the + * U.S. and other countries. + * + * UNIX is a registered trademark in the U.S. and other countries, exclusively licensed through X/Open + * Company, Ltd. + */ +/** + * Logging framework for the HotSpot CRI implementation. + * + * @author Lukas Stadler + * @author Thomas Wuerthinger + */ +package com.sun.hotspot.c1x.logging; diff -r 102466e70deb -r 91fe28b03d6a c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/package-info.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/package-info.java Wed Jan 26 18:17:37 2011 +0100 @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2010 Sun Microsystems, Inc. All rights reserved. + * + * Sun Microsystems, Inc. has intellectual property rights relating to technology embodied in the product + * that is described in this document. In particular, and without limitation, these intellectual property + * rights may include one or more of the U.S. patents listed at http://www.sun.com/patents and one or + * more additional patents or pending patent applications in the U.S. and in other countries. + * + * U.S. Government Rights - Commercial software. Government users are subject to the Sun + * Microsystems, Inc. standard license agreement and applicable provisions of the FAR and its + * supplements. + * + * Use is subject to license terms. Sun, Sun Microsystems, the Sun logo, Java and Solaris are trademarks or + * registered trademarks of Sun Microsystems, Inc. in the U.S. and other countries. All SPARC trademarks + * are used under license and are trademarks or registered trademarks of SPARC International, Inc. in the + * U.S. and other countries. + * + * UNIX is a registered trademark in the U.S. and other countries, exclusively licensed through X/Open + * Company, Ltd. + */ +/** + * Package containing the runtime interface (defined in the CRI project) implementation for HotSpot. + * There is a class that bridges from the C++ to the Java side (VMExitsNative.java) and one that bridges + * from the Java to the C++ side (VMEntriesNative.java). + * + * @author Lukas Stadler + * @author Thomas Wuerthinger + */ +package com.sun.hotspot.c1x; diff -r 102466e70deb -r 91fe28b03d6a c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/server/CompilationServer.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/server/CompilationServer.java Wed Jan 26 18:17:37 2011 +0100 @@ -0,0 +1,140 @@ +/* + * Copyright (c) 2010 Sun Microsystems, Inc. All rights reserved. + * + * Sun Microsystems, Inc. has intellectual property rights relating to technology embodied in the product + * that is described in this document. In particular, and without limitation, these intellectual property + * rights may include one or more of the U.S. patents listed at http://www.sun.com/patents and one or + * more additional patents or pending patent applications in the U.S. and in other countries. + * + * U.S. Government Rights - Commercial software. Government users are subject to the Sun + * Microsystems, Inc. standard license agreement and applicable provisions of the FAR and its + * supplements. + * + * Use is subject to license terms. Sun, Sun Microsystems, the Sun logo, Java and Solaris are trademarks or + * registered trademarks of Sun Microsystems, Inc. in the U.S. and other countries. All SPARC trademarks + * are used under license and are trademarks or registered trademarks of SPARC International, Inc. in the + * U.S. and other countries. + * + * UNIX is a registered trademark in the U.S. and other countries, exclusively licensed through X/Open + * Company, Ltd. + */ +package com.sun.hotspot.c1x.server; + +import java.io.*; +import java.lang.reflect.Proxy; +import java.net.*; +import java.rmi.registry.*; + +import javax.net.*; + +import com.sun.cri.ci.*; +import com.sun.cri.ri.*; +import com.sun.hotspot.c1x.*; +import com.sun.hotspot.c1x.Compiler; +import com.sun.hotspot.c1x.logging.*; + +/** + * Server side of the client/server compilation model. + * + * @author Lukas Stadler + */ +public class CompilationServer { + + private Registry registry; + private ServerSocket serverSocket; + private Socket socket; + private ObjectOutputStream output; + private ObjectInputStream input; + + public static void main(String[] args) throws Exception { + new CompilationServer().run(); + } + + public static class Container implements Serializable { + + public final Class clazz; + public final Object[] values; + + public Container(Class clazz, Object... values) { + this.clazz = clazz; + this.values = values; + } + } + + /** + * Replaces certain cir objects that cannot easily be made Serializable. + */ + public static class ReplacingOutputStream extends ObjectOutputStream { + + public ReplacingOutputStream(OutputStream out) throws IOException { + super(out); + enableReplaceObject(true); + } + + @Override + protected Object replaceObject(Object obj) throws IOException { + Class clazz = obj.getClass(); + if (clazz == CiConstant.class) { + CiConstant o = (CiConstant) obj; + return new Container(clazz, o.kind, o.boxedValue()); + } else if (clazz == CiDebugInfo.class) { + CiDebugInfo o = (CiDebugInfo) obj; + return new Container(clazz, o.codePos, o.registerRefMap, o.frameRefMap); + } else if (clazz == CiCodePos.class) { + CiCodePos o = (CiCodePos) obj; + return new Container(clazz, o.caller, o.method, o.bci); + } + return obj; + } + } + + /** + * Replaces certain cir objects that cannot easily be made Serializable. + */ + public static class ReplacingInputStream extends ObjectInputStream { + + public ReplacingInputStream(InputStream in) throws IOException { + super(in); + enableResolveObject(true); + } + + @Override + protected Object resolveObject(Object obj) throws IOException { + if (obj instanceof Container) { + Container c = (Container) obj; + if (c.clazz == CiConstant.class) { + return CiConstant.forBoxed((CiKind) c.values[0], c.values[1]); + } else if (c.clazz == CiDebugInfo.class) { + return new CiDebugInfo((CiCodePos) c.values[0], (CiBitMap) c.values[2], (CiBitMap) c.values[3]); + } else if (c.clazz == CiCodePos.class) { + return new CiCodePos((CiCodePos) c.values[0], (RiMethod) c.values[1], (Integer) c.values[2]); + } + throw new RuntimeException("unexpected container class"); + } + return obj; + } + } + + private void run() throws IOException, ClassNotFoundException { + serverSocket = ServerSocketFactory.getDefault().createServerSocket(1199); + while (true) { + try { + Logger.log("Compilation server ready, waiting for client to connect..."); + socket = serverSocket.accept(); + Logger.log("Connected to " + socket.getRemoteSocketAddress()); + output = new ReplacingOutputStream(socket.getOutputStream()); + input = new ReplacingInputStream(socket.getInputStream()); + + InvocationSocket invocation = new InvocationSocket(output, input); + VMEntries entries = (VMEntries) Proxy.newProxyInstance(VMEntries.class.getClassLoader(), new Class[] {VMEntries.class}, invocation); + VMExits exits = Compiler.initializeServer(entries); + invocation.setDelegate(exits); + + invocation.waitForResult(); + } catch (IOException e) { + e.printStackTrace(); + socket.close(); + } + } + } +} diff -r 102466e70deb -r 91fe28b03d6a c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/server/package-info.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/server/package-info.java Wed Jan 26 18:17:37 2011 +0100 @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2010 Sun Microsystems, Inc. All rights reserved. + * + * Sun Microsystems, Inc. has intellectual property rights relating to technology embodied in the product + * that is described in this document. In particular, and without limitation, these intellectual property + * rights may include one or more of the U.S. patents listed at http://www.sun.com/patents and one or + * more additional patents or pending patent applications in the U.S. and in other countries. + * + * U.S. Government Rights - Commercial software. Government users are subject to the Sun + * Microsystems, Inc. standard license agreement and applicable provisions of the FAR and its + * supplements. + * + * Use is subject to license terms. Sun, Sun Microsystems, the Sun logo, Java and Solaris are trademarks or + * registered trademarks of Sun Microsystems, Inc. in the U.S. and other countries. All SPARC trademarks + * are used under license and are trademarks or registered trademarks of SPARC International, Inc. in the + * U.S. and other countries. + * + * UNIX is a registered trademark in the U.S. and other countries, exclusively licensed through X/Open + * Company, Ltd. + */ +/** + * Implementation of a compilation server socket that delegates incoming requests to C1X. + * + * @author Lukas Stadler + * @author Thomas Wuerthinger + */ +package com.sun.hotspot.c1x.server; diff -r 102466e70deb -r 91fe28b03d6a c1x4hotspotsrc/hotspot/.cproject --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/c1x4hotspotsrc/hotspot/.cproject Wed Jan 26 18:17:37 2011 +0100 @@ -0,0 +1,661 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff -r 102466e70deb -r 91fe28b03d6a c1x4hotspotsrc/hotspot/.jcheck/conf --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/c1x4hotspotsrc/hotspot/.jcheck/conf Wed Jan 26 18:17:37 2011 +0100 @@ -0,0 +1,1 @@ +project=jdk7 diff -r 102466e70deb -r 91fe28b03d6a c1x4hotspotsrc/hotspot/.project --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/c1x4hotspotsrc/hotspot/.project Wed Jan 26 18:17:37 2011 +0100 @@ -0,0 +1,114 @@ + + + hotspot + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + auto,full,incremental, + + + ?children? + ?name?=outputEntries\|?children?=?name?=entry\\\\\\\|\\\|\|| + + + ?name? + + + + org.eclipse.cdt.make.core.append_environment + true + + + org.eclipse.cdt.make.core.autoBuildTarget + jvmg1 + + + org.eclipse.cdt.make.core.buildArguments + ${workspace_loc:/hotspot}/../../domake + + + org.eclipse.cdt.make.core.buildCommand + bash + + + org.eclipse.cdt.make.core.buildLocation + ${workspace_loc:/hotspot}/../../make + + + org.eclipse.cdt.make.core.cleanBuildTarget + clean + + + org.eclipse.cdt.make.core.contents + org.eclipse.cdt.make.core.activeConfigSettings + + + org.eclipse.cdt.make.core.enableAutoBuild + true + + + org.eclipse.cdt.make.core.enableCleanBuild + false + + + org.eclipse.cdt.make.core.enableFullBuild + true + + + org.eclipse.cdt.make.core.fullBuildTarget + jvmg1 + + + org.eclipse.cdt.make.core.stopOnError + true + + + org.eclipse.cdt.make.core.useDefaultBuildCmd + false + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + org.eclipse.cdt.core.cnature + org.eclipse.cdt.core.ccnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + + + cpu + 2 + PARENT-2-PROJECT_LOC/src/cpu/x86 + + + generated + 2 + PARENT-2-PROJECT_LOC/build/linux/linux_amd64_compiler1/generated + + + os + 2 + PARENT-2-PROJECT_LOC/src/os/linux + + + os_cpu + 2 + PARENT-2-PROJECT_LOC/src/os_cpu/linux_x86 + + + vm + 2 + PARENT-2-PROJECT_LOC/src/share/vm + + + diff -r 102466e70deb -r 91fe28b03d6a c1x4hotspotsrc/hotspot/.settings/org.eclipse.cdt.core.prefs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/c1x4hotspotsrc/hotspot/.settings/org.eclipse.cdt.core.prefs Wed Jan 26 18:17:37 2011 +0100 @@ -0,0 +1,152 @@ +#Wed Sep 01 16:57:34 PDT 2010 +eclipse.preferences.version=1 +org.eclipse.cdt.core.formatter.alignment_for_arguments_in_method_invocation=16 +org.eclipse.cdt.core.formatter.alignment_for_base_clause_in_type_declaration=80 +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_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_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.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_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_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.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 diff -r 102466e70deb -r 91fe28b03d6a c1x4hotspotsrc/hotspot/.settings/org.eclipse.cdt.ui.prefs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/c1x4hotspotsrc/hotspot/.settings/org.eclipse.cdt.ui.prefs Wed Jan 26 18:17:37 2011 +0100 @@ -0,0 +1,4 @@ +#Wed Sep 01 16:21:02 PDT 2010 +eclipse.preferences.version=1 +formatter_profile=_hotspotStyle +formatter_settings_version=1 diff -r 102466e70deb -r 91fe28b03d6a c1x4hotspotsrc/hotspot/.settings/org.eclipse.core.runtime.prefs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/c1x4hotspotsrc/hotspot/.settings/org.eclipse.core.runtime.prefs Wed Jan 26 18:17:37 2011 +0100 @@ -0,0 +1,5 @@ +#Wed Sep 01 16:13:40 PDT 2010 +content-types/enabled=true +content-types/org.eclipse.cdt.core.cHeader/file-extensions=hpp,incl +content-types/org.eclipse.cdt.core.cxxSource/file-extensions=cpp +eclipse.preferences.version=1 diff -r 102466e70deb -r 91fe28b03d6a c1x4hotspotsrc/hotspot/hotspot Default.launch --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/c1x4hotspotsrc/hotspot/hotspot Default.launch Wed Jan 26 18:17:37 2011 +0100 @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff -r 102466e70deb -r 91fe28b03d6a clean --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/clean Wed Jan 26 18:17:37 2011 +0100 @@ -0,0 +1,5 @@ +#!/bin/bash +pushd make +LANG=C ARCH_DATA_MODEL=64 HOTSPOT_BUILD_JOBS=16 make clean +popd + diff -r 102466e70deb -r 91fe28b03d6a create.cmd --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/create.cmd Wed Jan 26 18:17:37 2011 +0100 @@ -0,0 +1,12 @@ +set HotSpotMksHome=C:\Cygwin\bin +set path=%JAVA_HOME%\bin;C:\Cygwin\bin +call "%VS_VCVARS%\vsvars32.bat" + +set OrigPath=%cd% +cd make\windows + +mkdir %OrigPath%\work +call create.bat %OrigPath% %OrigPath%\work %OrigPath%\java + +cd %OrigPath% +pause diff -r 102466e70deb -r 91fe28b03d6a create64.cmd --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/create64.cmd Wed Jan 26 18:17:37 2011 +0100 @@ -0,0 +1,14 @@ +set HotSpotMksHome=C:\cygwin\bin +set JAVA_HOME=%cd%\java +set ORIG_PATH=%PATH% +set path=%JAVA_HOME%\bin;%path%;C:\cygwin\bin + +set OrigPath=%cd% +cd make\windows + +mkdir %OrigPath%\work +call create.bat %OrigPath% %OrigPath%\work %OrigPath%\java + +set PATH=%ORIG_PATH% +cd %OrigPath% +pause diff -r 102466e70deb -r 91fe28b03d6a domake --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/domake Wed Jan 26 18:17:37 2011 +0100 @@ -0,0 +1,43 @@ +#!/bin/bash + +test -n "$JDK7" || { echo "Need to set JDK7 environment variable to the base of a JDK 1.7"; exit 1; } +test -n "$JDK7G" || { echo "Need to set JDK7G environment variable to the base of a JDK 1.7"; exit 1; } + +# Resolve location of this script +me="${BASH_SOURCE[0]}" +while [ -h "$me" ]; do + me=`readlink -e "$me"` +done +graal_home=$(cd `dirname $me`; pwd) + +grep '-client KNOWN' $JDK7/jre/lib/amd64/jvm.cfg >/dev/null +if [ $? -ne 0 ] ; then + echo "The setting for -client in $JDK7/jre/lib/amd64/jvm.cfg must be:" + echo + echo " -client KNOWN" + echo + exit 1 +fi + +grep '-client KNOWN' $JDK7G/jre/lib/amd64/jvm.cfg >/dev/null +if [ $? -ne 0 ] ; then + echo "The setting for -client in $JDK7G/jre/lib/amd64/jvm.cfg must be:" + echo + echo " -client KNOWN" + echo + exit 1 +fi + +java_link="$graal_home/c1x4hotspotsrc/hotspot/java" +if [ ! -e $java_link ]; then + echo "Creating link: $java_link -> $JDK7/jre/bin/java" + ln -s $JDK7/jre/bin/java $java_link +fi + +pushd $graal_home/make + +ARCH_DATA_MODEL=64 LANG=C HOTSPOT_BUILD_JOBS=4 ALT_BOOTDIR=$JDK7G INSTALL=$JDK7G/jre make jvmg1 +ARCH_DATA_MODEL=64 LANG=C HOTSPOT_BUILD_JOBS=4 ALT_BOOTDIR=$JDK7 INSTALL=$JDK7/jre make product1 + +popd + diff -r 102466e70deb -r 91fe28b03d6a make/Makefile --- a/make/Makefile Thu Jan 20 15:52:05 2011 -0800 +++ b/make/Makefile Wed Jan 26 18:17:37 2011 +0100 @@ -164,13 +164,13 @@ @$(ECHO) "No compiler1 ($(VM_TARGET)) for ARCH_DATA_MODEL=$(ARCH_DATA_MODEL)" endif else - ifeq ($(ARCH_DATA_MODEL), 32) +# ifeq ($(ARCH_DATA_MODEL), 32) $(CD) $(OUTPUTDIR); \ $(MAKE) -f $(ABS_OS_MAKEFILE) \ $(MAKE_ARGS) $(VM_TARGET) - else - @$(ECHO) "No compiler1 ($(VM_TARGET)) for ARCH_DATA_MODEL=$(ARCH_DATA_MODEL)" - endif +# else +# @$(ECHO) "No compiler1 ($(VM_TARGET)) for ARCH_DATA_MODEL=$(ARCH_DATA_MODEL)" +# endif endif # Build compiler2 (server) rule, different for platforms @@ -372,11 +372,11 @@ $(install-file) # Xusage file -$(EXPORT_SERVER_DIR)/Xusage.txt $(EXPORT_CLIENT_DIR)/Xusage.txt $(EXPORT_KERNEL_DIR)/Xusage.txt: $(XUSAGE) - $(prep-target) - $(RM) $@.temp - $(SED) 's/\(separated by \)[;:]/\1$(PATH_SEP)/g' $< > $@.temp - $(MV) $@.temp $@ +#$(EXPORT_SERVER_DIR)/Xusage.txt $(EXPORT_CLIENT_DIR)/Xusage.txt $(EXPORT_KERNEL_DIR)/Xusage.txt: $(XUSAGE) +# $(prep-target) +# $(RM) $@.temp +# $(SED) 's/\(separated by \)[;:]/\1$(PATH_SEP)/g' $< > $@.temp +# $(MV) $@.temp $@ # # Clean rules diff -r 102466e70deb -r 91fe28b03d6a make/linux/Makefile --- a/make/linux/Makefile Thu Jan 20 15:52:05 2011 -0800 +++ b/make/linux/Makefile Wed Jan 26 18:17:37 2011 +0100 @@ -301,7 +301,7 @@ $(TARGETS_C1): $(SUBDIRS_C1) cd $(OSNAME)_$(BUILDARCH)_compiler1/$(patsubst %1,%,$@) && $(MAKE) $(MFLAGS) - cd $(OSNAME)_$(BUILDARCH)_compiler1/$(patsubst %1,%,$@) && ./test_gamma +# cd $(OSNAME)_$(BUILDARCH)_compiler1/$(patsubst %1,%,$@) && ./test_gamma ifdef INSTALL cd $(OSNAME)_$(BUILDARCH)_compiler1/$(patsubst %1,%,$@) && $(MAKE) $(MFLAGS) install endif diff -r 102466e70deb -r 91fe28b03d6a make/linux/makefiles/launcher.make diff -r 102466e70deb -r 91fe28b03d6a make/linux/makefiles/vm.make diff -r 102466e70deb -r 91fe28b03d6a make/windows/create.bat --- a/make/windows/create.bat Thu Jan 20 15:52:05 2011 -0800 +++ b/make/windows/create.bat Wed Jan 26 18:17:37 2011 +0100 @@ -54,6 +54,8 @@ if %errorlevel% == 0 goto isia64 cl 2>&1 | grep "AMD64" >NUL if %errorlevel% == 0 goto amd64 +cl 2>&1 | grep "x64" >NUL +if %errorlevel% == 0 goto amd64 set ARCH=x86 set BUILDARCH=i486 set Platform_arch=x86 diff -r 102466e70deb -r 91fe28b03d6a make/windows/makefiles/projectcreator.make diff -r 102466e70deb -r 91fe28b03d6a make/windows/makefiles/vm.make --- a/make/windows/makefiles/vm.make Thu Jan 20 15:52:05 2011 -0800 +++ b/make/windows/makefiles/vm.make Wed Jan 26 18:17:37 2011 +0100 @@ -132,6 +132,7 @@ VM_PATH=$(VM_PATH);../generated/adfiles VM_PATH=$(VM_PATH);../generated/jvmtifiles VM_PATH=$(VM_PATH);$(WorkSpace)/src/share/vm/c1 +VM_PATH=$(VM_PATH);$(WorkSpace)/src/share/vm/c1x VM_PATH=$(VM_PATH);$(WorkSpace)/src/share/vm/compiler VM_PATH=$(VM_PATH);$(WorkSpace)/src/share/vm/code VM_PATH=$(VM_PATH);$(WorkSpace)/src/share/vm/interpreter diff -r 102466e70deb -r 91fe28b03d6a runscimark.sh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/runscimark.sh Wed Jan 26 18:17:37 2011 +0100 @@ -0,0 +1,18 @@ +#!/bin/bash +if [ -z "${JDK7}" ]; then + echo "JDK7 is not defined." + exit 1; +fi +if [ -z "${MAXINE}" ]; then + echo "MAXINE is not defined. It must point to a maxine repository directory." + exit 1; +fi +if [ -z "${SCIMARK}" ]; then + echo "SCIMARK is not defined. It must point to a SciMark benchmark directory." + exit 1; +fi +for (( i = 1; i <= 5000; i++ )) ### Outer for loop ### +do + echo "$i " + ${JDK7}/jre/bin/java -client -graal -esa -ea -Xms32m -Xmx100m -Xbootclasspath/a:${SCIMARK} -C1X:+PrintTimers jnt.scimark2.commandline -large +done diff -r 102466e70deb -r 91fe28b03d6a src/cpu/x86/vm/assembler_x86.cpp --- a/src/cpu/x86/vm/assembler_x86.cpp Thu Jan 20 15:52:05 2011 -0800 +++ b/src/cpu/x86/vm/assembler_x86.cpp Wed Jan 26 18:17:37 2011 +0100 @@ -5544,6 +5544,7 @@ lea(c_rarg1, InternalAddress(rip)); movq(c_rarg2, rsp); // pass pointer to regs array andq(rsp, -16); // align stack as required by ABI + mov64(rax, 0); call(RuntimeAddress(CAST_FROM_FN_PTR(address, MacroAssembler::debug64))); hlt(); } @@ -5554,6 +5555,7 @@ push_CPU_state(); // keeps alignment at 16 bytes lea(c_rarg0, ExternalAddress((address) msg)); + mov64(rax, 0); call_VM_leaf(CAST_FROM_FN_PTR(address, warning), c_rarg0); pop_CPU_state(); pop(rsp); diff -r 102466e70deb -r 91fe28b03d6a src/cpu/x86/vm/c1_Runtime1_x86.cpp --- a/src/cpu/x86/vm/c1_Runtime1_x86.cpp Thu Jan 20 15:52:05 2011 -0800 +++ b/src/cpu/x86/vm/c1_Runtime1_x86.cpp Wed Jan 26 18:17:37 2011 +0100 @@ -611,30 +611,50 @@ // has_argument: true if the exception needs an argument (passed on stack because registers must be preserved) OopMapSet* Runtime1::generate_exception_throw(StubAssembler* sasm, address target, bool has_argument) { - // preserve all registers - int num_rt_args = has_argument ? 2 : 1; - OopMap* oop_map = save_live_registers(sasm, num_rt_args); + OopMapSet* oop_maps = new OopMapSet(); + if (UseC1X) { + // c1x passes the argument in r10 + OopMap* oop_map = save_live_registers(sasm, 1); + + // now all registers are saved and can be used freely + // verify that no old value is used accidentally + __ invalidate_registers(true, true, true, true, true, true); - // now all registers are saved and can be used freely - // verify that no old value is used accidentally - __ invalidate_registers(true, true, true, true, true, true); + // registers used by this stub + const Register temp_reg = rbx; - // registers used by this stub - const Register temp_reg = rbx; + // load argument for exception that is passed as an argument into the stub + if (has_argument) { + __ movptr(c_rarg1, r10); + } + int call_offset = __ call_RT(noreg, noreg, target, has_argument ? 1 : 0); - // load argument for exception that is passed as an argument into the stub - if (has_argument) { -#ifdef _LP64 - __ movptr(c_rarg1, Address(rbp, 2*BytesPerWord)); -#else - __ movptr(temp_reg, Address(rbp, 2*BytesPerWord)); - __ push(temp_reg); -#endif // _LP64 + oop_maps->add_gc_map(call_offset, oop_map); + } else { + // preserve all registers + int num_rt_args = has_argument ? 2 : 1; + OopMap* oop_map = save_live_registers(sasm, num_rt_args); + + // now all registers are saved and can be used freely + // verify that no old value is used accidentally + __ invalidate_registers(true, true, true, true, true, true); + + // registers used by this stub + const Register temp_reg = rbx; + + // load argument for exception that is passed as an argument into the stub + if (has_argument) { + #ifdef _LP64 + __ movptr(c_rarg1, Address(rbp, 2*BytesPerWord)); + #else + __ movptr(temp_reg, Address(rbp, 2*BytesPerWord)); + __ push(temp_reg); + #endif // _LP64 + } + int call_offset = __ call_RT(noreg, noreg, target, num_rt_args - 1); + + oop_maps->add_gc_map(call_offset, oop_map); } - int call_offset = __ call_RT(noreg, noreg, target, num_rt_args - 1); - - OopMapSet* oop_maps = new OopMapSet(); - oop_maps->add_gc_map(call_offset, oop_map); __ stop("should not reach here"); @@ -729,6 +749,74 @@ } +void Runtime1::c1x_generate_handle_exception(StubAssembler *sasm, OopMapSet* oop_maps, OopMap* oop_map) { + NOT_LP64(fatal("64 bit only")); + // incoming parameters + const Register exception_oop = j_rarg0; + // other registers used in this stub + const Register exception_pc = j_rarg1; + const Register thread = r15_thread; + + __ block_comment("c1x_generate_handle_exception"); + + // verify that rax, contains a valid exception + __ verify_not_null_oop(exception_oop); + +#ifdef ASSERT + // check that fields in JavaThread for exception oop and issuing pc are + // empty before writing to them + Label oop_empty; + __ cmpptr(Address(thread, JavaThread::exception_oop_offset()), (int32_t) NULL_WORD); + __ jcc(Assembler::equal, oop_empty); + __ stop("exception oop already set"); + __ bind(oop_empty); + + Label pc_empty; + __ cmpptr(Address(thread, JavaThread::exception_pc_offset()), 0); + __ jcc(Assembler::equal, pc_empty); + __ stop("exception pc already set"); + __ bind(pc_empty); +#endif + + // save exception oop and issuing pc into JavaThread + // (exception handler will load it from here) + __ movptr(Address(thread, JavaThread::exception_oop_offset()), exception_oop); + __ movptr(exception_pc, Address(rbp, 1*BytesPerWord)); + __ movptr(Address(thread, JavaThread::exception_pc_offset()), exception_pc); + + // compute the exception handler. + // the exception oop and the throwing pc are read from the fields in JavaThread + int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, exception_handler_for_pc)); + oop_maps->add_gc_map(call_offset, oop_map); + + // rax,: handler address + // will be the deopt blob if nmethod was deoptimized while we looked up + // handler regardless of whether handler existed in the nmethod. + + // only rax, is valid at this time, all other registers have been destroyed by the runtime call + __ invalidate_registers(false, true, true, true, true, true); + +#ifdef ASSERT + // Do we have an exception handler in the nmethod? + Label done; + __ testptr(rax, rax); + __ jcc(Assembler::notZero, done); + __ stop("no handler found"); + __ bind(done); +#endif + + // exception handler found + // patch the return address -> the stub will directly return to the exception handler + __ movptr(Address(rbp, 1*BytesPerWord), rax); + + // restore registers + restore_live_registers(sasm, false); + + // return to exception handler + __ leave(); + __ ret(0); +} + void Runtime1::generate_unwind_exception(StubAssembler *sasm) { // incoming parameters @@ -937,6 +1025,12 @@ } +JRT_ENTRY(void, c1x_create_null_exception(JavaThread* thread)) + thread->set_vm_result(Exceptions::new_exception(thread, vmSymbols::java_lang_NullPointerException(), NULL)()); +JRT_END + + + OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) { @@ -1256,8 +1350,8 @@ // will be place in C abi locations #ifdef _LP64 - __ verify_oop(c_rarg0); - __ mov(rax, c_rarg0); + __ verify_oop((UseC1X) ? j_rarg0 : c_rarg0); + __ mov(rax, (UseC1X) ? j_rarg0 : c_rarg0); #else // The object is passed on the stack and we haven't pushed a // frame yet so it's one work away from top of stack. @@ -1326,7 +1420,8 @@ break; case unwind_exception_id: - { __ set_info("unwind_exception", dont_gc_arguments); + { + __ set_info("unwind_exception", dont_gc_arguments); // note: no stubframe since we are about to leave the current // activation and we are calling a leaf VM function only. generate_unwind_exception(sasm); @@ -1385,10 +1480,17 @@ __ movptr(rsi, Address(rsp, (klass_off) * VMRegImpl::stack_slot_size)); // subclass __ movptr(rax, Address(rsp, (sup_k_off) * VMRegImpl::stack_slot_size)); // superclass + Label success; Label miss; + if (UseC1X) { + // TODO this should really be within the XirSnippets + __ check_klass_subtype_fast_path(rsi, rax, rcx, &success, &miss, NULL); + }; + __ check_klass_subtype_slow_path(rsi, rax, rcx, rdi, NULL, &miss); // fallthrough on success: + __ bind(success); __ movptr(Address(rsp, (result_off) * VMRegImpl::stack_slot_size), 1); // result __ pop(rax); __ pop(rcx); @@ -1786,6 +1888,211 @@ break; #endif // !SERIALGC + case c1x_unwind_exception_call_id: { + // remove the frame from the stack + __ movptr(rsp, rbp); + __ pop(rbp); + // exception_oop is passed using ordinary java calling conventions + __ movptr(rax, j_rarg0); + + Label nonNullExceptionOop; + __ testptr(rax, rax); + __ jcc(Assembler::notZero, nonNullExceptionOop); + { + __ enter(); + oop_maps = new OopMapSet(); + OopMap* oop_map = save_live_registers(sasm, 0); + int call_offset = __ call_RT(rax, noreg, (address)c1x_create_null_exception, 0); + oop_maps->add_gc_map(call_offset, oop_map); + __ leave(); + } + __ bind(nonNullExceptionOop); + + __ set_info("unwind_exception", dont_gc_arguments); + // note: no stubframe since we are about to leave the current + // activation and we are calling a leaf VM function only. + generate_unwind_exception(sasm); + __ should_not_reach_here(); + break; + } + + case c1x_handle_exception_id: { + StubFrame f(sasm, "c1x_handle_exception", dont_gc_arguments); + oop_maps = new OopMapSet(); + OopMap* oop_map = save_live_registers(sasm, 1, false); + c1x_generate_handle_exception(sasm, oop_maps, oop_map); + break; + } + + case c1x_global_implicit_null_id: { + __ push(rax); + __ push(rax); + // move saved fp to make space for the inserted return address + __ get_thread(rax); + __ movptr(rax, Address(rax, JavaThread::saved_exception_pc_offset())); + __ movptr(Address(rsp, HeapWordSize), rax); + __ pop(rax); + + { StubFrame f(sasm, "c1x_global_implicit_null_id", dont_gc_arguments); + oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, throw_null_pointer_exception), false); + } + break; + } + + case c1x_throw_div0_exception_id: { + __ push(rax); + __ push(rax); + // move saved fp to make space for the inserted return address + __ get_thread(rax); + __ movptr(rax, Address(rax, JavaThread::saved_exception_pc_offset())); + __ movptr(Address(rsp, HeapWordSize), rax); + __ pop(rax); + + { StubFrame f(sasm, "throw_div0_exception", dont_gc_arguments); + oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, throw_div0_exception), false); + } + break; + } + + case c1x_slow_subtype_check_id: { + Label success; + Label miss; + + // TODO this should really be within the XirSnippets + __ check_klass_subtype_fast_path(j_rarg0, j_rarg1, j_rarg2, &success, &miss, NULL); + __ check_klass_subtype_slow_path(j_rarg0, j_rarg1, j_rarg2, j_rarg3, NULL, &miss); + + // fallthrough on success: + __ bind(success); + __ movptr(rax, 1); + __ ret(0); + + __ bind(miss); + __ movptr(rax, NULL_WORD); + __ ret(0); + break; + } + + case c1x_verify_pointer_id: { + __ verify_oop(r13, "c1x verify pointer"); + __ ret(0); + break; + } + + case c1x_arithmetic_frem_id: { + __ subptr(rsp, 8); + __ movflt(Address(rsp, 0), xmm1); + __ fld_s(Address(rsp, 0)); + __ movflt(Address(rsp, 0), xmm0); + __ fld_s(Address(rsp, 0)); + Label L; + __ bind(L); + __ fprem(); + __ fwait(); + __ fnstsw_ax(); + __ testl(rax, 0x400); + __ jcc(Assembler::notZero, L); + __ fxch(1); + __ fpop(); + __ fstp_s(Address(rsp, 0)); + __ movflt(xmm0, Address(rsp, 0)); + __ addptr(rsp, 8); + __ ret(0); + break; + } + case c1x_arithmetic_drem_id: { + __ subptr(rsp, 8); + __ movdbl(Address(rsp, 0), xmm1); + __ fld_d(Address(rsp, 0)); + __ movdbl(Address(rsp, 0), xmm0); + __ fld_d(Address(rsp, 0)); + Label L; + __ bind(L); + __ fprem(); + __ fwait(); + __ fnstsw_ax(); + __ testl(rax, 0x400); + __ jcc(Assembler::notZero, L); + __ fxch(1); + __ fpop(); + __ fstp_d(Address(rsp, 0)); + __ movdbl(xmm0, Address(rsp, 0)); + __ addptr(rsp, 8); + __ ret(0); + break; + } + case c1x_monitorenter_id: { + Label slow_case; + + Register obj = j_rarg0; + Register lock = j_rarg1; + + Register scratch1 = rax; + Register scratch2 = rbx; + assert_different_registers(obj, lock, scratch1, scratch2); + + // copied from LIR_Assembler::emit_lock + if (UseFastLocking) { + assert(BasicLock::displaced_header_offset_in_bytes() == 0, "lock_reg must point to the displaced header"); + __ lock_object(scratch1, obj, lock, scratch2, slow_case); + __ ret(0); + } + + __ bind(slow_case); + { + StubFrame f(sasm, "c1x_monitorenter", dont_gc_arguments); + OopMap* map = save_live_registers(sasm, 1, save_fpu_registers); + + // Called with store_parameter and not C abi + int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, monitorenter), obj, lock); + + oop_maps = new OopMapSet(); + oop_maps->add_gc_map(call_offset, map); + restore_live_registers(sasm, save_fpu_registers); + } + __ ret(0); + break; + } + case c1x_monitorexit_id: { + Label slow_case; + + Register obj = j_rarg0; + Register lock = j_rarg1; + + // needed in rax later on... + Register lock2 = rax; + __ mov(lock2, lock); + Register scratch1 = rbx; + assert_different_registers(obj, lock, scratch1, lock2); + + // copied from LIR_Assembler::emit_lock + if (UseFastLocking) { + assert(BasicLock::displaced_header_offset_in_bytes() == 0, "lock_reg must point to the displaced header"); + __ unlock_object(scratch1, obj, lock2, slow_case); + __ ret(0); + } + + __ bind(slow_case); + { + StubFrame f(sasm, "c1x_monitorexit", dont_gc_arguments); + OopMap* map = save_live_registers(sasm, 2, save_fpu_registers); + + // note: really a leaf routine but must setup last java sp + // => use call_RT for now (speed can be improved by + // doing last java sp setup manually) + int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, monitorexit), lock); + + oop_maps = new OopMapSet(); + oop_maps->add_gc_map(call_offset, map); + restore_live_registers(sasm, save_fpu_registers); + } + __ ret(0); + break; + } + + + + default: { StubFrame f(sasm, "unimplemented entry", dont_gc_arguments); __ movptr(rax, (int)id); diff -r 102466e70deb -r 91fe28b03d6a src/cpu/x86/vm/frame_x86.cpp --- a/src/cpu/x86/vm/frame_x86.cpp Thu Jan 20 15:52:05 2011 -0800 +++ b/src/cpu/x86/vm/frame_x86.cpp Wed Jan 26 18:17:37 2011 +0100 @@ -235,6 +235,9 @@ if (TracePcPatching) { tty->print_cr("patch_pc at address" INTPTR_FORMAT " [" INTPTR_FORMAT " -> " INTPTR_FORMAT "] ", &((address *)sp())[-1], ((address *)sp())[-1], pc); + tty->print_cr("sp[0]: " INTPTR_FORMAT, ((intptr_t*)sp())[0]); + tty->print_cr("sp[1]: " INTPTR_FORMAT, ((intptr_t*)sp())[1]); + tty->print_cr("sp[2]: " INTPTR_FORMAT, ((intptr_t*)sp())[2]); } ((address *)sp())[-1] = pc; _cb = CodeCache::find_blob(pc); diff -r 102466e70deb -r 91fe28b03d6a src/cpu/x86/vm/sharedRuntime_x86_64.cpp --- a/src/cpu/x86/vm/sharedRuntime_x86_64.cpp Thu Jan 20 15:52:05 2011 -0800 +++ b/src/cpu/x86/vm/sharedRuntime_x86_64.cpp Wed Jan 26 18:17:37 2011 +0100 @@ -2655,6 +2655,40 @@ __ bind(no_pending_exception); #endif + // (tw) Start of C1X uncommon trap code. + __ jmp(cont); + + int uncommon_trap_offset = __ pc() - start; + + // Warning: Duplicate code + + // Save everything in sight. + map = RegisterSaver::save_live_registers(masm, 0, &frame_size_in_words); + + // Normal deoptimization + + + // fetch_unroll_info needs to call last_java_frame() + __ set_last_Java_frame(noreg, noreg, NULL); + + __ movl(c_rarg1, (int32_t)Deoptimization::Unpack_reexecute); + __ movl(r14, c_rarg1); // save into r14 for later call to unpack_frames + __ mov(c_rarg0, r15_thread); + __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, Deoptimization::uncommon_trap))); + + // Need to have an oopmap that tells fetch_unroll_info where to + // find any register it might need. + + oop_maps->add_gc_map( __ pc()-start, map->deep_copy()); + + __ reset_last_Java_frame(false, false); + + Label after_fetch_unroll_info_call; + __ jmp(after_fetch_unroll_info_call); + + + // (tw) End of C1X uncommon trap code. + __ bind(cont); // Call C code. Need thread and this frame, but NOT official VM entry @@ -2684,6 +2718,8 @@ __ reset_last_Java_frame(false, false); + __ bind(after_fetch_unroll_info_call); + // Load UnrollBlock* into rdi __ mov(rdi, rax); @@ -2845,6 +2881,7 @@ _deopt_blob = DeoptimizationBlob::create(&buffer, oop_maps, 0, exception_offset, reexecute_offset, frame_size_in_words); _deopt_blob->set_unpack_with_exception_in_tls_offset(exception_in_tls_offset); + _deopt_blob->set_uncommon_trap_offset(uncommon_trap_offset); } #ifdef COMPILER2 diff -r 102466e70deb -r 91fe28b03d6a src/os/linux/vm/os_linux.cpp --- a/src/os/linux/vm/os_linux.cpp Thu Jan 20 15:52:05 2011 -0800 +++ b/src/os/linux/vm/os_linux.cpp Wed Jan 26 18:17:37 2011 +0100 @@ -3490,7 +3490,14 @@ void signalHandler(int sig, siginfo_t* info, void* uc) { assert(info != NULL && uc != NULL, "it must be old kernel"); + ResourceMark rm; + if (TraceSignals) { + tty->print_cr(err_msg("signal received: code=%d errno=%d signo=%d thread=%s address=%x", info->si_code, info->si_errno, info->si_signo, Thread::current()->name(), info->si_addr)); + } JVM_handle_linux_signal(sig, info, uc, true); + if (TraceSignals) { + tty->print_cr("signal handled"); + } } diff -r 102466e70deb -r 91fe28b03d6a src/os_cpu/linux_x86/vm/os_linux_x86.cpp --- a/src/os_cpu/linux_x86/vm/os_linux_x86.cpp Thu Jan 20 15:52:05 2011 -0800 +++ b/src/os_cpu/linux_x86/vm/os_linux_x86.cpp Wed Jan 26 18:17:37 2011 +0100 @@ -289,6 +289,17 @@ } #endif // AMD64 + if (TraceSignals) { + CodeBlob* cb = CodeCache::find_blob(pc); + if (cb != NULL && cb->is_nmethod()) { + nmethod* nm = (nmethod*)cb; + int rel = pc - nm->code_begin(); + tty->print_cr(err_msg("Implicit exception at %d of method %s", rel, nm->method()->name()->as_C_string())); + } else { + tty->print_cr("No code blob found for %x", pc); + } + } + // Handle ALL stack overflow variations here if (sig == SIGSEGV) { address addr = (address) info->si_addr; @@ -302,6 +313,7 @@ if (thread->thread_state() == _thread_in_Java) { // Throw a stack overflow exception. Guard pages will be reenabled // while unwinding the stack. + if (WizardMode) tty->print("implicit: %08x%08x\n", ((long)pc) >> 32, pc); stub = SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::STACK_OVERFLOW); } else { // Thread was in the vm or native code. Return and try to finish. @@ -387,8 +399,15 @@ #endif // AMD64 } else if (sig == SIGSEGV && !MacroAssembler::needs_explicit_null_check((intptr_t)info->si_addr)) { + if (TraceSignals) { + tty->print_cr("Implicit exception continuation"); + } // Determination of interpreter/vtable stub/compiled code null exception stub = SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::IMPLICIT_NULL); + } else if (sig == SIGSEGV) { + if (TraceSignals) { + tty->print_cr("would have needed explicit null check %d", (intptr_t)info->si_addr); + } } } else if (thread->thread_state() == _thread_in_vm && sig == SIGBUS && /* info->si_code == BUS_OBJERR && */ diff -r 102466e70deb -r 91fe28b03d6a src/share/tools/ProjectCreator/BuildConfig.java --- a/src/share/tools/ProjectCreator/BuildConfig.java Thu Jan 20 15:52:05 2011 -0800 +++ b/src/share/tools/ProjectCreator/BuildConfig.java Wed Jan 26 18:17:37 2011 +0100 @@ -252,12 +252,22 @@ void initDefaultDefines(Vector defines) { Vector sysDefines = new Vector(); - sysDefines.add("WIN32"); + if( Util.os().equals("Win32")) { + sysDefines.add("WIN32"); + sysDefines.add("HOTSPOT_LIB_ARCH=\\\"i386\\\""); + } else { + sysDefines.add("_AMD64_"); + sysDefines.add("AMD64"); + sysDefines.add("_WIN64"); + sysDefines.add("_LP64"); + if (System.getenv("MSC_VER") != null) + sysDefines.add("MSC_VER=" + System.getenv("MSC_VER")); + sysDefines.add("HOTSPOT_LIB_ARCH=\\\"amd64\\\""); + } sysDefines.add("_WINDOWS"); sysDefines.add("HOTSPOT_BUILD_USER="+System.getProperty("user.name")); sysDefines.add("HOTSPOT_BUILD_TARGET=\\\""+get("Build")+"\\\""); sysDefines.add("_JNI_IMPLEMENTATION_"); - sysDefines.add("HOTSPOT_LIB_ARCH=\\\"i386\\\""); sysDefines.addAll(defines); diff -r 102466e70deb -r 91fe28b03d6a src/share/tools/ProjectCreator/ProjectCreator.java --- a/src/share/tools/ProjectCreator/ProjectCreator.java Thu Jan 20 15:52:05 2011 -0800 +++ b/src/share/tools/ProjectCreator/ProjectCreator.java Wed Jan 26 18:17:37 2011 +0100 @@ -1,3 +1,6 @@ +import java.util.Map; +import java.util.Map.Entry; + /* * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. diff -r 102466e70deb -r 91fe28b03d6a src/share/tools/ProjectCreator/Util.java --- a/src/share/tools/ProjectCreator/Util.java Thu Jan 20 15:52:05 2011 -0800 +++ b/src/share/tools/ProjectCreator/Util.java Wed Jan 26 18:17:37 2011 +0100 @@ -23,6 +23,7 @@ */ import java.util.*; +import java.util.Map.Entry; import java.io.File; public class Util { @@ -84,5 +85,25 @@ } static String sep = File.separator; - static String os = "Win32"; //System.getProperty("os.name"); + + private static String _os; + + static String os() { + if( _os==null) { + + for(Map.Entry entry: System.getenv().entrySet()) + if("PLATFORM_ARCH_MODEL".equals(entry.getKey().toUpperCase())) { + String archModel = entry.getValue(); + if("x86_32".equals(archModel)) + _os = "Win32"; + else if("x86_64".equals(archModel)) + _os = "x64"; + else + throw new RuntimeException("Unsupported PLATFORM_ARCH_MODEL " + archModel); + return _os; + } + throw new RuntimeException("PLATFORM_ARCH_MODEL not specified"); + } + return _os; + } } diff -r 102466e70deb -r 91fe28b03d6a src/share/tools/ProjectCreator/WinGammaPlatformVC6.java --- a/src/share/tools/ProjectCreator/WinGammaPlatformVC6.java Thu Jan 20 15:52:05 2011 -0800 +++ b/src/share/tools/ProjectCreator/WinGammaPlatformVC6.java Wed Jan 26 18:17:37 2011 +0100 @@ -288,6 +288,6 @@ } String makeCfgName(String flavourBuild) { - return "vm - "+ Util.os + " " + flavourBuild; + return "vm - "+ "Win32" + " " + flavourBuild; } } diff -r 102466e70deb -r 91fe28b03d6a src/share/tools/ProjectCreator/WinGammaPlatformVC7.java --- a/src/share/tools/ProjectCreator/WinGammaPlatformVC7.java Thu Jan 20 15:52:05 2011 -0800 +++ b/src/share/tools/ProjectCreator/WinGammaPlatformVC7.java Wed Jan 26 18:17:37 2011 +0100 @@ -56,7 +56,7 @@ ); startTag("Platforms", null); - tag("Platform", new String[] {"Name", Util.os}); + tag("Platform", new String[] {"Name", Util.os()}); endTag("Platforms"); startTag("Configurations", null); @@ -260,6 +260,9 @@ rv.add(container); } + rv.add(new DirectoryFilter("C1X", "share/vm/c1x", sbase)); + rv.add(new DirectoryFilter("C1", "share/vm/c1", sbase)); + ContainerFilter generated = new ContainerFilter("Generated"); ContainerFilter c1Generated = new ContainerFilter("C1"); c1Generated.add(new SpecificPathFilter("C++ Interpreter Generated", new String[] {".*compiler1/generated/jvmtifiles/bytecodeInterpreterWithChecks.+"})); @@ -462,7 +465,7 @@ "PreprocessorDefinitions", "NDEBUG", "MkTypLibCompatible", "TRUE", "SuppressStartupBanner", "TRUE", - "TargetEnvironment", "1", + "TargetEnvironment", Util.os().equals("Win32") ? "1" : "3", "TypeLibraryName", cfg.get("OutputDir") + Util.sep + "vm.tlb", "HeaderFileName", "" } @@ -611,7 +614,7 @@ addAttr(rv, "BaseAddress", "0x8000000"); addAttr(rv, "ImportLibrary", outDir+Util.sep+"jvm.lib"); // Set /MACHINE option. 1 is machineX86 - addAttr(rv, "TargetMachine", "1"); + addAttr(rv, "TargetMachine", Util.os().equals("Win32") ? "1" : "17"); return rv; } @@ -694,6 +697,6 @@ } String makeCfgName(String flavourBuild) { - return flavourBuild + "|" + Util.os; + return flavourBuild + "|" + Util.os(); } } diff -r 102466e70deb -r 91fe28b03d6a src/share/tools/ProjectCreator/WinGammaPlatformVC8.java --- a/src/share/tools/ProjectCreator/WinGammaPlatformVC8.java Thu Jan 20 15:52:05 2011 -0800 +++ b/src/share/tools/ProjectCreator/WinGammaPlatformVC8.java Wed Jan 26 18:17:37 2011 +0100 @@ -40,6 +40,8 @@ addAttr(rv, "UsePrecompiledHeader", "2"); // Set /EHsc- option. 0 is cppExceptionHandlingNo addAttr(rv, "ExceptionHandling", "0"); + // Parallel compilation + addAttr(rv, "AdditionalOptions", "/MP"); // enable multi process builds extAttr(rv, "AdditionalOptions", "/MP"); diff -r 102466e70deb -r 91fe28b03d6a src/share/vm/asm/codeBuffer.cpp --- a/src/share/vm/asm/codeBuffer.cpp Thu Jan 20 15:52:05 2011 -0800 +++ b/src/share/vm/asm/codeBuffer.cpp Wed Jan 26 18:17:37 2011 +0100 @@ -435,8 +435,9 @@ { // not sure why this is here, but why not... - int alignSize = MAX2((intx) sizeof(jdouble), CodeEntryAlignment); - assert( (dest->_total_start - _insts.start()) % alignSize == 0, "copy must preserve alignment"); + // (tw) disabled assert + // int alignSize = MAX2((intx) sizeof(jdouble), CodeEntryAlignment); + // assert( (dest->_total_start - _insts.start()) % alignSize == 0, "copy must preserve alignment"); } const CodeSection* prev_cs = NULL; diff -r 102466e70deb -r 91fe28b03d6a src/share/vm/c1/c1_Compiler.cpp --- a/src/share/vm/c1/c1_Compiler.cpp Thu Jan 20 15:52:05 2011 -0800 +++ b/src/share/vm/c1/c1_Compiler.cpp Wed Jan 26 18:17:37 2011 +0100 @@ -90,6 +90,7 @@ void Compiler::compile_method(ciEnv* env, ciMethod* method, int entry_bci) { + assert(!UseC1X, "c1 called in UseC1X mode!"); // Allocate buffer blob once at startup since allocation for each // compilation seems to be too expensive (at least on Intel win32). BufferBlob* buffer_blob = CompilerThread::current()->get_buffer_blob(); diff -r 102466e70deb -r 91fe28b03d6a src/share/vm/c1/c1_LIRGenerator.cpp --- a/src/share/vm/c1/c1_LIRGenerator.cpp Thu Jan 20 15:52:05 2011 -0800 +++ b/src/share/vm/c1/c1_LIRGenerator.cpp Wed Jan 26 18:17:37 2011 +0100 @@ -2513,7 +2513,7 @@ // Load CallSite object from constant pool cache. __ oop2reg(cpcache->constant_encoding(), tmp); - __ load(new LIR_Address(tmp, call_site_offset, T_OBJECT), tmp); + __ load(new LIR_Address(tmp, (int)call_site_offset, T_OBJECT), tmp); // Load target MethodHandle from CallSite object. __ load(new LIR_Address(tmp, java_dyn_CallSite::target_offset_in_bytes(), T_OBJECT), receiver); diff -r 102466e70deb -r 91fe28b03d6a src/share/vm/c1/c1_Runtime1.cpp --- a/src/share/vm/c1/c1_Runtime1.cpp Thu Jan 20 15:52:05 2011 -0800 +++ b/src/share/vm/c1/c1_Runtime1.cpp Wed Jan 26 18:17:37 2011 +0100 @@ -172,8 +172,15 @@ case slow_subtype_check_id: case fpu2long_stub_id: case unwind_exception_id: - case counter_overflow_id: -#if defined(SPARC) || defined(PPC) + case c1x_verify_pointer_id: + case c1x_unwind_exception_call_id: + case c1x_slow_subtype_check_id: + case c1x_arithmetic_frem_id: + case c1x_arithmetic_drem_id: +#ifndef TIERED + case counter_overflow_id: // Not generated outside the tiered world +#endif +#ifdef SPARC case handle_exception_nofpu_id: // Unused on sparc #endif break; @@ -430,6 +437,9 @@ JRT_ENTRY_NO_ASYNC(static address, exception_handler_for_pc_helper(JavaThread* thread, oopDesc* ex, address pc, nmethod*& nm)) Handle exception(thread, ex); + if (UseC1X && exception.is_null()) { + exception = Exceptions::new_exception(thread, vmSymbols::java_lang_NullPointerException(), NULL); + } nm = CodeCache::find_nmethod(pc); assert(nm != NULL, "this is not an nmethod"); // Adjust the pc as needed/ @@ -619,12 +629,22 @@ JRT_ENTRY_NO_ASYNC(void, Runtime1::monitorenter(JavaThread* thread, oopDesc* obj, BasicObjectLock* lock)) NOT_PRODUCT(_monitorenter_slowcase_cnt++;) +#ifdef ASSERT + if (TraceC1X >= 3) { + tty->print_cr("entered locking slow case with obj=" INTPTR_FORMAT " and lock= " INTPTR_FORMAT, obj, lock); + } if (PrintBiasedLockingStatistics) { Atomic::inc(BiasedLocking::slow_path_entry_count_addr()); } +#endif Handle h_obj(thread, obj); assert(h_obj()->is_oop(), "must be NULL or an object"); if (UseBiasedLocking) { + if (UseFastLocking) { + assert(obj == lock->obj(), "must match"); + } else { + lock->set_obj(obj); + } // Retry fast entry if bias is revoked to avoid unnecessary inflation ObjectSynchronizer::fast_enter(h_obj, lock->lock(), true, CHECK); } else { @@ -637,6 +657,14 @@ ObjectSynchronizer::fast_enter(h_obj, lock->lock(), false, THREAD); } } +#ifdef ASSERT + if (TraceC1X >= 3) { + tty->print_cr("exiting locking lock state: obj=" INTPTR_FORMAT, lock->obj()); + lock->lock()->print_on(tty); + tty->print_cr(""); + tty->print_cr("done"); + } +#endif JRT_END @@ -648,7 +676,19 @@ EXCEPTION_MARK; oop obj = lock->obj(); - assert(obj->is_oop(), "must be NULL or an object"); + +#ifdef DEBUG + if (!obj->is_oop()) { + ResetNoHandleMark rhm; + nmethod* method = thread->last_frame().cb()->as_nmethod_or_null(); + if (method != NULL) { + tty->print_cr("ERROR in monitorexit in method %s wrong obj " INTPTR_FORMAT, method->name(), obj); + } + thread->print_stack_on(tty); + assert(false, "invalid lock object pointer dected"); + } +#endif + if (UseFastLocking) { // When using fast locking, the compiled code has already tried the fast case ObjectSynchronizer::slow_exit(obj, lock->lock(), THREAD); @@ -844,7 +884,9 @@ assert(k != NULL && !k->is_klass(), "must be class mirror or other Java constant"); } break; - default: Unimplemented(); + default: + tty->print_cr("Unhandled bytecode: %d stub_id=%d caller=%s bci=%d pc=%d", code, stub_id, caller_method->name()->as_C_string(), bci, caller_frame.pc()); + Unimplemented(); } // convert to handle load_klass = Handle(THREAD, k); diff -r 102466e70deb -r 91fe28b03d6a src/share/vm/c1/c1_Runtime1.hpp --- a/src/share/vm/c1/c1_Runtime1.hpp Thu Jan 20 15:52:05 2011 -0800 +++ b/src/share/vm/c1/c1_Runtime1.hpp Wed Jan 26 18:17:37 2011 +0100 @@ -69,6 +69,16 @@ stub(g1_post_barrier_slow) \ stub(fpu2long_stub) \ stub(counter_overflow) \ + stub(c1x_unwind_exception_call) \ + stub(c1x_handle_exception) \ + stub(c1x_global_implicit_null) \ + stub(c1x_throw_div0_exception) \ + stub(c1x_slow_subtype_check) \ + stub(c1x_arithmetic_frem) \ + stub(c1x_arithmetic_drem) \ + stub(c1x_monitorenter) \ + stub(c1x_monitorexit) \ + stub(c1x_verify_pointer) \ last_entry(number_of_ids) #define DECLARE_STUB_ID(x) x ## _id , @@ -120,6 +130,7 @@ static OopMapSet* generate_code_for(StubID id, StubAssembler* masm); static OopMapSet* generate_exception_throw(StubAssembler* sasm, address target, bool has_argument); static void generate_handle_exception(StubAssembler *sasm, OopMapSet* oop_maps, OopMap* oop_map, bool ignore_fpu_registers = false); + static void c1x_generate_handle_exception(StubAssembler *sasm, OopMapSet* oop_maps, OopMap* oop_map); static void generate_unwind_exception(StubAssembler *sasm); static OopMapSet* generate_patching(StubAssembler* sasm, address target); diff -r 102466e70deb -r 91fe28b03d6a src/share/vm/c1/c1_globals.hpp --- a/src/share/vm/c1/c1_globals.hpp Thu Jan 20 15:52:05 2011 -0800 +++ b/src/share/vm/c1/c1_globals.hpp Wed Jan 26 18:17:37 2011 +0100 @@ -47,6 +47,16 @@ // #define C1_FLAGS(develop, develop_pd, product, product_pd, notproduct) \ \ + product(bool, UseC1X, false, \ + "Use C1X instead of C1") \ + product(bool, C1XBailoutIsFatal, true, \ + "Abort the VM on C1X bailout") \ + product(bool, BootstrapC1X, false, \ + "Bootstrap C1X before running Java main method") \ + product(intx, TraceC1X, 0, \ + "Trace level for C1X") \ + product(bool, TraceSignals, false, \ + "Trace signals and implicit exception handling") \ /* Printing */ \ notproduct(bool, PrintC1Statistics, false, \ "Print Compiler1 statistics" ) \ @@ -227,7 +237,7 @@ develop(bool, UseFastNewObjectArray, true, \ "Use fast inlined object array allocation") \ \ - develop(bool, UseFastLocking, true, \ + product(bool, UseFastLocking, true, \ "Use fast inlined locking code") \ \ develop(bool, UseSlowPath, false, \ diff -r 102466e70deb -r 91fe28b03d6a src/share/vm/c1x/c1x_CodeInstaller.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/vm/c1x/c1x_CodeInstaller.cpp Wed Jan 26 18:17:37 2011 +0100 @@ -0,0 +1,737 @@ +/* + * Copyright 2000-2010 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +#include "precompiled.hpp" +#include "c1x/c1x_Compiler.hpp" +#include "c1x/c1x_CodeInstaller.hpp" +#include "c1x/c1x_JavaAccess.hpp" +#include "c1x/c1x_VmIds.hpp" +#include "c1/c1_Runtime1.hpp" +#include "classfile/vmSymbols.hpp" +#include "vmreg_x86.inline.hpp" + + +// TODO this should be handled in a more robust way - not hard coded... +Register CPU_REGS[] = { rax, rcx, rdx, rbx, rsp, rbp, rsi, rdi, r8, r9, r10, r11, r12, r13, r14, r15 }; +bool OOP_ALLOWED[] = {true, true, true, true, false, false, true, true, true, true, false, true, true, true, true, true}; +const static int NUM_CPU_REGS = sizeof(CPU_REGS) / sizeof(Register); +XMMRegister XMM_REGS[] = { xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7, xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15 }; +const static int NUM_XMM_REGS = sizeof(XMM_REGS) / sizeof(XMMRegister); +const static int NUM_REGS = NUM_CPU_REGS + NUM_XMM_REGS; +const static jlong NO_REF_MAP = 0x8000000000000000L; + +// convert c1x register indices (as used in oop maps) to hotspot registers +VMReg get_hotspot_reg(jint c1x_reg) { + + assert(c1x_reg >= 0 && c1x_reg < NUM_REGS, "invalid register number"); + if (c1x_reg < NUM_CPU_REGS) { + return CPU_REGS[c1x_reg]->as_VMReg(); + } else { + return XMM_REGS[c1x_reg - NUM_CPU_REGS]->as_VMReg(); + } +} + +static bool is_bit_set(oop bit_map, int i) { + const int MapWordBits = 64; + if (i < MapWordBits) { + jlong low = CiBitMap::low(bit_map); + return (low & (1L << i)) != 0; + } else { + jint extra_idx = (i - MapWordBits) / MapWordBits; + arrayOop extra = (arrayOop) CiBitMap::extra(bit_map); + assert(extra_idx >= 0 && extra_idx < extra->length(), "unexpected index"); + jlong word = ((jlong*) extra->base(T_LONG))[extra_idx]; + return (word & (1L << (i % MapWordBits))) != 0; + } +} + +// creates a hotspot oop map out of the byte arrays provided by CiDebugInfo +static OopMap* create_oop_map(jint frame_size, jint parameter_count, oop debug_info) { + OopMap* map = new OopMap(frame_size, parameter_count); + oop register_map = (oop) CiDebugInfo::registerRefMap(debug_info); + oop frame_map = (oop) CiDebugInfo::frameRefMap(debug_info); + + if (register_map != NULL) { + assert(CiBitMap::size(register_map) == (unsigned) NUM_CPU_REGS, "unexpected register_map length"); + for (jint i = 0; i < NUM_CPU_REGS; i++) { + bool is_oop = is_bit_set(register_map, i); + VMReg reg = get_hotspot_reg(i); + if (is_oop) { + assert(OOP_ALLOWED[i], "this register may never be an oop, register map misaligned?"); + map->set_oop(reg); + } else { + map->set_value(reg); + } + } + } + + if (frame_size > 0) { + assert(CiBitMap::size(frame_map) == frame_size / HeapWordSize, "unexpected frame_map length"); + + for (jint i = 0; i < frame_size / HeapWordSize; i++) { + bool is_oop = is_bit_set(frame_map, i); + // hotspot stack slots are 4 bytes + VMReg reg = VMRegImpl::stack2reg(i * 2); + if (is_oop) { + map->set_oop(reg); + } else { + map->set_value(reg); + } + } + } else { + assert(frame_map == NULL || CiBitMap::size(frame_map) == 0, "cannot have frame_map for frames with size 0"); + } + + return map; +} + +// TODO: finish this - c1x doesn't provide any scope values at the moment +static ScopeValue* get_hotspot_value(oop value, int frame_size) { + if (value == CiValue::IllegalValue()) { + return new LocationValue(Location::new_stk_loc(Location::invalid, 0)); + } + + BasicType type = C1XCompiler::kindToBasicType(CiKind::typeChar(CiValue::kind(value))); + Location::Type locationType = Location::normal; + if (type == T_OBJECT || type == T_ARRAY) locationType = Location::oop; + if (value->is_a(CiRegisterValue::klass())) { + jint number = CiRegister::number(CiRegisterValue::reg(value)); + if (number < 16) { + return new LocationValue(Location::new_reg_loc(locationType, as_Register(number)->as_VMReg())); + } else { + return new LocationValue(Location::new_reg_loc(locationType, as_XMMRegister(number - 16)->as_VMReg())); + } + } else if (value->is_a(CiStackSlot::klass())) { + jint index = CiStackSlot::index(value); + if (index >= 0) { + return new LocationValue(Location::new_stk_loc(locationType, index * HeapWordSize)); + } else { + int frame_size_bytes = frame_size + 2 * HeapWordSize; + return new LocationValue(Location::new_stk_loc(locationType, -(index * HeapWordSize) + frame_size_bytes)); + } + } else if (value->is_a(CiConstant::klass())){ + oop obj = CiConstant::object(value); + jlong prim = CiConstant::primitive(value); + if (type == T_INT || type == T_FLOAT || type == T_SHORT || type == T_CHAR || type == T_BOOLEAN || type == T_BYTE) { + return new ConstantIntValue(*(jint*)&prim); + } else if (type == T_LONG || type == T_DOUBLE) { + return new ConstantLongValue(prim); + } else if (type == T_OBJECT) { + oop obj = CiConstant::object(value); + if (obj == NULL) { + return new ConstantOopWriteValue(NULL); + } else { + obj->print(); + ShouldNotReachHere(); + } + } else if (type == T_ADDRESS) { + return new ConstantLongValue(prim); + } + tty->print("%i", type); + ShouldNotReachHere(); + } else { + value->klass()->print(); + value->print(); + ShouldNotReachHere(); + } +} + +// constructor used to create a method +CodeInstaller::CodeInstaller(Handle target_method) { + ciMethod *ciMethodObject = NULL; + { + No_Safepoint_Verifier no_safepoint; + _env = CURRENT_ENV; + + initialize_fields(target_method); + assert(_hotspot_method != NULL && _name == NULL, "installMethod needs NON-NULL method and NULL name"); + assert(_hotspot_method->is_a(HotSpotMethodResolved::klass()), "installMethod needs a HotSpotMethodResolved"); + + methodOop method = VmIds::get(HotSpotMethodResolved::vmId(_hotspot_method)); + ciMethodObject = (ciMethod *) _env->get_object(method); + _parameter_count = method->size_of_parameters(); + } + + // (very) conservative estimate: each site needs a relocation + //CodeBuffer buffer("temp c1x method", _total_size, _sites->length() * relocInfo::length_limit); + CodeBuffer buffer(CompilerThread::current()->get_buffer_blob()); + initialize_buffer(buffer); + process_exception_handlers(); + + int stack_slots = (_frame_size / HeapWordSize) + 2; // conversion to words, need to add two slots for ret address and frame pointer + ThreadToNativeFromVM t((JavaThread*) Thread::current()); + _env->register_method(ciMethodObject, -1, &_offsets, _custom_stack_area_offset, &buffer, stack_slots, _debug_recorder->_oopmaps, &_exception_handler_table, + &_implicit_exception_table, C1XCompiler::instance(), _env->comp_level(), false, false); + +} + +// constructor used to create a stub +CodeInstaller::CodeInstaller(Handle target_method, jlong& id) { + No_Safepoint_Verifier no_safepoint; + _env = CURRENT_ENV; + + initialize_fields(target_method); + assert(_hotspot_method == NULL && _name != NULL, "installMethod needs NON-NULL name and NULL method"); + + // (very) conservative estimate: each site needs a relocation + CodeBuffer buffer(CompilerThread::current()->get_buffer_blob()); + initialize_buffer(buffer); + + const char* cname = java_lang_String::as_utf8_string(_name); + BufferBlob* blob = BufferBlob::create(strdup(cname), &buffer); // this is leaking strings... but only a limited number of stubs will be created + IF_TRACE_C1X_3 Disassembler::decode((CodeBlob*) blob); + id = VmIds::addStub(blob->code_begin()); +} + +void CodeInstaller::initialize_fields(Handle target_method) { + _citarget_method = HotSpotTargetMethod::targetMethod(target_method); + _hotspot_method = HotSpotTargetMethod::method(target_method); + _name = HotSpotTargetMethod::name(target_method); + _sites = (arrayOop) HotSpotTargetMethod::sites(target_method); + oop assumptions = CiTargetMethod::assumptions(_citarget_method); + if (assumptions != NULL) { + _assumptions = (arrayOop) CiAssumptions::list(assumptions); + } else { + _assumptions = NULL; + } + _exception_handlers = (arrayOop) HotSpotTargetMethod::exceptionHandlers(target_method); + + _code = (arrayOop) CiTargetMethod::targetCode(_citarget_method); + _code_size = CiTargetMethod::targetCodeSize(_citarget_method); + _frame_size = CiTargetMethod::frameSize(_citarget_method); + _custom_stack_area_offset = CiTargetMethod::customStackAreaOffset(_citarget_method); + + + // (very) conservative estimate: each site needs a constant section entry + _constants_size = _sites->length() * BytesPerLong; + _total_size = align_size_up(_code_size, HeapWordSize) + _constants_size; + + _next_call_type = MARK_INVOKE_INVALID; +} + +// perform data and call relocation on the CodeBuffer +void CodeInstaller::initialize_buffer(CodeBuffer& buffer) { + int locs_buffer_size = _sites->length() * (relocInfo::length_limit + sizeof(relocInfo)); + char* locs_buffer = NEW_RESOURCE_ARRAY(char, locs_buffer_size); + buffer.insts()->initialize_shared_locs((relocInfo*)locs_buffer, locs_buffer_size / sizeof(relocInfo)); + buffer.initialize_stubs_size(256); + buffer.initialize_consts_size(_constants_size); + + _oop_recorder = new OopRecorder(_env->arena()); + _env->set_oop_recorder(_oop_recorder); + _debug_recorder = new DebugInformationRecorder(_env->oop_recorder()); + _debug_recorder->set_oopmaps(new OopMapSet()); + _dependencies = new Dependencies(_env); + + _env->set_oop_recorder(_oop_recorder); + _env->set_debug_info(_debug_recorder); + _env->set_dependencies(_dependencies); + buffer.initialize_oop_recorder(_oop_recorder); + + _instructions = buffer.insts(); + _constants = buffer.consts(); + + // copy the code into the newly created CodeBuffer + memcpy(_instructions->start(), _code->base(T_BYTE), _code_size); + _instructions->set_end(_instructions->start() + _code_size); + + oop* sites = (oop*) _sites->base(T_OBJECT); + for (int i = 0; i < _sites->length(); i++) { + oop site = sites[i]; + jint pc_offset = CiTargetMethod_Site::pcOffset(site); + + if (site->is_a(CiTargetMethod_Safepoint::klass())) { + TRACE_C1X_4("safepoint at %i", pc_offset); + site_Safepoint(buffer, pc_offset, site); + } else if (site->is_a(CiTargetMethod_Call::klass())) { + TRACE_C1X_4("call at %i", pc_offset); + site_Call(buffer, pc_offset, site); + } else if (site->is_a(CiTargetMethod_DataPatch::klass())) { + TRACE_C1X_4("datapatch at %i", pc_offset); + site_DataPatch(buffer, pc_offset, site); + } else if (site->is_a(CiTargetMethod_Mark::klass())) { + TRACE_C1X_4("mark at %i", pc_offset); + site_Mark(buffer, pc_offset, site); + } else { + fatal("unexpected Site subclass"); + } + } + + + if (_assumptions != NULL) { + oop* assumptions = (oop*) _assumptions->base(T_OBJECT); + for (int i = 0; i < _assumptions->length(); ++i) { + oop assumption = assumptions[i]; + if (assumption != NULL) { + if (assumption->is_a(CiAssumptions_ConcreteSubtype::klass())) { + assumption_ConcreteSubtype(assumption); + } else if (assumption->is_a(CiAssumptions_ConcreteMethod::klass())) { + assumption_ConcreteMethod(assumption); + } else { + fatal("unexpected Assumption subclass"); + } + } + } + } +} + +void CodeInstaller::assumption_ConcreteSubtype(oop assumption) { + oop context_oop = CiAssumptions_ConcreteSubtype::context(assumption); + oop type_oop = CiAssumptions_ConcreteSubtype::subtype(assumption); + + ciKlass* context = (ciKlass*) CURRENT_ENV->get_object(java_lang_Class::as_klassOop(HotSpotTypeResolved::javaMirror(context_oop))); + ciKlass* type = (ciKlass*) CURRENT_ENV->get_object(java_lang_Class::as_klassOop(HotSpotTypeResolved::javaMirror(type_oop))); + + _dependencies->assert_leaf_type(type); + if (context != type) { + assert(context->is_abstract(), ""); + ThreadToNativeFromVM trans(JavaThread::current()); + _dependencies->assert_abstract_with_unique_concrete_subtype(context, type); + } +} + +void CodeInstaller::assumption_ConcreteMethod(oop assumption) { + oop context_oop = CiAssumptions_ConcreteMethod::context(assumption); + oop method_oop = CiAssumptions_ConcreteMethod::method(assumption); + jlong context_oop_id = HotSpotMethodResolved::vmId(context_oop); + jlong method_oop_id = HotSpotMethodResolved::vmId(method_oop); + methodOop method = VmIds::get(method_oop_id); + methodOop context = VmIds::get(context_oop_id); + + ciMethod* m = (ciMethod*) CURRENT_ENV->get_object(method); + ciMethod* c = (ciMethod*) CURRENT_ENV->get_object(context); + ciKlass* context_klass = c->holder(); + { + ThreadToNativeFromVM trans(JavaThread::current()); + _dependencies->assert_unique_concrete_method(context_klass, m); + } +} + +void CodeInstaller::process_exception_handlers() { + // allocate some arrays for use by the collection code. + const int num_handlers = 5; + GrowableArray* bcis = new GrowableArray (num_handlers); + GrowableArray* scope_depths = new GrowableArray (num_handlers); + GrowableArray* pcos = new GrowableArray (num_handlers); + + if (_exception_handlers != NULL) { + oop* exception_handlers = (oop*) _exception_handlers->base(T_OBJECT); + for (int i = 0; i < _exception_handlers->length(); i++) { + jint pc_offset = CiTargetMethod_Site::pcOffset(exception_handlers[i]); + int start = i; + while ((i + 1) < _exception_handlers->length() && CiTargetMethod_Site::pcOffset(exception_handlers[i + 1]) == pc_offset) + i++; + + // empty the arrays + bcis->trunc_to(0); + scope_depths->trunc_to(0); + pcos->trunc_to(0); + + for (int j = start; j <= i; j++) { + oop exc = exception_handlers[j]; + jint handler_offset = CiTargetMethod_ExceptionHandler::handlerPos(exc); + jint handler_bci = CiTargetMethod_ExceptionHandler::handlerBci(exc); + jint bci = CiTargetMethod_ExceptionHandler::bci(exc); + jint scope_level = CiTargetMethod_ExceptionHandler::scopeLevel(exc); + Handle handler_type = CiTargetMethod_ExceptionHandler::exceptionType(exc); + + assert(handler_offset != -1, "must have been generated"); + + int e = bcis->find(handler_bci); + if (e >= 0 && scope_depths->at(e) == scope_level) { + // two different handlers are declared to dispatch to the same + // catch bci. During parsing we created edges for each + // handler but we really only need one. The exception handler + // table will also get unhappy if we try to declare both since + // it's nonsensical. Just skip this handler. + continue; + } + + bcis->append(handler_bci); + if (handler_bci == -1) { + // insert a wildcard handler at scope depth 0 so that the + // exception lookup logic with find it. + scope_depths->append(0); + } else { + scope_depths->append(scope_level); + } + pcos->append(handler_offset); + + // stop processing once we hit a catch any + // if (handler->is_catch_all()) { + // assert(i == handlers->length() - 1, "catch all must be last handler"); + // } + + } + _exception_handler_table.add_subtable(pc_offset, bcis, scope_depths, pcos); + } + } + +} + +void CodeInstaller::record_scope(jint pc_offset, oop code_pos) { + oop caller_pos = CiCodePos::caller(code_pos); + if (caller_pos != NULL) { + record_scope(pc_offset, caller_pos); + } + oop frame = NULL; + if (code_pos->klass()->klass_part()->name() == vmSymbols::com_sun_cri_ci_CiDebugInfo_Frame()) { + frame = code_pos; + } + + oop hotspot_method = CiCodePos::method(code_pos); + assert(hotspot_method != NULL && hotspot_method->is_a(HotSpotMethodResolved::klass()), "unexpected hotspot method"); + methodOop method = VmIds::get(HotSpotMethodResolved::vmId(hotspot_method)); + ciMethod *cimethod = (ciMethod *) _env->get_object(method); + jint bci = CiCodePos::bci(code_pos); + bool reexecute; + if (bci == -1) { + reexecute = false; + } else { + Bytecodes::Code code = Bytecodes::java_code_at(method->bcp_from(bci)); + reexecute = Interpreter::bytecode_should_reexecute(code); + } + + if (TraceC1X >= 2) { + tty->print_cr("Recording scope pc_offset=%d bci=%d frame=%d", pc_offset, bci, frame); + } + + if (frame != NULL) { + jint local_count = CiDebugInfo_Frame::numLocals(frame); + jint expression_count = CiDebugInfo_Frame::numStack(frame); + jint monitor_count = CiDebugInfo_Frame::numLocks(frame); + arrayOop values = (arrayOop) CiDebugInfo_Frame::values(frame); + + assert(local_count + expression_count + monitor_count == values->length(), "unexpected values length"); + + GrowableArray* locals = new GrowableArray (); + GrowableArray* expressions = new GrowableArray (); + GrowableArray* monitors = new GrowableArray (); + + if (TraceC1X >= 2) { + tty->print_cr("Scope at bci %d with %d values", bci, values->length()); + tty->print_cr("%d locals %d expressions, %d monitors", local_count, expression_count, monitor_count); + } + + for (jint i = 0; i < values->length(); i++) { + ScopeValue* value = get_hotspot_value(((oop*) values->base(T_OBJECT))[i], _frame_size); + + if (i < local_count) { + locals->append(value); + } else if (i < local_count + expression_count) { + expressions->append(value); + } else { + assert(value->is_location(), "invalid monitor location"); + LocationValue* loc = (LocationValue*)value; + int monitor_offset = loc->location().stack_offset(); + LocationValue* obj = new LocationValue(Location::new_stk_loc(Location::oop, monitor_offset + BasicObjectLock::obj_offset_in_bytes())); + monitors->append(new MonitorValue(obj, Location::new_stk_loc(Location::normal, monitor_offset + BasicObjectLock::lock_offset_in_bytes()))); + } + } + DebugToken* locals_token = _debug_recorder->create_scope_values(locals); + DebugToken* expressions_token = _debug_recorder->create_scope_values(expressions); + DebugToken* monitors_token = _debug_recorder->create_monitor_values(monitors); + + _debug_recorder->describe_scope(pc_offset, cimethod, bci, reexecute, false, false, locals_token, expressions_token, monitors_token); + } else { + _debug_recorder->describe_scope(pc_offset, cimethod, bci, reexecute, false, false, NULL, NULL, NULL); + } +} + +void CodeInstaller::site_Safepoint(CodeBuffer& buffer, jint pc_offset, oop site) { + oop debug_info = CiTargetMethod_Safepoint::debugInfo(site); + assert(debug_info != NULL, "debug info expected"); + + // address instruction = _instructions->start() + pc_offset; + // jint next_pc_offset = Assembler::locate_next_instruction(instruction) - _instructions->start(); + _debug_recorder->add_safepoint(pc_offset, create_oop_map(_frame_size, _parameter_count, debug_info)); + + oop code_pos = CiDebugInfo::codePos(debug_info); + record_scope(pc_offset, code_pos); + + _debug_recorder->end_safepoint(pc_offset); +} + +void CodeInstaller::site_Call(CodeBuffer& buffer, jint pc_offset, oop site) { + oop runtime_call = CiTargetMethod_Call::runtimeCall(site); + oop hotspot_method = CiTargetMethod_Call::method(site); + oop symbol = CiTargetMethod_Call::symbol(site); + oop global_stub = CiTargetMethod_Call::globalStubID(site); + + oop debug_info = CiTargetMethod_Call::debugInfo(site); + + assert((runtime_call ? 1 : 0) + (hotspot_method ? 1 : 0) + (symbol ? 1 : 0) + (global_stub ? 1 : 0) == 1, "Call site needs exactly one type"); + + assert(NativeCall::instruction_size == (int)NativeJump::instruction_size, "unexpected size)"); + jint next_pc_offset = pc_offset + NativeCall::instruction_size; + + if (debug_info != NULL) { + _debug_recorder->add_safepoint(next_pc_offset, create_oop_map(_frame_size, _parameter_count, debug_info)); + oop code_pos = CiDebugInfo::codePos(debug_info); + record_scope(next_pc_offset, code_pos); + } + + if (runtime_call != NULL) { + NativeCall* call = nativeCall_at(_instructions->start() + pc_offset); + if (runtime_call == CiRuntimeCall::Debug()) { + TRACE_C1X_3("CiRuntimeCall::Debug()"); + } else if (runtime_call == CiRuntimeCall::UnwindException()) { + call->set_destination(Runtime1::entry_for(Runtime1::c1x_unwind_exception_call_id)); + _instructions->relocate(call->instruction_address(), runtime_call_Relocation::spec(), Assembler::call32_operand); + TRACE_C1X_3("CiRuntimeCall::UnwindException()"); + } else if (runtime_call == CiRuntimeCall::HandleException()) { + call->set_destination(Runtime1::entry_for(Runtime1::c1x_handle_exception_id)); + _instructions->relocate(call->instruction_address(), runtime_call_Relocation::spec(), Assembler::call32_operand); + TRACE_C1X_3("CiRuntimeCall::HandleException()"); + } else if (runtime_call == CiRuntimeCall::JavaTimeMillis()) { + call->set_destination((address)os::javaTimeMillis); + _instructions->relocate(call->instruction_address(), runtime_call_Relocation::spec(), Assembler::call32_operand); + TRACE_C1X_3("CiRuntimeCall::JavaTimeMillis()"); + } else if (runtime_call == CiRuntimeCall::JavaTimeNanos()) { + call->set_destination((address)os::javaTimeNanos); + _instructions->relocate(call->instruction_address(), runtime_call_Relocation::spec(), Assembler::call32_operand); + TRACE_C1X_3("CiRuntimeCall::JavaTimeNanos()"); + } else if (runtime_call == CiRuntimeCall::ArithmeticFrem()) { + call->set_destination(Runtime1::entry_for(Runtime1::c1x_arithmetic_frem_id)); + _instructions->relocate(call->instruction_address(), runtime_call_Relocation::spec(), Assembler::call32_operand); + TRACE_C1X_3("CiRuntimeCall::ArithmeticFrem()"); + } else if (runtime_call == CiRuntimeCall::ArithmeticDrem()) { + call->set_destination(Runtime1::entry_for(Runtime1::c1x_arithmetic_drem_id)); + _instructions->relocate(call->instruction_address(), runtime_call_Relocation::spec(), Assembler::call32_operand); + TRACE_C1X_3("CiRuntimeCall::ArithmeticDrem()"); + } else if (runtime_call == CiRuntimeCall::RegisterFinalizer()) { + call->set_destination(Runtime1::entry_for(Runtime1::register_finalizer_id)); + _instructions->relocate(call->instruction_address(), runtime_call_Relocation::spec(), Assembler::call32_operand); + } else if (runtime_call == CiRuntimeCall::Deoptimize()) { + call->set_destination(SharedRuntime::deopt_blob()->uncommon_trap()); + _instructions->relocate(call->instruction_address(), runtime_call_Relocation::spec(), Assembler::call32_operand); + } else { + runtime_call->print(); + fatal("runtime_call not implemented"); + } + } else if (global_stub != NULL) { + NativeInstruction* inst = nativeInstruction_at(_instructions->start() + pc_offset); + assert(java_lang_boxing_object::is_instance(global_stub, T_LONG), "global_stub needs to be of type Long"); + + if (inst->is_call()) { + nativeCall_at((address)inst)->set_destination(VmIds::getStub(global_stub)); + } else { + nativeJump_at((address)inst)->set_jump_destination(VmIds::getStub(global_stub)); + } + _instructions->relocate((address)inst, runtime_call_Relocation::spec(), Assembler::call32_operand); + TRACE_C1X_3("relocating (stub) at %016x", inst); + } else if (symbol != NULL) { + fatal("symbol"); + } else { // method != NULL + NativeCall* call = nativeCall_at(_instructions->start() + pc_offset); + assert(hotspot_method != NULL, "unexpected RiMethod"); + assert(debug_info != NULL, "debug info expected"); + + methodOop method = NULL; + if (hotspot_method->is_a(HotSpotMethodResolved::klass())) method = VmIds::get(HotSpotMethodResolved::vmId(hotspot_method)); + + assert(debug_info != NULL, "debug info expected"); + + TRACE_C1X_3("method call"); + switch (_next_call_type) { + case MARK_INVOKEVIRTUAL: + case MARK_INVOKEINTERFACE: { + assert(method == NULL || !method->is_static(), "cannot call static method with invokeinterface"); + + call->set_destination(SharedRuntime::get_resolve_virtual_call_stub()); + _instructions->relocate(call->instruction_address(), virtual_call_Relocation::spec(_invoke_mark_pc), Assembler::call32_operand); + break; + } + case MARK_INVOKESTATIC: { + assert(method == NULL || method->is_static(), "cannot call non-static method with invokestatic"); + call->set_destination(SharedRuntime::get_resolve_static_call_stub()); + _instructions->relocate(call->instruction_address(), relocInfo::static_call_type, Assembler::call32_operand); + break; + } + case MARK_INVOKESPECIAL: { + assert(method == NULL || !method->is_static(), "cannot call static method with invokespecial"); + + call->set_destination(SharedRuntime::get_resolve_opt_virtual_call_stub()); + _instructions->relocate(call->instruction_address(), relocInfo::opt_virtual_call_type, Assembler::call32_operand); + break; + } + case MARK_INVOKE_INVALID: + default: + fatal("invalid _next_call_type value"); + break; + } + } + _next_call_type = MARK_INVOKE_INVALID; + if (debug_info != NULL) { + _debug_recorder->end_safepoint(next_pc_offset); + } +} + +void CodeInstaller::site_DataPatch(CodeBuffer& buffer, jint pc_offset, oop site) { + oop constant = CiTargetMethod_DataPatch::constant(site); + oop kind = CiConstant::kind(constant); + + address instruction = _instructions->start() + pc_offset; + + switch (CiKind::typeChar(kind)) { + case 'z': + case 'b': + case 's': + case 'c': + case 'i': + fatal("int-sized values not expected in DataPatch") + ; + break; + case 'f': + case 'l': + case 'd': { + address operand = Assembler::locate_operand(instruction, Assembler::disp32_operand); + address next_instruction = Assembler::locate_next_instruction(instruction); + // we don't care if this is a long/double/etc., the primitive field contains the right bits + address dest = _constants->end(); + *(jlong*) dest = CiConstant::primitive(constant); + _constants->set_end(dest + BytesPerLong); + + long disp = dest - next_instruction; + assert(disp == (jint) disp, "disp doesn't fit in 32 bits"); + *((jint*) operand) = (jint) disp; + + _instructions->relocate(instruction, section_word_Relocation::spec((address) dest, CodeBuffer::SECT_CONSTS), Assembler::disp32_operand); + TRACE_C1X_3("relocating (Float/Long/Double) at %016x/%016x", instruction, operand); + break; + } + case 'a': { + address operand = Assembler::locate_operand(instruction, Assembler::imm_operand); + Handle obj = CiConstant::object(constant); + + if (obj->is_a(HotSpotTypeResolved::klass())) { + assert(!obj.is_null(), ""); + *((jobject*) operand) = JNIHandles::make_local(java_lang_Class::as_klassOop(HotSpotTypeResolved::javaMirror(obj))); + _instructions->relocate(instruction, oop_Relocation::spec_for_immediate(), Assembler::imm_operand); + TRACE_C1X_3("relocating (HotSpotType) at %016x/%016x", instruction, operand); + } else { + jobject value; + if (obj() == HotSpotProxy::DUMMY_CONSTANT_OBJ()) { + value = (jobject) Universe::non_oop_word(); + } else { + value = JNIHandles::make_local(obj()); + } + *((jobject*) operand) = value; + _instructions->relocate(instruction, oop_Relocation::spec_for_immediate(), Assembler::imm_operand); + TRACE_C1X_3("relocating (oop constant) at %016x/%016x", instruction, operand); + } + break; + } + default: + fatal("unexpected CiKind in DataPatch"); + break; + } +} + +void CodeInstaller::site_Mark(CodeBuffer& buffer, jint pc_offset, oop site) { + oop id_obj = CiTargetMethod_Mark::id(site); + arrayOop references = (arrayOop) CiTargetMethod_Mark::references(site); + + if (id_obj != NULL) { + assert(java_lang_boxing_object::is_instance(id_obj, T_INT), "Integer id expected"); + jint id = id_obj->int_field(java_lang_boxing_object::value_offset_in_bytes(T_INT)); + + address instruction = _instructions->start() + pc_offset; + + switch (id) { + case MARK_UNVERIFIED_ENTRY: + _offsets.set_value(CodeOffsets::Entry, pc_offset); + break; + case MARK_VERIFIED_ENTRY: + _offsets.set_value(CodeOffsets::Verified_Entry, pc_offset); + break; + case MARK_OSR_ENTRY: + _offsets.set_value(CodeOffsets::OSR_Entry, pc_offset); + break; + case MARK_UNWIND_ENTRY: + _offsets.set_value(CodeOffsets::UnwindHandler, pc_offset); + break; + case MARK_EXCEPTION_HANDLER_ENTRY: + _offsets.set_value(CodeOffsets::Exceptions, pc_offset); + break; + case MARK_DEOPT_HANDLER_ENTRY: + _offsets.set_value(CodeOffsets::Deopt, pc_offset); + break; + case MARK_STATIC_CALL_STUB: { + assert(references->length() == 1, "static call stub needs one reference"); + oop ref = ((oop*) references->base(T_OBJECT))[0]; + address call_pc = _instructions->start() + CiTargetMethod_Site::pcOffset(ref); + _instructions->relocate(instruction, static_stub_Relocation::spec(call_pc)); + _instructions->relocate(instruction, oop_Relocation::spec_for_immediate(), Assembler::imm_operand); + break; + } + case MARK_INVOKE_INVALID: + case MARK_INVOKEINTERFACE: + case MARK_INVOKESTATIC: + case MARK_INVOKESPECIAL: + case MARK_INVOKEVIRTUAL: + _next_call_type = (MarkId) id; + _invoke_mark_pc = instruction; + break; + case MARK_IMPLICIT_NULL: + _implicit_exception_table.append(pc_offset, pc_offset); + break; + case MARK_KLASS_PATCHING: + case MARK_ACCESS_FIELD_PATCHING: { + unsigned char* byte_count = (unsigned char*) (instruction - 1); + unsigned char* byte_skip = (unsigned char*) (instruction - 2); + unsigned char* being_initialized_entry_offset = (unsigned char*) (instruction - 3); + + assert(*byte_skip == 5, "unexpected byte_skip"); + + assert(references->length() == 2, "MARK_KLASS_PATCHING/MARK_ACCESS_FIELD_PATCHING needs 2 references"); + oop ref1 = ((oop*) references->base(T_OBJECT))[0]; + oop ref2 = ((oop*) references->base(T_OBJECT))[1]; + int i_byte_count = CiTargetMethod_Site::pcOffset(ref2) - CiTargetMethod_Site::pcOffset(ref1); + assert(i_byte_count == (unsigned char)i_byte_count, "invalid offset"); + *byte_count = i_byte_count; + *being_initialized_entry_offset = *byte_count + *byte_skip; + + // we need to correct the offset of a field access - it's created with MAX_INT to ensure the correct size, and hotspot expects 0 + if (id == MARK_ACCESS_FIELD_PATCHING) { + NativeMovRegMem* inst = nativeMovRegMem_at(_instructions->start() + CiTargetMethod_Site::pcOffset(ref1)); + assert(inst->offset() == max_jint, "unexpected offset value"); + inst->set_offset(0); + } + break; + } + case MARK_DUMMY_OOP_RELOCATION: { + _instructions->relocate(instruction, oop_Relocation::spec_for_immediate(), Assembler::imm_operand); + + RelocIterator iter(_instructions, (address) instruction, (address) (instruction + 1)); + relocInfo::change_reloc_info_for_address(&iter, (address) instruction, relocInfo::oop_type, relocInfo::none); + break; + } + default: + ShouldNotReachHere(); + break; + } + } +} + diff -r 102466e70deb -r 91fe28b03d6a src/share/vm/c1x/c1x_CodeInstaller.hpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/vm/c1x/c1x_CodeInstaller.hpp Wed Jan 26 18:17:37 2011 +0100 @@ -0,0 +1,107 @@ +/* + * Copyright 2000-2010 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +/* + * This class handles the conversion from a CiTargetMethod to a CodeBlob or an nmethod. + */ +class CodeInstaller { +private: + // these need to correspond to HotSpotXirGenerator.java + enum MarkId { + MARK_VERIFIED_ENTRY = 0x0001, + MARK_UNVERIFIED_ENTRY = 0x0002, + MARK_OSR_ENTRY = 0x0003, + MARK_UNWIND_ENTRY = 0x0004, + MARK_EXCEPTION_HANDLER_ENTRY = 0x0005, + MARK_DEOPT_HANDLER_ENTRY = 0x0006, + MARK_STATIC_CALL_STUB = 0x1000, + MARK_INVOKE_INVALID = 0x2000, + MARK_INVOKEINTERFACE = 0x2001, + MARK_INVOKESTATIC = 0x2002, + MARK_INVOKESPECIAL = 0x2003, + MARK_INVOKEVIRTUAL = 0x2004, + MARK_IMPLICIT_NULL = 0x3000, + MARK_KLASS_PATCHING = 0x4000, + MARK_DUMMY_OOP_RELOCATION = 0x4001, + MARK_ACCESS_FIELD_PATCHING = 0x4002 + }; + + ciEnv* _env; + + oop _citarget_method; + oop _hotspot_method; + oop _name; + arrayOop _sites; + arrayOop _assumptions; + arrayOop _exception_handlers; + CodeOffsets _offsets; + + arrayOop _code; + jint _code_size; + jint _frame_size; + jint _custom_stack_area_offset; + jint _parameter_count; + jint _constants_size; + jint _total_size; + + MarkId _next_call_type; + address _invoke_mark_pc; + + CodeSection* _instructions; + CodeSection* _constants; + + OopRecorder* _oop_recorder; + DebugInformationRecorder* _debug_recorder; + Dependencies* _dependencies; + ExceptionHandlerTable _exception_handler_table; + ImplicitExceptionTable _implicit_exception_table; + +public: + + // constructor used to create a method + CodeInstaller(Handle target_method); + + // constructor used to create a stub + CodeInstaller(Handle target_method, jlong& id); + +private: + // extract the fields of the CiTargetMethod + void initialize_fields(Handle target_method); + + // perform data and call relocation on the CodeBuffer + void initialize_buffer(CodeBuffer& buffer); + + void assumption_ConcreteSubtype(oop assumption); + void assumption_ConcreteMethod(oop assumption); + + void site_Safepoint(CodeBuffer& buffer, jint pc_offset, oop site); + void site_Call(CodeBuffer& buffer, jint pc_offset, oop site); + void site_DataPatch(CodeBuffer& buffer, jint pc_offset, oop site); + void site_Mark(CodeBuffer& buffer, jint pc_offset, oop site); + + void record_scope(jint pc_offset, oop code_pos); + + void process_exception_handlers(); + +}; diff -r 102466e70deb -r 91fe28b03d6a src/share/vm/c1x/c1x_Compiler.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/vm/c1x/c1x_Compiler.cpp Wed Jan 26 18:17:37 2011 +0100 @@ -0,0 +1,202 @@ +/* + * Copyright 2000-2010 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +#include "precompiled.hpp" +#include "c1x/c1x_Compiler.hpp" +#include "c1x/c1x_JavaAccess.hpp" +#include "c1x/c1x_VMExits.hpp" +#include "c1x/c1x_VMEntries.hpp" +#include "c1x/c1x_VmIds.hpp" +#include "c1/c1_Runtime1.hpp" + +C1XCompiler* C1XCompiler::_instance = NULL; + +C1XCompiler::C1XCompiler() { + _initialized = false; + assert(_instance == NULL, "only one instance allowed"); + _instance = this; +} + +// Initialization +void C1XCompiler::initialize() { + if (_initialized) return; + CompilerThread* THREAD = CompilerThread::current(); + _initialized = true; + TRACE_C1X_1("C1XCompiler::initialize"); + + initialize_buffer_blob(); + Runtime1::initialize(THREAD->get_buffer_blob()); + + JNIEnv *env = ((JavaThread *) Thread::current())->jni_environment(); + jclass klass = env->FindClass("com/sun/hotspot/c1x/VMEntriesNative"); + if (klass == NULL) { + fatal("c1x VMEntries class not found"); + } + env->RegisterNatives(klass, VMEntries_methods, VMEntries_methods_count()); + + { + VM_ENTRY_MARK; + check_pending_exception("Could not register natives"); + } + + c1x_compute_offsets(); + + { + VM_ENTRY_MARK; + HandleMark hm; + for (int i = 0; i < Arguments::num_c1x_args(); ++i) { + const char* arg = Arguments::c1x_args_array()[i]; + Handle option = java_lang_String::create_from_str(arg, THREAD); + bool result = VMExits::setOption(option); + if (!result) fatal("Invalid option for C1X!"); + } + } +} + +void C1XCompiler::initialize_buffer_blob() { + + CompilerThread* THREAD = CompilerThread::current(); + if (THREAD->get_buffer_blob() == NULL) { + // setup CodeBuffer. Preallocate a BufferBlob of size + // NMethodSizeLimit plus some extra space for constants. + int code_buffer_size = Compilation::desired_max_code_buffer_size() + + Compilation::desired_max_constant_size(); + BufferBlob* blob = BufferBlob::create("C1X temporary CodeBuffer", + code_buffer_size); + guarantee(blob != NULL, "must create code buffer"); + THREAD->set_buffer_blob(blob); + } +} + +// Compilation entry point for methods +void C1XCompiler::compile_method(ciEnv* env, ciMethod* target, int entry_bci) { + initialize(); + VM_ENTRY_MARK; + ResourceMark rm; + HandleMark hm; + + initialize_buffer_blob(); + VmIds::initializeObjects(); + + CompilerThread::current()->set_compiling(true); + methodOop method = (methodOop) target->get_oop(); + VMExits::compileMethod(VmIds::add(method), VmIds::toString(method->name(), THREAD), entry_bci); + CompilerThread::current()->set_compiling(false); + + VmIds::cleanupLocalObjects(); +} + +// Print compilation timers and statistics +void C1XCompiler::print_timers() { + TRACE_C1X_1("C1XCompiler::print_timers"); +} + +oop C1XCompiler::get_RiType(ciType *type, KlassHandle accessor, TRAPS) { + if (type->is_loaded()) { + if (type->is_primitive_type()) { + return VMExits::createRiTypePrimitive((int) type->basic_type(), THREAD); + } + KlassHandle klass = (klassOop) type->get_oop(); + Handle name = VmIds::toString(klass->name(), THREAD); + return createHotSpotTypeResolved(klass, name, CHECK_NULL); + } else { + symbolOop name = ((ciKlass *) type)->name()->get_symbolOop(); + return VMExits::createRiTypeUnresolved(VmIds::toString(name, THREAD), THREAD); + } +} + +oop C1XCompiler::get_RiField(ciField *field, ciInstanceKlass* accessor_klass, KlassHandle accessor, Bytecodes::Code byteCode, TRAPS) { + bool will_link = field->will_link_from_vm(accessor_klass, byteCode); + int offset = (field->holder()->is_loaded() && will_link) ? field->offset() : -1; + Handle field_name = VmIds::toString(field->name()->get_symbolOop(), CHECK_0); + Handle field_holder = get_RiType(field->holder(), accessor, CHECK_0); + Handle field_type = get_RiType(field->type(), accessor, CHECK_0); + + // TODO: implement caching + return VMExits::createRiField(field_holder, field_name, field_type, offset, THREAD); +} + +oop C1XCompiler::createHotSpotTypeResolved(KlassHandle klass, Handle name, TRAPS) { + if (klass->c1x_mirror() != NULL) { + return klass->c1x_mirror(); + } + + instanceKlass::cast(HotSpotTypeResolved::klass())->initialize(CHECK_NULL); + Handle obj = instanceKlass::cast(HotSpotTypeResolved::klass())->allocate_instance(CHECK_NULL); + assert(obj() != NULL, "must succeed in allocating instance"); + + + if (klass->oop_is_instance()) { + instanceKlass* ik = (instanceKlass*)klass()->klass_part(); + Handle full_name = java_lang_String::create_from_str(ik->signature_name(), CHECK_NULL); + HotSpotType::set_name(obj, full_name()); + } else { + HotSpotType::set_name(obj, name()); + } + + HotSpotTypeResolved::set_javaMirror(obj, klass->java_mirror()); + HotSpotTypeResolved::set_simpleName(obj, name()); + HotSpotTypeResolved::set_accessFlags(obj, klass->access_flags().as_int()); + HotSpotTypeResolved::set_isInterface(obj, klass->is_interface()); + HotSpotTypeResolved::set_isInstanceClass(obj, klass->oop_is_instance()); + + if (klass->oop_is_javaArray()) { + HotSpotTypeResolved::set_isArrayClass(obj, true); + HotSpotTypeResolved::set_componentType(obj, NULL); + } else { + HotSpotTypeResolved::set_isArrayClass(obj, false); + HotSpotTypeResolved::set_componentType(obj, NULL); + HotSpotTypeResolved::set_isInitialized(obj, instanceKlass::cast(klass())->is_initialized()); + HotSpotTypeResolved::set_instanceSize(obj, instanceKlass::cast(klass())->size_helper() * HeapWordSize); + HotSpotTypeResolved::set_hasFinalizer(obj, klass->has_finalizer()); + } + + // TODO replace these with correct values + HotSpotTypeResolved::set_hasSubclass(obj, false); + HotSpotTypeResolved::set_hasFinalizableSubclass(obj, false); + + klass->set_c1x_mirror(obj()); + + return obj(); +} + +BasicType C1XCompiler::kindToBasicType(jchar ch) { + switch(ch) { + case 'z': return T_BOOLEAN; + case 'b': return T_BYTE; + case 's': return T_SHORT; + case 'c': return T_CHAR; + case 'i': return T_INT; + case 'f': return T_FLOAT; + case 'l': return T_LONG; + case 'd': return T_DOUBLE; + case 'a': return T_OBJECT; + case 'r': return T_ADDRESS; + case '-': return T_ILLEGAL; + default: + fatal(err_msg("unexpected CiKind: %c", ch)); + break; + } +} + diff -r 102466e70deb -r 91fe28b03d6a src/share/vm/c1x/c1x_Compiler.hpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/vm/c1x/c1x_Compiler.hpp Wed Jan 26 18:17:37 2011 +0100 @@ -0,0 +1,98 @@ +/* + * Copyright 2000-2010 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +#include "compiler/abstractCompiler.hpp" + +class C1XCompiler : public AbstractCompiler { + +private: + + bool _initialized; + + static C1XCompiler* _instance; + +public: + + C1XCompiler(); + + static C1XCompiler* instance() { return _instance; } + + + virtual const char* name() { return "C1X"; } + + // Native / OSR not supported + virtual bool supports_native() { return false; } + virtual bool supports_osr () { return false; } + + // Pretend to be C1 + bool is_c1 () { return true; } + bool is_c2 () { return false; } + + // Initialization + virtual void initialize(); + + // Compilation entry point for methods + virtual void compile_method(ciEnv* env, ciMethod* target, int entry_bci); + + // Print compilation timers and statistics + virtual void print_timers(); + + static oop get_RiType(ciType *klass, KlassHandle accessor, TRAPS); + static oop get_RiField(ciField *ciField, ciInstanceKlass* accessor_klass, KlassHandle accessor, Bytecodes::Code byteCode, TRAPS); + + static oop createHotSpotTypeResolved(KlassHandle klass, Handle name, TRAPS); + + static BasicType kindToBasicType(jchar ch); + + static int to_cp_index_u2(int index) { + // Swap. + index = ((index & 0xFF) << 8) | (index >> 8); + // Tag. + index = index + constantPoolOopDesc::CPCACHE_INDEX_TAG; + return index; + } + +private: + + void initialize_buffer_blob(); +}; + +// Tracing macros + +#define IF_TRACE_C1X_1 if (!(TraceC1X >= 1)) ; else +#define IF_TRACE_C1X_2 if (!(TraceC1X >= 2)) ; else +#define IF_TRACE_C1X_3 if (!(TraceC1X >= 3)) ; else +#define IF_TRACE_C1X_4 if (!(TraceC1X >= 4)) ; else +#define IF_TRACE_C1X_5 if (!(TraceC1X >= 5)) ; else + +// using commas and else to keep one-instruction semantics + +#define TRACE_C1X_1 if (!(TraceC1X >= 1 && (tty->print("TraceC1X-1: "), true))) ; else tty->print_cr +#define TRACE_C1X_2 if (!(TraceC1X >= 2 && (tty->print(" TraceC1X-2: "), true))) ; else tty->print_cr +#define TRACE_C1X_3 if (!(TraceC1X >= 3 && (tty->print(" TraceC1X-3: "), true))) ; else tty->print_cr +#define TRACE_C1X_4 if (!(TraceC1X >= 4 && (tty->print(" TraceC1X-4: "), true))) ; else tty->print_cr +#define TRACE_C1X_5 if (!(TraceC1X >= 5 && (tty->print(" TraceC1X-5: "), true))) ; else tty->print_cr + + + diff -r 102466e70deb -r 91fe28b03d6a src/share/vm/c1x/c1x_JavaAccess.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/vm/c1x/c1x_JavaAccess.cpp Wed Jan 26 18:17:37 2011 +0100 @@ -0,0 +1,83 @@ +/* + * Copyright 2000-2010 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +#include "precompiled.hpp" +#include "c1x/c1x_JavaAccess.hpp" + +// This function is similar to javaClasses.cpp, it computes the field offset of a (static or instance) field. +// It looks up the name and signature symbols without creating new ones, all the symbols of these classes need to be already loaded. + +static void compute_offset(int &dest_offset, klassOop klass_oop, const char* name, const char* signature, bool static_field) { + symbolOop name_symbol = SymbolTable::probe(name, strlen(name)); + symbolOop signature_symbol = SymbolTable::probe(signature, strlen(signature)); +#ifdef DEBUG + if (name_symbol == NULL) { + tty->print_cr("symbol with name %s was not found in symbol table (klass=%s)", name, klass_oop->klass_part()->name()->as_C_string()); + } +#endif + assert(name_symbol != NULL, "symbol not found - class layout changed?"); + assert(signature_symbol != NULL, "symbol not found - class layout changed?"); + + instanceKlass* ik = instanceKlass::cast(klass_oop); + fieldDescriptor fd; + if (!ik->find_field(name_symbol, signature_symbol, &fd)) { + ResourceMark rm; + tty->print_cr("Invalid layout of %s at %s", name_symbol->as_C_string(), ik->external_name()); + fatal("Invalid layout of preloaded class"); + } + assert(fd.is_static() == static_field, "static/instance mismatch"); + dest_offset = fd.offset(); +} + +// This piece of macro magic creates the contents of the c1x_compute_offsets method that initializes the field indices of all the access classes. + +#define START_CLASS(name) { klassOop k = SystemDictionary::name##_klass(); + +#define END_CLASS } + +#define FIELD(klass, name, signature, static_field) compute_offset(klass::_##name##_offset, k, #name, signature, static_field); +#define CHAR_FIELD(klass, name) FIELD(klass, name, "C", false) +#define INT_FIELD(klass, name) FIELD(klass, name, "I", false) +#define BOOLEAN_FIELD(klass, name) FIELD(klass, name, "Z", false) +#define LONG_FIELD(klass, name) FIELD(klass, name, "J", false) +#define OOP_FIELD(klass, name, signature) FIELD(klass, name, signature, false) +#define STATIC_OOP_FIELD(klass, name, signature) FIELD(klass, name, signature, true) + + +void c1x_compute_offsets() { + COMPILER_CLASSES_DO(START_CLASS, END_CLASS, CHAR_FIELD, INT_FIELD, BOOLEAN_FIELD, LONG_FIELD, OOP_FIELD, STATIC_OOP_FIELD) +} + +#define EMPTY0 +#define EMPTY1(x) +#define EMPTY2(x,y) +#define FIELD2(klass, name) int klass::_##name##_offset = 0; +#define FIELD3(klass, name, sig) FIELD2(klass, name) + +COMPILER_CLASSES_DO(EMPTY1, EMPTY0, FIELD2, FIELD2, FIELD2, FIELD2, FIELD3, FIELD3) + + + + + diff -r 102466e70deb -r 91fe28b03d6a src/share/vm/c1x/c1x_JavaAccess.hpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/vm/c1x/c1x_JavaAccess.hpp Wed Jan 26 18:17:37 2011 +0100 @@ -0,0 +1,246 @@ +/* + * Copyright 2000-2010 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +void c1x_compute_offsets(); + +/* This macro defines the structure of the CiTargetMethod - classes. + * It will generate classes with accessors similar to javaClasses.hpp, but with specializations for oops, Handles and jni handles. + * + * The public interface of these classes will look like this: + + * class CiStackSlot : AllStatic { + * public: + * static klassOop klass(); + * static jint index(oop obj); + * static jint index(Handle obj); + * static jint index(jobject obj); + * static void set_index(oop obj, jint x); + * static void set_index(Handle obj, jint x); + * static void set_index(jobject obj, jint x); + * }; + * + */ + +#define COMPILER_CLASSES_DO(start_class, end_class, char_field, int_field, boolean_field, long_field, oop_field, static_oop_field) \ + start_class(HotSpotTypeResolved) \ + oop_field(HotSpotTypeResolved, javaMirror, "Ljava/lang/Class;") \ + oop_field(HotSpotTypeResolved, simpleName, "Ljava/lang/String;") \ + int_field(HotSpotTypeResolved, accessFlags) \ + boolean_field(HotSpotTypeResolved, hasFinalizer) \ + boolean_field(HotSpotTypeResolved, hasSubclass) \ + boolean_field(HotSpotTypeResolved, hasFinalizableSubclass) \ + boolean_field(HotSpotTypeResolved, isInitialized) \ + boolean_field(HotSpotTypeResolved, isArrayClass) \ + boolean_field(HotSpotTypeResolved, isInstanceClass) \ + boolean_field(HotSpotTypeResolved, isInterface) \ + int_field(HotSpotTypeResolved, instanceSize) \ + oop_field(HotSpotTypeResolved, componentType, "Lcom/sun/cri/ri/RiType;") \ + end_class \ + start_class(HotSpotType) \ + oop_field(HotSpotType, name, "Ljava/lang/String;") \ + end_class \ + start_class(HotSpotField) \ + oop_field(HotSpotField, constant, "Lcom/sun/cri/ci/CiConstant;") \ + end_class \ + start_class(HotSpotMethodResolved) \ + long_field(HotSpotMethodResolved, vmId) \ + end_class \ + start_class(HotSpotProxy) \ + static_oop_field(HotSpotProxy, DUMMY_CONSTANT_OBJ, "Ljava/lang/Long;") \ + end_class \ + start_class(HotSpotTargetMethod) \ + oop_field(HotSpotTargetMethod, targetMethod, "Lcom/sun/cri/ci/CiTargetMethod;") \ + oop_field(HotSpotTargetMethod, method, "Lcom/sun/hotspot/c1x/HotSpotMethodResolved;")\ + oop_field(HotSpotTargetMethod, name, "Ljava/lang/String;") \ + oop_field(HotSpotTargetMethod, sites, "[Lcom/sun/cri/ci/CiTargetMethod$Site;") \ + oop_field(HotSpotTargetMethod, exceptionHandlers, "[Lcom/sun/cri/ci/CiTargetMethod$ExceptionHandler;") \ + end_class \ + start_class(HotSpotExceptionHandler) \ + int_field(HotSpotExceptionHandler, startBci) \ + int_field(HotSpotExceptionHandler, endBci) \ + int_field(HotSpotExceptionHandler, handlerBci) \ + int_field(HotSpotExceptionHandler, catchClassIndex) \ + oop_field(HotSpotExceptionHandler, catchClass, "Lcom/sun/cri/ri/RiType;") \ + end_class \ + start_class(CiTargetMethod) \ + int_field(CiTargetMethod, frameSize) \ + int_field(CiTargetMethod, customStackAreaOffset) \ + oop_field(CiTargetMethod, targetCode, "[B") \ + oop_field(CiTargetMethod, assumptions, "Lcom/sun/cri/ci/CiAssumptions;") \ + int_field(CiTargetMethod, targetCodeSize) \ + end_class \ + start_class(CiAssumptions) \ + oop_field(CiAssumptions, list, "[Lcom/sun/cri/ci/CiAssumptions$Assumption;") \ + end_class \ + start_class(CiAssumptions_ConcreteSubtype) \ + oop_field(CiAssumptions_ConcreteSubtype, context, "Lcom/sun/cri/ri/RiType;") \ + oop_field(CiAssumptions_ConcreteSubtype, subtype, "Lcom/sun/cri/ri/RiType;") \ + end_class \ + start_class(CiAssumptions_ConcreteMethod) \ + oop_field(CiAssumptions_ConcreteMethod, context, "Lcom/sun/cri/ri/RiMethod;") \ + oop_field(CiAssumptions_ConcreteMethod, method, "Lcom/sun/cri/ri/RiMethod;") \ + end_class \ + start_class(CiTargetMethod_Site) \ + int_field(CiTargetMethod_Site, pcOffset) \ + end_class \ + start_class(CiTargetMethod_Call) \ + oop_field(CiTargetMethod_Call, runtimeCall, "Lcom/sun/cri/ci/CiRuntimeCall;") \ + oop_field(CiTargetMethod_Call, method, "Lcom/sun/cri/ri/RiMethod;") \ + oop_field(CiTargetMethod_Call, symbol, "Ljava/lang/String;") \ + oop_field(CiTargetMethod_Call, globalStubID, "Ljava/lang/Object;") \ + oop_field(CiTargetMethod_Call, debugInfo, "Lcom/sun/cri/ci/CiDebugInfo;") \ + end_class \ + start_class(CiTargetMethod_DataPatch) \ + oop_field(CiTargetMethod_DataPatch, constant, "Lcom/sun/cri/ci/CiConstant;") \ + end_class \ + start_class(CiTargetMethod_Safepoint) \ + oop_field(CiTargetMethod_Safepoint, debugInfo, "Lcom/sun/cri/ci/CiDebugInfo;") \ + end_class \ + start_class(CiTargetMethod_ExceptionHandler) \ + int_field(CiTargetMethod_ExceptionHandler, handlerPos) \ + int_field(CiTargetMethod_ExceptionHandler, handlerBci) \ + int_field(CiTargetMethod_ExceptionHandler, bci) \ + int_field(CiTargetMethod_ExceptionHandler, scopeLevel) \ + oop_field(CiTargetMethod_ExceptionHandler, exceptionType, "Lcom/sun/cri/ri/RiType;")\ + end_class \ + start_class(CiTargetMethod_Mark) \ + oop_field(CiTargetMethod_Mark, id, "Ljava/lang/Object;") \ + oop_field(CiTargetMethod_Mark, references, "[Lcom/sun/cri/ci/CiTargetMethod$Mark;") \ + end_class \ + start_class(CiDebugInfo) \ + oop_field(CiDebugInfo, codePos, "Lcom/sun/cri/ci/CiCodePos;") \ + oop_field(CiDebugInfo, registerRefMap, "Lcom/sun/cri/ci/CiBitMap;") \ + oop_field(CiDebugInfo, frameRefMap, "Lcom/sun/cri/ci/CiBitMap;") \ + end_class \ + start_class(CiBitMap) \ + int_field(CiBitMap, size) \ + long_field(CiBitMap, low) \ + oop_field(CiBitMap, extra, "[J") \ + end_class \ + start_class(CiDebugInfo_Frame) \ + oop_field(CiDebugInfo_Frame, values, "[Lcom/sun/cri/ci/CiValue;") \ + int_field(CiDebugInfo_Frame, numLocals) \ + int_field(CiDebugInfo_Frame, numStack) \ + int_field(CiDebugInfo_Frame, numLocks) \ + end_class \ + start_class(CiCodePos) \ + oop_field(CiCodePos, caller, "Lcom/sun/cri/ci/CiCodePos;") \ + oop_field(CiCodePos, method, "Lcom/sun/cri/ri/RiMethod;") \ + int_field(CiCodePos, bci) \ + end_class \ + start_class(CiConstant) \ + oop_field(CiConstant, kind, "Lcom/sun/cri/ci/CiKind;") \ + oop_field(CiConstant, object, "Ljava/lang/Object;") \ + long_field(CiConstant, primitive) \ + end_class \ + start_class(CiKind) \ + char_field(CiKind, typeChar) \ + static_oop_field(CiKind, Boolean, "Lcom/sun/cri/ci/CiKind;"); \ + static_oop_field(CiKind, Byte, "Lcom/sun/cri/ci/CiKind;"); \ + static_oop_field(CiKind, Char, "Lcom/sun/cri/ci/CiKind;"); \ + static_oop_field(CiKind, Short, "Lcom/sun/cri/ci/CiKind;"); \ + static_oop_field(CiKind, Int, "Lcom/sun/cri/ci/CiKind;"); \ + static_oop_field(CiKind, Long, "Lcom/sun/cri/ci/CiKind;"); \ + end_class \ + start_class(CiRuntimeCall) \ + static_oop_field(CiRuntimeCall, UnwindException, "Lcom/sun/cri/ci/CiRuntimeCall;"); \ + static_oop_field(CiRuntimeCall, RegisterFinalizer, "Lcom/sun/cri/ci/CiRuntimeCall;"); \ + static_oop_field(CiRuntimeCall, HandleException, "Lcom/sun/cri/ci/CiRuntimeCall;"); \ + static_oop_field(CiRuntimeCall, OSRMigrationEnd, "Lcom/sun/cri/ci/CiRuntimeCall;"); \ + static_oop_field(CiRuntimeCall, JavaTimeMillis, "Lcom/sun/cri/ci/CiRuntimeCall;"); \ + static_oop_field(CiRuntimeCall, JavaTimeNanos, "Lcom/sun/cri/ci/CiRuntimeCall;"); \ + static_oop_field(CiRuntimeCall, Debug, "Lcom/sun/cri/ci/CiRuntimeCall;"); \ + static_oop_field(CiRuntimeCall, ArithmethicLrem, "Lcom/sun/cri/ci/CiRuntimeCall;"); \ + static_oop_field(CiRuntimeCall, ArithmeticLdiv, "Lcom/sun/cri/ci/CiRuntimeCall;"); \ + static_oop_field(CiRuntimeCall, ArithmeticFrem, "Lcom/sun/cri/ci/CiRuntimeCall;"); \ + static_oop_field(CiRuntimeCall, ArithmeticDrem, "Lcom/sun/cri/ci/CiRuntimeCall;"); \ + static_oop_field(CiRuntimeCall, ArithmeticCos, "Lcom/sun/cri/ci/CiRuntimeCall;"); \ + static_oop_field(CiRuntimeCall, ArithmeticTan, "Lcom/sun/cri/ci/CiRuntimeCall;"); \ + static_oop_field(CiRuntimeCall, ArithmeticLog, "Lcom/sun/cri/ci/CiRuntimeCall;"); \ + static_oop_field(CiRuntimeCall, ArithmeticLog10, "Lcom/sun/cri/ci/CiRuntimeCall;"); \ + static_oop_field(CiRuntimeCall, ArithmeticSin, "Lcom/sun/cri/ci/CiRuntimeCall;"); \ + static_oop_field(CiRuntimeCall, Deoptimize, "Lcom/sun/cri/ci/CiRuntimeCall;"); \ + end_class \ + start_class(RiMethod) \ + end_class \ + start_class(CiValue) \ + oop_field(CiValue, kind, "Lcom/sun/cri/ci/CiKind;") \ + static_oop_field(CiValue, IllegalValue, "Lcom/sun/cri/ci/CiValue;"); \ + end_class \ + start_class(CiRegisterValue) \ + oop_field(CiRegisterValue, reg, "Lcom/sun/cri/ci/CiRegister;") \ + end_class \ + start_class(CiRegister) \ + int_field(CiRegister, number) \ + end_class \ + start_class(CiStackSlot) \ + int_field(CiStackSlot, index) \ + end_class \ + /* end*/ + + + + +#define START_CLASS(name) \ + class name : AllStatic { \ + private: \ + friend class C1XCompiler; \ + static void check(oop obj) { assert(obj != NULL, "NULL field access of class " #name); assert(obj->is_a(SystemDictionary::name##_klass()), "wrong class, " #name " expected"); } \ + static void compute_offsets(); \ + public: \ + static klassOop klass() { return SystemDictionary::name##_klass(); } + +#define END_CLASS }; + +#define FIELD(name, type, accessor) \ + static int _##name##_offset; \ + static type name(oop obj) { check(obj); return obj->accessor(_##name##_offset); } \ + static type name(Handle obj) { check(obj()); return obj->accessor(_##name##_offset); } \ + static type name(jobject obj) { check(JNIHandles::resolve(obj)); return JNIHandles::resolve(obj)->accessor(_##name##_offset); } \ + static void set_##name(oop obj, type x) { check(obj); obj->accessor##_put(_##name##_offset, x); } \ + static void set_##name(Handle obj, type x) { check(obj()); obj->accessor##_put(_##name##_offset, x); } \ + static void set_##name(jobject obj, type x) { check(JNIHandles::resolve(obj)); JNIHandles::resolve(obj)->accessor##_put(_##name##_offset, x); } + +#define CHAR_FIELD(klass, name) FIELD(name, jchar, char_field) +#define INT_FIELD(klass, name) FIELD(name, jint, int_field) +#define BOOLEAN_FIELD(klass, name) FIELD(name, jboolean, bool_field) +#define LONG_FIELD(klass, name) FIELD(name, jlong, long_field) +#define OOP_FIELD(klass, name, signature) FIELD(name, oop, obj_field) +#define STATIC_OOP_FIELD(klassName, name, signature) \ + static int _##name##_offset; \ + static oop name() { return klassName::klass()->obj_field(_##name##_offset); } \ + static void set_##name(oop x) { klassName::klass()->obj_field_put(_##name##_offset, x); } + +COMPILER_CLASSES_DO(START_CLASS, END_CLASS, CHAR_FIELD, INT_FIELD, BOOLEAN_FIELD, LONG_FIELD, OOP_FIELD, STATIC_OOP_FIELD) +#undef START_CLASS +#undef END_CLASS +#undef FIELD +#undef CHAR_FIELD +#undef INT_FIELD +#undef BOOLEAN_FIELD +#undef LONG_FIELD +#undef OOP_FIELD +#undef STATIC_OOP_FIELD + + diff -r 102466e70deb -r 91fe28b03d6a src/share/vm/c1x/c1x_VMEntries.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/vm/c1x/c1x_VMEntries.cpp Wed Jan 26 18:17:37 2011 +0100 @@ -0,0 +1,668 @@ +/* + * Copyright 2000-2010 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +#include "precompiled.hpp" +#include "c1x/c1x_VMEntries.hpp" +#include "c1x/c1x_Compiler.hpp" +#include "c1x/c1x_JavaAccess.hpp" +#include "c1x/c1x_CodeInstaller.hpp" +#include "c1x/c1x_VMExits.hpp" +#include "c1x/c1x_VmIds.hpp" +#include "c1/c1_Runtime1.hpp" + +// public byte[] RiMethod_code(long vmId); +JNIEXPORT jbyteArray JNICALL Java_com_sun_hotspot_c1x_VMEntries_RiMethod_1code(JNIEnv *env, jobject, jlong vmId) { + methodHandle method = VmIds::get(vmId); + int code_size = method->code_size(); + jbyteArray result = env->NewByteArray(code_size); + env->SetByteArrayRegion(result, 0, code_size, (const jbyte *) method->code_base()); + return result; +} + +// public int RiMethod_maxStackSize(long vmId); +JNIEXPORT jint JNICALL Java_com_sun_hotspot_c1x_VMEntries_RiMethod_1maxStackSize(JNIEnv *, jobject, jlong vmId) { + return VmIds::get(vmId)->max_stack(); +} + +// public int RiMethod_maxLocals(long vmId); +JNIEXPORT jint JNICALL Java_com_sun_hotspot_c1x_VMEntries_RiMethod_1maxLocals(JNIEnv *, jobject, jlong vmId) { + return VmIds::get(vmId)->max_locals(); +} + +// public RiType RiMethod_holder(long vmId); +JNIEXPORT jobject JNICALL Java_com_sun_hotspot_c1x_VMEntries_RiMethod_1holder(JNIEnv *, jobject, jlong vmId) { + VM_ENTRY_MARK + KlassHandle klass = VmIds::get(vmId)->method_holder(); + Handle name = VmIds::toString(klass->name(), CHECK_NULL); + oop holder = C1XCompiler::createHotSpotTypeResolved(klass, name, CHECK_NULL); + return JNIHandles::make_local(THREAD, holder); +} + +// public String RiMethod_signature(long vmId); +JNIEXPORT jstring JNICALL Java_com_sun_hotspot_c1x_VMEntries_RiMethod_1signature(JNIEnv *env, jobject, jlong vmId) { + VM_ENTRY_MARK + methodOop method = VmIds::get(vmId); + method->constMethod()->exception_table(); + return VmIds::toString(method->signature(), THREAD); +} + +// public int RiMethod_accessFlags(long vmId); +JNIEXPORT jint JNICALL Java_com_sun_hotspot_c1x_VMEntries_RiMethod_1accessFlags(JNIEnv *, jobject, jlong vmId) { + return VmIds::get(vmId)->access_flags().as_int(); +} + +// public RiExceptionHandler[] RiMethod_exceptionHandlers(long vmId); +JNIEXPORT jobjectArray JNICALL Java_com_sun_hotspot_c1x_VMEntries_RiMethod_1exceptionHandlers(JNIEnv *, jobject, jlong vmId) { + VM_ENTRY_MARK + methodHandle method = VmIds::get(vmId); + typeArrayHandle handlers = method->exception_table(); + int handler_count = handlers.is_null() ? 0 : handlers->length() / 4; + + instanceKlass::cast(HotSpotExceptionHandler::klass())->initialize(CHECK_NULL); + objArrayHandle array = oopFactory::new_objArray(SystemDictionary::RiExceptionHandler_klass(), handler_count, CHECK_NULL); + + for (int i = 0; i < handler_count; i++) { + // exception handlers are stored as four integers: start bci, end bci, handler bci, catch class constant pool index + int base = i * 4; + Handle entry = instanceKlass::cast(HotSpotExceptionHandler::klass())->allocate_instance(CHECK_NULL); + HotSpotExceptionHandler::set_startBci(entry, handlers->int_at(base + 0)); + HotSpotExceptionHandler::set_endBci(entry, handlers->int_at(base + 1)); + HotSpotExceptionHandler::set_handlerBci(entry, handlers->int_at(base + 2)); + int catch_class_index = handlers->int_at(base + 3); + HotSpotExceptionHandler::set_catchClassIndex(entry, catch_class_index); + + if (catch_class_index == 0) { + HotSpotExceptionHandler::set_catchClass(entry, NULL); + } else { + constantPoolOop cp = instanceKlass::cast(method->method_holder())->constants(); + ciInstanceKlass* loading_klass = (ciInstanceKlass *) CURRENT_ENV->get_object(method->method_holder()); + bool is_accessible = false; + ciKlass *klass = CURRENT_ENV->get_klass_by_index(cp, catch_class_index, is_accessible, loading_klass); + oop catch_class = C1XCompiler::get_RiType(klass, method->method_holder(), CHECK_NULL); + + HotSpotExceptionHandler::set_catchClass(entry, catch_class); + } + array->obj_at_put(i, entry()); + } + + return (jobjectArray) JNIHandles::make_local(array()); +} + +// public boolean RiMethod_hasBalancedMonitors(long vmId); +JNIEXPORT jint JNICALL Java_com_sun_hotspot_c1x_VMEntries_RiMethod_1hasBalancedMonitors(JNIEnv *, jobject, jlong vmId) { + ciMethod* cimethod; + { + VM_ENTRY_MARK; + cimethod = (ciMethod*)CURRENT_ENV->get_object(VmIds::get(vmId)); + } + return cimethod->has_balanced_monitors(); +} + +// public boolean RiMethod_uniqueConcreteMethod(long vmId); +JNIEXPORT jobject JNICALL Java_com_sun_hotspot_c1x_VMEntries_RiMethod_1uniqueConcreteMethod(JNIEnv *, jobject, jlong vmId) { + VM_ENTRY_MARK; + ciMethod* cimethod = (ciMethod*)CURRENT_ENV->get_object(VmIds::get(vmId)); + if (cimethod->holder()->is_interface()) { + // Cannot trust interfaces. Because of: + // interface I { void foo(); } + // class A { public void foo() {} } + // class B extends A implements I { } + // class C extends B { public void foo() { } } + // class D extends B { } + // Would lead to identify C.foo() as the unique concrete method for I.foo() without seeing A.foo(). + return false; + } + klassOop klass = (klassOop)cimethod->holder()->get_oop(); + methodHandle method((methodOop)cimethod->get_oop()); + methodHandle unique_concrete; + { + ResourceMark rm; + MutexLocker locker(Compile_lock); + unique_concrete = methodHandle(Dependencies::find_unique_concrete_method(klass, method())); + } + if (unique_concrete.is_null()) { + return NULL; + } + + Handle name = VmIds::toString(unique_concrete->name(), CHECK_NULL); + oop method_resolved = VMExits::createRiMethodResolved(VmIds::add(unique_concrete()), name, CHECK_NULL); + return JNIHandles::make_local(THREAD, method_resolved); +} + +// public RiType RiSignature_lookupType(String returnType, HotSpotTypeResolved accessingClass); +JNIEXPORT jobject JNICALL Java_com_sun_hotspot_c1x_VMEntries_RiSignature_1lookupType(JNIEnv *env, jobject, jstring jname, jobject accessingClass) { + VM_ENTRY_MARK; + + symbolOop nameSymbol = VmIds::toSymbol(jname); + Handle name = JNIHandles::resolve(jname); + + oop result; + if (nameSymbol == vmSymbols::int_signature()) { + result = VMExits::createRiTypePrimitive((int) T_INT, THREAD); + } else if (nameSymbol == vmSymbols::long_signature()) { + result = VMExits::createRiTypePrimitive((int) T_LONG, THREAD); + } else if (nameSymbol == vmSymbols::bool_signature()) { + result = VMExits::createRiTypePrimitive((int) T_BOOLEAN, THREAD); + } else if (nameSymbol == vmSymbols::char_signature()) { + result = VMExits::createRiTypePrimitive((int) T_CHAR, THREAD); + } else if (nameSymbol == vmSymbols::short_signature()) { + result = VMExits::createRiTypePrimitive((int) T_SHORT, THREAD); + } else if (nameSymbol == vmSymbols::byte_signature()) { + result = VMExits::createRiTypePrimitive((int) T_BYTE, THREAD); + } else if (nameSymbol == vmSymbols::double_signature()) { + result = VMExits::createRiTypePrimitive((int) T_DOUBLE, THREAD); + } else if (nameSymbol == vmSymbols::float_signature()) { + result = VMExits::createRiTypePrimitive((int) T_FLOAT, THREAD); + } else { + klassOop resolved_type = NULL; + // if the name isn't in the symbol table then the class isn't loaded anyway... + if (nameSymbol != NULL) { + Handle classloader; + Handle protectionDomain; + if (JNIHandles::resolve(accessingClass) != NULL) { + classloader = java_lang_Class::as_klassOop(HotSpotTypeResolved::javaMirror(accessingClass))->klass_part()->class_loader(); + protectionDomain = java_lang_Class::as_klassOop(HotSpotTypeResolved::javaMirror(accessingClass))->klass_part()->protection_domain(); + } + resolved_type = SystemDictionary::resolve_or_null(nameSymbol, classloader, protectionDomain, THREAD); + if (HAS_PENDING_EXCEPTION) { + CLEAR_PENDING_EXCEPTION; + resolved_type = NULL; + } + } + if (resolved_type != NULL) { + result = C1XCompiler::createHotSpotTypeResolved(resolved_type, name, CHECK_NULL); + } else { + result = VMExits::createRiTypeUnresolved(name, THREAD); + } + } + + return JNIHandles::make_local(THREAD, result); +} + +// public Object RiConstantPool_lookupConstant(long vmId, int cpi); +JNIEXPORT jobject JNICALL Java_com_sun_hotspot_c1x_VMEntries_RiConstantPool_1lookupConstant(JNIEnv *env, jobject, jlong vmId, jint index) { + VM_ENTRY_MARK; + + constantPoolOop cp = VmIds::get(vmId); + + oop result = NULL; + constantTag tag = cp->tag_at(index); + if (tag.is_int()) { + result = VMExits::createCiConstant(CiKind::Int(), cp->int_at(index), CHECK_0); + } else if (tag.is_long()) { + result = VMExits::createCiConstant(CiKind::Long(), cp->long_at(index), CHECK_0); + } else if (tag.is_float()) { + result = VMExits::createCiConstantFloat(cp->float_at(index), CHECK_0); + } else if (tag.is_double()) { + result = VMExits::createCiConstantDouble(cp->double_at(index), CHECK_0); + } else if (tag.is_string() || tag.is_unresolved_string()) { + oop string = NULL; + if (cp->is_pseudo_string_at(index)) { + string = cp->pseudo_string_at(index); + } else { + string = cp->string_at(index, THREAD); + if (HAS_PENDING_EXCEPTION) { + CLEAR_PENDING_EXCEPTION; + // TODO: Gracefully exit compilation. + fatal("out of memory during compilation!"); + return NULL; + } + } + result = VMExits::createCiConstantObject(string, CHECK_0); + } else if (tag.is_klass() || tag.is_unresolved_klass()) { + bool ignore; + ciInstanceKlass* accessor = (ciInstanceKlass*) ciEnv::current()->get_object(cp->pool_holder()); + ciKlass* klass = ciEnv::current()->get_klass_by_index(cp, index, ignore, accessor); + result = C1XCompiler::get_RiType(klass, cp->pool_holder(), CHECK_NULL); + } else if (tag.is_object()) { + oop obj = cp->object_at(index); + assert(obj->is_instance(), "must be an instance"); + result = VMExits::createCiConstantObject(obj, CHECK_NULL); + } else { + ShouldNotReachHere(); + } + + return JNIHandles::make_local(THREAD, result); +} + +// public RiMethod RiConstantPool_lookupMethod(long vmId, int cpi, byte byteCode); +JNIEXPORT jobject JNICALL Java_com_sun_hotspot_c1x_VMEntries_RiConstantPool_1lookupMethod(JNIEnv *env, jobject, jlong vmId, jint index, jbyte byteCode) { + VM_ENTRY_MARK; + + index = C1XCompiler::to_cp_index_u2(index); + constantPoolHandle cp = VmIds::get(vmId); + + Bytecodes::Code bc = (Bytecodes::Code) (((int) byteCode) & 0xFF); + ciInstanceKlass* loading_klass = (ciInstanceKlass *) CURRENT_ENV->get_object(cp->pool_holder()); + ciMethod *cimethod = CURRENT_ENV->get_method_by_index(cp, index, bc, loading_klass); + if (cimethod->is_loaded()) { + methodOop method = (methodOop) cimethod->get_oop(); + Handle name = VmIds::toString(method->name(), CHECK_NULL); + return JNIHandles::make_local(THREAD, VMExits::createRiMethodResolved(VmIds::add(method), name, THREAD)); + } else { + Handle name = VmIds::toString((symbolOop) cimethod->name()->get_oop(), CHECK_NULL); + Handle signature = VmIds::toString((symbolOop) cimethod->signature()->as_symbol()->get_oop(), CHECK_NULL); + Handle holder = C1XCompiler::get_RiType(cimethod->holder(), cp->klass(), THREAD); + return JNIHandles::make_local(THREAD, VMExits::createRiMethodUnresolved(name, signature, holder, THREAD)); + } +} + +// public RiSignature RiConstantPool_lookupSignature(long vmId, int cpi); +JNIEXPORT jobject JNICALL Java_com_sun_hotspot_c1x_VMEntries_RiConstantPool_1lookupSignature(JNIEnv *env, jobject, jlong vmId, jint index) { + fatal("currently unsupported"); + return NULL; +} + +// public RiType RiConstantPool_lookupType(long vmId, int cpi); +JNIEXPORT jobject JNICALL Java_com_sun_hotspot_c1x_VMEntries_RiConstantPool_1lookupType(JNIEnv *env, jobject, jlong vmId, jint index) { + VM_ENTRY_MARK; + + constantPoolOop cp = VmIds::get(vmId); + + ciInstanceKlass* loading_klass = (ciInstanceKlass *) CURRENT_ENV->get_object(cp->pool_holder()); + bool is_accessible = false; + ciKlass *klass = CURRENT_ENV->get_klass_by_index(cp, index, is_accessible, loading_klass); + return JNIHandles::make_local(THREAD, C1XCompiler::get_RiType(klass, cp->klass(), THREAD)); +} + +// public RiField RiConstantPool_lookupField(long vmId, int cpi); +JNIEXPORT jobject JNICALL Java_com_sun_hotspot_c1x_VMEntries_RiConstantPool_1lookupField(JNIEnv *env, jobject, jlong vmId, jint index, jbyte byteCode) { + VM_ENTRY_MARK; + + index = C1XCompiler::to_cp_index_u2(index); + constantPoolOop cp = VmIds::get(vmId); + + ciInstanceKlass* loading_klass = (ciInstanceKlass *) CURRENT_ENV->get_object(cp->pool_holder()); + ciField *field = CURRENT_ENV->get_field_by_index(loading_klass, index); + Bytecodes::Code code = (Bytecodes::Code)(((int) byteCode) & 0xFF); + Handle field_handle = C1XCompiler::get_RiField(field, loading_klass, cp->pool_holder(), code, THREAD); + bool is_constant = field->is_constant(); + if (is_constant && field->is_static()) { + ciConstant constant = field->constant_value(); + oop constant_object = NULL; + switch (constant.basic_type()) { + case T_OBJECT: + case T_ARRAY: + { + ciObject* obj = constant.as_object(); + if (obj->is_null_object()) { + constant_object = VMExits::createCiConstantObject(NULL, CHECK_0); + } else if (obj->can_be_constant()) { + constant_object = VMExits::createCiConstantObject(constant.as_object()->get_oop(), CHECK_0); + } + } + break; + case T_DOUBLE: + constant_object = VMExits::createCiConstantDouble(constant.as_double(), CHECK_0); + break; + case T_FLOAT: + constant_object = VMExits::createCiConstantFloat(constant.as_float(), CHECK_0); + break; + case T_LONG: + constant_object = VMExits::createCiConstant(CiKind::Long(), constant.as_long(), CHECK_0); + break; + case T_INT: + constant_object = VMExits::createCiConstant(CiKind::Int(), constant.as_int(), CHECK_0); + break; + case T_SHORT: + constant_object = VMExits::createCiConstant(CiKind::Short(), constant.as_int(), CHECK_0); + break; + case T_CHAR: + constant_object = VMExits::createCiConstant(CiKind::Char(), constant.as_int(), CHECK_0); + break; + case T_BYTE: + constant_object = VMExits::createCiConstant(CiKind::Byte(), constant.as_int(), CHECK_0); + break; + case T_BOOLEAN: + constant_object = VMExits::createCiConstant(CiKind::Boolean(), constant.as_int(), CHECK_0); + break; + default: + constant.print(); + fatal("Unhandled constant"); + } + if (constant_object != NULL) { + HotSpotField::set_constant(field_handle, constant_object); + } + } + return JNIHandles::make_local(THREAD, field_handle()); +} + +// public RiConstantPool RiType_constantPool(HotSpotTypeResolved klass); +JNIEXPORT jobject JNICALL Java_com_sun_hotspot_c1x_VMEntries_RiType_1constantPool(JNIEnv *, jobject, jobject klass) { + VM_ENTRY_MARK; + + assert(JNIHandles::resolve(klass) != NULL, ""); + constantPoolOop constantPool = ((instanceKlass*)java_lang_Class::as_klassOop(HotSpotTypeResolved::javaMirror(klass))->klass_part())->constants(); + return JNIHandles::make_local(VMExits::createRiConstantPool(VmIds::add(constantPool), THREAD)); +} + +// public RiMethod RiType_resolveMethodImpl(HotSpotTypeResolved klass, String name, String signature); +JNIEXPORT jobject JNICALL Java_com_sun_hotspot_c1x_VMEntries_RiType_3resolveMethodImpl(JNIEnv *, jobject, jobject resolved_type, jstring name, jstring signature) { + VM_ENTRY_MARK; + + assert(JNIHandles::resolve(resolved_type) != NULL, ""); + klassOop klass = java_lang_Class::as_klassOop(HotSpotTypeResolved::javaMirror(resolved_type)); + symbolOop name_symbol = VmIds::toSymbol(name); + symbolOop signature_symbol = VmIds::toSymbol(signature); + methodOop method = klass->klass_part()->lookup_method(name_symbol, signature_symbol); + if (method == NULL) { + if (TraceC1X >= 3) { + ResourceMark rm; + tty->print_cr("Could not resolve method %s %s on klass %d", name_symbol->as_C_string(), signature_symbol->as_C_string(), klass->klass_part()->name()->as_C_string()); + } + return NULL; + } + return JNIHandles::make_local(THREAD, VMExits::createRiMethodResolved(VmIds::add(method), Handle(JNIHandles::resolve(name)), THREAD)); +} + +// public boolean RiType_isSubtypeOf(HotSpotTypeResolved klass, RiType other); +JNIEXPORT jboolean JNICALL Java_com_sun_hotspot_c1x_VMEntries_RiType_2isSubtypeOf(JNIEnv *, jobject, jobject klass, jobject jother) { + oop other = JNIHandles::resolve(jother); + assert(other->is_a(HotSpotTypeResolved::klass()), "resolved hotspot type expected"); + assert(JNIHandles::resolve(klass) != NULL, ""); + klassOop thisKlass = java_lang_Class::as_klassOop(HotSpotTypeResolved::javaMirror(klass)); + klassOop otherKlass = java_lang_Class::as_klassOop(HotSpotTypeResolved::javaMirror(other)); + if (thisKlass->klass_part()->oop_is_instance_slow()) { + return instanceKlass::cast(thisKlass)->is_subtype_of(otherKlass); + } else if (thisKlass->klass_part()->oop_is_array()) { + return arrayKlass::cast(thisKlass)->is_subtype_of(otherKlass); + } else { + fatal("unexpected class type"); + } +} + +// public RiType RiType_componentType(HotSpotResolvedType klass); +JNIEXPORT jobject JNICALL Java_com_sun_hotspot_c1x_VMEntries_RiType_1componentType(JNIEnv *, jobject, jobject klass) { + ciArrayKlass* array_klass; + { + VM_ENTRY_MARK; + assert(JNIHandles::resolve(klass) != NULL, ""); + array_klass = (ciArrayKlass *) CURRENT_ENV->get_object(java_lang_Class::as_klassOop(HotSpotTypeResolved::javaMirror(klass))); + } + ciType* element_type = array_klass->element_type(); + + VM_ENTRY_MARK; + assert(JNIHandles::resolve(klass) != NULL, ""); + return JNIHandles::make_local(C1XCompiler::get_RiType(element_type, java_lang_Class::as_klassOop(HotSpotTypeResolved::javaMirror(klass)), THREAD)); +} + + +// public RiType RiType_uniqueConcreteSubtype(HotSpotResolvedType klass); +JNIEXPORT jobject JNICALL Java_com_sun_hotspot_c1x_VMEntries_RiType_1uniqueConcreteSubtype(JNIEnv *, jobject, jobject klass) { + + Thread* THREAD = Thread::current(); + KlassHandle klass_handle(java_lang_Class::as_klassOop(HotSpotTypeResolved::javaMirror(klass))); + ciInstanceKlass* k = NULL; + { + VM_ENTRY_MARK; + k = (ciInstanceKlass *) CURRENT_ENV->get_object(klass_handle()); + } + + if (k->is_abstract()) { + ciInstanceKlass* sub = k->unique_concrete_subklass(); + if (sub != NULL && sub->is_leaf_type()) { + VM_ENTRY_MARK; + return JNIHandles::make_local(C1XCompiler::get_RiType(sub, klass_handle, THREAD)); + } + } else if (k->is_leaf_type()) { + assert(!k->is_interface(), ""); + return klass; + } + + return NULL; +} + +// public RiType RiType_arrayOf(HotSpotTypeResolved klass); +JNIEXPORT jobject JNICALL Java_com_sun_hotspot_c1x_VMEntries_RiType_1arrayOf(JNIEnv *, jobject, jobject klass) { + VM_ENTRY_MARK; + + KlassHandle klass_handle(java_lang_Class::as_klassOop(HotSpotTypeResolved::javaMirror(klass))); + KlassHandle array = klass_handle->array_klass(THREAD); + Handle name = VmIds::toString(array->name(), CHECK_NULL); + return JNIHandles::make_local(THREAD, C1XCompiler::createHotSpotTypeResolved(array, name, THREAD)); +} + +// public RiType getPrimitiveArrayType(CiKind kind); +JNIEXPORT jobject JNICALL Java_com_sun_hotspot_c1x_VMEntries_getPrimitiveArrayType(JNIEnv *env, jobject, jobject kind) { + VM_ENTRY_MARK; + BasicType type = C1XCompiler::kindToBasicType(CiKind::typeChar(kind)); + assert(type != T_OBJECT, "primitive type expecteds"); + ciKlass* klass = ciTypeArrayKlass::make(type); + return JNIHandles::make_local(THREAD, C1XCompiler::get_RiType(klass, KlassHandle(NULL, THREAD), THREAD)); +} + +// public RiType getType(Class javaClass); +JNIEXPORT jobject JNICALL Java_com_sun_hotspot_c1x_VMEntries_getType(JNIEnv *env, jobject, jobject javaClass) { + VM_ENTRY_MARK; + oop javaClassOop = JNIHandles::resolve(javaClass); + if (javaClassOop == NULL) { + fatal("argument to VMEntries.getType must not be NULL"); + } else if (java_lang_Class::is_primitive(javaClassOop)) { + BasicType basicType = java_lang_Class::primitive_type(javaClassOop); + return JNIHandles::make_local(THREAD, VMExits::createRiTypePrimitive((int) basicType, THREAD)); + } else { + KlassHandle klass = java_lang_Class::as_klassOop(javaClassOop); + Handle name = java_lang_String::create_from_symbol(klass->name(), CHECK_NULL); + + oop type = C1XCompiler::createHotSpotTypeResolved(klass, name, CHECK_NULL); + return JNIHandles::make_local(THREAD, type); + } +} + + +// helpers used to set fields in the HotSpotVMConfig object +jfieldID getFieldID(JNIEnv* env, jobject obj, const char* name, const char* sig) { + jfieldID id = env->GetFieldID(env->GetObjectClass(obj), name, sig); + if (id == NULL) { + TRACE_C1X_1("field not found: %s (%s)", name, sig); + fatal("field not found"); + } + return id; +} + +void set_boolean(JNIEnv* env, jobject obj, const char* name, bool value) { env->SetBooleanField(obj, getFieldID(env, obj, name, "Z"), value); } +void set_int(JNIEnv* env, jobject obj, const char* name, int value) { env->SetIntField(obj, getFieldID(env, obj, name, "I"), value); } +void set_long(JNIEnv* env, jobject obj, const char* name, long value) { env->SetLongField(obj, getFieldID(env, obj, name, "J"), value); } +void set_object(JNIEnv* env, jobject obj, const char* name, jobject value) { env->SetObjectField(obj, getFieldID(env, obj, name, "Ljava/lang/Object;"), value); } +void set_int_array(JNIEnv* env, jobject obj, const char* name, jarray value) { env->SetObjectField(obj, getFieldID(env, obj, name, "[I"), value); } + +jboolean get_boolean(JNIEnv* env, jobject obj, const char* name) { return env->GetBooleanField(obj, getFieldID(env, obj, name, "Z")); } +jint get_int(JNIEnv* env, jobject obj, const char* name) { return env->GetIntField(obj, getFieldID(env, obj, name, "I")); } +jlong get_long(JNIEnv* env, jobject obj, const char* name) { return env->GetLongField(obj, getFieldID(env, obj, name, "J")); } +jobject get_object(JNIEnv* env, jobject obj, const char* name) { return env->GetObjectField(obj, getFieldID(env, obj, name, "Ljava/lang/Object;")); } +jobject get_object(JNIEnv* env, jobject obj, const char* name, const char* sig) { return env->GetObjectField(obj, getFieldID(env, obj, name, sig)); } + + +BasicType basicTypes[] = { T_BOOLEAN, T_BYTE, T_SHORT, T_CHAR, T_INT, T_FLOAT, T_LONG, T_DOUBLE, T_OBJECT }; +int basicTypeCount = sizeof(basicTypes) / sizeof(BasicType); + +// public HotSpotVMConfig getConfiguration(); +JNIEXPORT jobject JNICALL Java_com_sun_hotspot_c1x_VMEntries_getConfiguration(JNIEnv *env, jobject) { + jclass klass = env->FindClass("com/sun/hotspot/c1x/HotSpotVMConfig"); + assert(klass != NULL, "HotSpot vm config class not found"); + jobject config = env->AllocObject(klass); +#ifdef _WIN64 + set_boolean(env, config, "windowsOs", true); +#else + set_boolean(env, config, "windowsOs", false); +#endif + set_boolean(env, config, "verifyPointers", VerifyOops); + set_boolean(env, config, "useFastLocking", UseFastLocking); + set_boolean(env, config, "useFastNewObjectArray", UseFastNewObjectArray); + set_boolean(env, config, "useFastNewTypeArray", UseFastNewTypeArray); + set_int(env, config, "codeEntryAlignment", CodeEntryAlignment); + set_int(env, config, "vmPageSize", os::vm_page_size()); + set_int(env, config, "stackShadowPages", StackShadowPages); + set_int(env, config, "hubOffset", oopDesc::klass_offset_in_bytes()); + set_int(env, config, "arrayLengthOffset", arrayOopDesc::length_offset_in_bytes()); + set_int(env, config, "klassStateOffset", instanceKlass::init_state_offset_in_bytes() + sizeof(oopDesc)); + set_int(env, config, "klassStateFullyInitialized", (int)instanceKlass::fully_initialized); + set_int(env, config, "threadTlabTopOffset", in_bytes(JavaThread::tlab_top_offset())); + set_int(env, config, "threadTlabEndOffset", in_bytes(JavaThread::tlab_end_offset())); + set_int(env, config, "threadObjectOffset", in_bytes(JavaThread::threadObj_offset())); + set_int(env, config, "instanceHeaderPrototypeOffset", Klass::prototype_header_offset_in_bytes() + klassOopDesc::klass_part_offset_in_bytes()); + set_int(env, config, "threadExceptionOopOffset", in_bytes(JavaThread::exception_oop_offset())); + set_int(env, config, "threadExceptionPcOffset", in_bytes(JavaThread::exception_pc_offset())); + set_int(env, config, "threadMultiNewArrayStorage", in_bytes(JavaThread::c1x_multinewarray_storage_offset())); + set_int(env, config, "classMirrorOffset", klassOopDesc::klass_part_offset_in_bytes() + Klass::java_mirror_offset_in_bytes()); + + set_long(env, config, "debugStub", VmIds::addStub((address)warning)); + set_long(env, config, "instanceofStub", VmIds::addStub(Runtime1::entry_for(Runtime1::slow_subtype_check_id))); + set_long(env, config, "verifyPointerStub", VmIds::addStub(Runtime1::entry_for(Runtime1::c1x_verify_pointer_id))); + set_long(env, config, "newInstanceStub", VmIds::addStub(Runtime1::entry_for(Runtime1::fast_new_instance_init_check_id))); + set_long(env, config, "unresolvedNewInstanceStub", VmIds::addStub(Runtime1::entry_for(Runtime1::new_instance_id))); + set_long(env, config, "newTypeArrayStub", VmIds::addStub(Runtime1::entry_for(Runtime1::new_type_array_id))); + set_long(env, config, "newObjectArrayStub", VmIds::addStub(Runtime1::entry_for(Runtime1::new_object_array_id))); + set_long(env, config, "newMultiArrayStub", VmIds::addStub(Runtime1::entry_for(Runtime1::new_multi_array_id))); + set_long(env, config, "loadKlassStub", VmIds::addStub(Runtime1::entry_for(Runtime1::load_klass_patching_id))); + set_long(env, config, "accessFieldStub", VmIds::addStub(Runtime1::entry_for(Runtime1::access_field_patching_id))); + set_long(env, config, "resolveStaticCallStub", VmIds::addStub(SharedRuntime::get_resolve_static_call_stub())); + set_long(env, config, "inlineCacheMissStub", VmIds::addStub(SharedRuntime::get_ic_miss_stub())); + set_long(env, config, "unwindExceptionStub", VmIds::addStub(Runtime1::entry_for(Runtime1::c1x_unwind_exception_call_id))); + set_long(env, config, "handleExceptionStub", VmIds::addStub(Runtime1::entry_for(Runtime1::handle_exception_nofpu_id))); + set_long(env, config, "handleDeoptStub", VmIds::addStub(SharedRuntime::deopt_blob()->unpack())); + set_long(env, config, "throwClassCastException", VmIds::addStub(Runtime1::entry_for(Runtime1::throw_class_cast_exception_id))); + set_long(env, config, "throwArrayStoreException", VmIds::addStub(Runtime1::entry_for(Runtime1::throw_array_store_exception_id))); + set_long(env, config, "throwArrayIndexException", VmIds::addStub(Runtime1::entry_for(Runtime1::throw_range_check_failed_id))); + set_long(env, config, "monitorEnterStub", VmIds::addStub(Runtime1::entry_for(Runtime1::monitorenter_id))); + set_long(env, config, "monitorExitStub", VmIds::addStub(Runtime1::entry_for(Runtime1::monitorexit_id))); + set_long(env, config, "fastMonitorEnterStub", VmIds::addStub(Runtime1::entry_for(Runtime1::c1x_monitorenter_id))); + set_long(env, config, "fastMonitorExitStub", VmIds::addStub(Runtime1::entry_for(Runtime1::c1x_monitorexit_id))); + set_long(env, config, "safepointPollingAddress", (jlong)(os::get_polling_page() + (SafepointPollOffset % os::vm_page_size()))); + + BarrierSet* bs = Universe::heap()->barrier_set(); + switch (bs->kind()) { + case BarrierSet::CardTableModRef: + case BarrierSet::CardTableExtension: { + jlong base = (jlong)((CardTableModRefBS*)bs)->byte_map_base; + assert(base != 0, "unexpected byte_map_base"); + set_long(env, config, "cardtableStartAddress", base); + set_int(env, config, "cardtableShift", CardTableModRefBS::card_shift); + break; + } + case BarrierSet::ModRef: + case BarrierSet::Other: + set_long(env, config, "cardtableStartAddress", 0); + set_int(env, config, "cardtableShift", 0); + // No post barriers + break; +#ifndef SERIALGC + case BarrierSet::G1SATBCT: + case BarrierSet::G1SATBCTLogging: +#endif // SERIALGC + default: + ShouldNotReachHere(); + } + + jintArray arrayOffsets = env->NewIntArray(basicTypeCount); + for (int i=0; iSetIntArrayRegion(arrayOffsets, i, 1, &offset); + } + set_int_array(env, config, "arrayOffsets", arrayOffsets); + set_int(env, config, "arrayClassElementOffset", objArrayKlass::element_klass_offset_in_bytes() + sizeof(oopDesc)); + return config; +} + +// public void installMethod(HotSpotTargetMethod targetMethod); +JNIEXPORT void JNICALL Java_com_sun_hotspot_c1x_VMEntries_installMethod(JNIEnv *jniEnv, jobject, jobject targetMethod) { + VM_ENTRY_MARK; + CodeInstaller installer(JNIHandles::resolve(targetMethod)); +} + +// public HotSpotProxy installStub(HotSpotTargetMethod targetMethod, String name); +JNIEXPORT jlong JNICALL Java_com_sun_hotspot_c1x_VMEntries_installStub(JNIEnv *jniEnv, jobject, jobject targetMethod) { + VM_ENTRY_MARK; + jlong id; + CodeInstaller installer(JNIHandles::resolve(targetMethod), id); + return id; +} + +// public void recordBailout(String reason); +JNIEXPORT void JNICALL Java_com_sun_hotspot_c1x_VMEntries_recordBailout(JNIEnv *jniEnv, jobject message) { + if (C1XBailoutIsFatal) { + Handle msg = JNIHandles::resolve(message); + if (msg.is_null()) { + java_lang_String::print(msg, tty); + } + fatal("Bailout in C1X"); + } +} + + + + +#define CC (char*) /*cast a literal from (const char*)*/ +#define FN_PTR(f) CAST_FROM_FN_PTR(void*, &f) + +#define PROXY "J" +#define TYPE "Lcom/sun/cri/ri/RiType;" +#define RESOLVED_TYPE "Lcom/sun/hotspot/c1x/HotSpotTypeResolved;" +#define METHOD "Lcom/sun/cri/ri/RiMethod;" +#define SIGNATURE "Lcom/sun/cri/ri/RiSignature;" +#define FIELD "Lcom/sun/cri/ri/RiField;" +#define CONSTANT_POOL "Lcom/sun/cri/ri/RiConstantPool;" +#define EXCEPTION_HANDLERS "[Lcom/sun/cri/ri/RiExceptionHandler;" +#define TARGET_METHOD "Lcom/sun/hotspot/c1x/HotSpotTargetMethod;" +#define CONFIG "Lcom/sun/hotspot/c1x/HotSpotVMConfig;" +#define HS_METHOD "Lcom/sun/hotspot/c1x/HotSpotMethod;" +#define CI_CONSTANT "Lcom/sun/cri/ci/CiConstant;" +#define CI_KIND "Lcom/sun/cri/ci/CiKind;" +#define STRING "Ljava/lang/String;" +#define OBJECT "Ljava/lang/Object;" +#define CLASS "Ljava/lang/Class;" + +JNINativeMethod VMEntries_methods[] = { + {CC"RiMethod_code", CC"("PROXY")[B", FN_PTR(Java_com_sun_hotspot_c1x_VMEntries_RiMethod_1code)}, + {CC"RiMethod_maxStackSize", CC"("PROXY")I", FN_PTR(Java_com_sun_hotspot_c1x_VMEntries_RiMethod_1maxStackSize)}, + {CC"RiMethod_maxLocals", CC"("PROXY")I", FN_PTR(Java_com_sun_hotspot_c1x_VMEntries_RiMethod_1maxLocals)}, + {CC"RiMethod_holder", CC"("PROXY")"TYPE, FN_PTR(Java_com_sun_hotspot_c1x_VMEntries_RiMethod_1holder)}, + {CC"RiMethod_signature", CC"("PROXY")"STRING, FN_PTR(Java_com_sun_hotspot_c1x_VMEntries_RiMethod_1signature)}, + {CC"RiMethod_accessFlags", CC"("PROXY")I", FN_PTR(Java_com_sun_hotspot_c1x_VMEntries_RiMethod_1accessFlags)}, + {CC"RiMethod_exceptionHandlers", CC"("PROXY")"EXCEPTION_HANDLERS, FN_PTR(Java_com_sun_hotspot_c1x_VMEntries_RiMethod_1exceptionHandlers)}, + {CC"RiMethod_hasBalancedMonitors", CC"("PROXY")Z", FN_PTR(Java_com_sun_hotspot_c1x_VMEntries_RiMethod_1hasBalancedMonitors)}, + {CC"RiMethod_uniqueConcreteMethod", CC"("PROXY")"METHOD, FN_PTR(Java_com_sun_hotspot_c1x_VMEntries_RiMethod_1uniqueConcreteMethod)}, + {CC"RiSignature_lookupType", CC"("STRING RESOLVED_TYPE")"TYPE, FN_PTR(Java_com_sun_hotspot_c1x_VMEntries_RiSignature_1lookupType)}, + {CC"RiConstantPool_lookupConstant", CC"("PROXY"I)"OBJECT, FN_PTR(Java_com_sun_hotspot_c1x_VMEntries_RiConstantPool_1lookupConstant)}, + {CC"RiConstantPool_lookupMethod", CC"("PROXY"IB)"METHOD, FN_PTR(Java_com_sun_hotspot_c1x_VMEntries_RiConstantPool_1lookupMethod)}, + {CC"RiConstantPool_lookupSignature", CC"("PROXY"I)"SIGNATURE, FN_PTR(Java_com_sun_hotspot_c1x_VMEntries_RiConstantPool_1lookupSignature)}, + {CC"RiConstantPool_lookupType", CC"("PROXY"I)"TYPE, FN_PTR(Java_com_sun_hotspot_c1x_VMEntries_RiConstantPool_1lookupType)}, + {CC"RiConstantPool_lookupField", CC"("PROXY"IB)"FIELD, FN_PTR(Java_com_sun_hotspot_c1x_VMEntries_RiConstantPool_1lookupField)}, + {CC"RiType_constantPool", CC"("RESOLVED_TYPE")"CONSTANT_POOL, FN_PTR(Java_com_sun_hotspot_c1x_VMEntries_RiType_1constantPool)}, + {CC"RiType_resolveMethodImpl", CC"("RESOLVED_TYPE STRING STRING")"METHOD, FN_PTR(Java_com_sun_hotspot_c1x_VMEntries_RiType_3resolveMethodImpl)}, + {CC"RiType_isSubtypeOf", CC"("RESOLVED_TYPE TYPE")Z", FN_PTR(Java_com_sun_hotspot_c1x_VMEntries_RiType_2isSubtypeOf)}, + {CC"RiType_componentType", CC"("RESOLVED_TYPE")"TYPE, FN_PTR(Java_com_sun_hotspot_c1x_VMEntries_RiType_1componentType)}, + {CC"RiType_uniqueConcreteSubtype", CC"("RESOLVED_TYPE")"TYPE, FN_PTR(Java_com_sun_hotspot_c1x_VMEntries_RiType_1uniqueConcreteSubtype)}, + {CC"RiType_arrayOf", CC"("RESOLVED_TYPE")"TYPE, FN_PTR(Java_com_sun_hotspot_c1x_VMEntries_RiType_1arrayOf)}, + {CC"getPrimitiveArrayType", CC"("CI_KIND")"TYPE, FN_PTR(Java_com_sun_hotspot_c1x_VMEntries_getPrimitiveArrayType)}, + {CC"getType", CC"("CLASS")"TYPE, FN_PTR(Java_com_sun_hotspot_c1x_VMEntries_getType)}, + {CC"getConfiguration", CC"()"CONFIG, FN_PTR(Java_com_sun_hotspot_c1x_VMEntries_getConfiguration)}, + {CC"installMethod", CC"("TARGET_METHOD")V", FN_PTR(Java_com_sun_hotspot_c1x_VMEntries_installMethod)}, + {CC"installStub", CC"("TARGET_METHOD")"PROXY, FN_PTR(Java_com_sun_hotspot_c1x_VMEntries_installStub)}, + {CC"recordBailout", CC"("STRING")V", FN_PTR(Java_com_sun_hotspot_c1x_VMEntries_recordBailout)} +}; + +int VMEntries_methods_count() { + return sizeof(VMEntries_methods) / sizeof(JNINativeMethod); +} diff -r 102466e70deb -r 91fe28b03d6a src/share/vm/c1x/c1x_VMEntries.hpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/vm/c1x/c1x_VMEntries.hpp Wed Jan 26 18:17:37 2011 +0100 @@ -0,0 +1,30 @@ +/* + * Copyright 2000-2010 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +extern JNINativeMethod VMEntries_methods[]; +int VMEntries_methods_count(); + +// nothing here - no need to define the jni method implementations in a header file + + diff -r 102466e70deb -r 91fe28b03d6a src/share/vm/c1x/c1x_VMExits.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/vm/c1x/c1x_VMExits.cpp Wed Jan 26 18:17:37 2011 +0100 @@ -0,0 +1,220 @@ +/* + * Copyright 2000-2010 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +#include "precompiled.hpp" +#include "c1x/c1x_VMExits.hpp" + +// this is a *global* handle +jobject VMExits::_vmExitsPermObject; +jobject VMExits::_vmExitsPermKlass; + +KlassHandle VMExits::vmExitsKlass() { + if (JNIHandles::resolve(_vmExitsPermKlass) == NULL) { + klassOop result = SystemDictionary::resolve_or_null(vmSymbols::com_sun_hotspot_c1x_VMExits(), SystemDictionary::java_system_loader(), NULL, Thread::current()); + if (result == NULL) { + fatal("Could not find class com.sun.hotspot.c1x.VMExits"); + } + _vmExitsPermKlass = JNIHandles::make_global(result); + } + return KlassHandle((klassOop)JNIHandles::resolve_non_null(_vmExitsPermKlass)); +} + +Handle VMExits::instance() { + if (JNIHandles::resolve(_vmExitsPermObject) == NULL) { + KlassHandle compiler_klass = SystemDictionary::resolve_or_null(vmSymbols::com_sun_hotspot_c1x_Compiler(), SystemDictionary::java_system_loader(), NULL, Thread::current()); + if (compiler_klass.is_null()) { + fatal("Could not find class com.sun.hotspot.c1x.Compiler"); + } + JavaValue result(T_OBJECT); + JavaCallArguments args; + JavaCalls::call_static(&result, compiler_klass(), vmSymbols::getVMExits_name(), vmSymbols::getVMExits_signature(), &args, Thread::current()); + check_pending_exception("Couldn't get VMExits"); + oop res = (oop) result.get_jobject(); + _vmExitsPermObject = JNIHandles::make_global(res); + } + return Handle(JNIHandles::resolve_non_null(_vmExitsPermObject)); +} + +jboolean VMExits::setOption(Handle option) { + assert(!option.is_null(), ""); + Thread* THREAD = Thread::current(); + JavaValue result(T_BOOLEAN); + JavaCallArguments args; + args.push_oop(instance()); + args.push_oop(option); + JavaCalls::call_interface(&result, vmExitsKlass(), vmSymbols::setOption_name(), vmSymbols::setOption_signature(), &args, THREAD); + check_pending_exception("Error while calling setOption"); + return result.get_jboolean(); +} + +void VMExits::compileMethod(jlong methodVmId, Handle name, int entry_bci) { + assert(!name.is_null(), "just checking"); + Thread* THREAD = Thread::current(); + JavaValue result(T_VOID); + JavaCallArguments args; + args.push_oop(instance()); + args.push_long(methodVmId); + args.push_oop(name); + args.push_int(entry_bci); + JavaCalls::call_interface(&result, vmExitsKlass(), vmSymbols::compileMethod_name(), vmSymbols::compileMethod_signature(), &args, THREAD); + check_pending_exception("Error while calling compileMethod"); +} + +oop VMExits::createRiMethodResolved(jlong vmId, Handle name, TRAPS) { + assert(!name.is_null(), "just checking"); + JavaValue result(T_OBJECT); + JavaCallArguments args; + args.push_oop(instance()); + args.push_long(vmId); + args.push_oop(name); + JavaCalls::call_interface(&result, vmExitsKlass(), vmSymbols::createRiMethodResolved_name(), vmSymbols::createRiMethodResolved_signature(), &args, THREAD); + check_pending_exception("Error while calling createRiMethodResolved"); + return (oop) result.get_jobject(); +} + +oop VMExits::createRiMethodUnresolved(Handle name, Handle signature, Handle holder, TRAPS) { + assert(!name.is_null(), "just checking"); + JavaValue result(T_OBJECT); + JavaCallArguments args; + args.push_oop(instance()); + args.push_oop(name); + args.push_oop(signature); + args.push_oop(holder); + JavaCalls::call_interface(&result, vmExitsKlass(), vmSymbols::createRiMethodUnresolved_name(), vmSymbols::createRiMethodUnresolved_signature(), &args, THREAD); + check_pending_exception("Error while calling createRiMethodUnresolved"); + return (oop) result.get_jobject(); +} + +oop VMExits::createRiField(Handle holder, Handle name, Handle type, int index, TRAPS) { + assert(!holder.is_null(), "just checking"); + assert(!name.is_null(), "just checking"); + assert(!type.is_null(), "just checking"); + JavaValue result(T_OBJECT); + JavaCallArguments args; + args.push_oop(instance()); + args.push_oop(holder); + args.push_oop(name); + args.push_oop(type); + args.push_int(index); + JavaCalls::call_interface(&result, vmExitsKlass(), vmSymbols::createRiField_name(), vmSymbols::createRiField_signature(), &args, THREAD); + check_pending_exception("Error while calling createRiField"); + return (oop) result.get_jobject(); +} + +oop VMExits::createRiType(jlong vmId, Handle name, TRAPS) { + assert(!name.is_null(), "just checking"); + JavaValue result(T_OBJECT); + JavaCallArguments args; + args.push_oop(instance()); + args.push_long(vmId); + args.push_oop(name); + JavaCalls::call_interface(&result, vmExitsKlass(), vmSymbols::createRiType_name(), vmSymbols::createRiType_signature(), &args, THREAD); + check_pending_exception("Error while calling createRiType"); + return (oop) result.get_jobject(); +} + +oop VMExits::createRiTypePrimitive(int basic_type, TRAPS) { + JavaValue result(T_OBJECT); + JavaCallArguments args; + args.push_oop(instance()); + args.push_int(basic_type); + JavaCalls::call_interface(&result, vmExitsKlass(), vmSymbols::createRiTypePrimitive_name(), vmSymbols::createRiTypePrimitive_signature(), &args, THREAD); + check_pending_exception("Error while calling createRiTypePrimitive"); + return (oop) result.get_jobject(); +} + +oop VMExits::createRiTypeUnresolved(Handle name, TRAPS) { + assert(!name.is_null(), "just checking"); + JavaValue result(T_OBJECT); + JavaCallArguments args; + args.push_oop(instance()); + args.push_oop(name); + JavaCalls::call_interface(&result, vmExitsKlass(), vmSymbols::createRiTypeUnresolved_name(), vmSymbols::createRiTypeUnresolved_signature(), &args, THREAD); + check_pending_exception("Error while calling createRiTypeUnresolved"); + return (oop) result.get_jobject(); +} + +oop VMExits::createRiConstantPool(jlong vmId, TRAPS) { + JavaValue result(T_OBJECT); + JavaCallArguments args; + args.push_oop(instance()); + args.push_long(vmId); + JavaCalls::call_interface(&result, vmExitsKlass(), vmSymbols::createRiConstantPool_name(), vmSymbols::createRiConstantPool_signature(), &args, THREAD); + check_pending_exception("Error while calling createRiConstantPool"); + return (oop) result.get_jobject(); +} + +oop VMExits::createRiSignature(Handle name, TRAPS) { + assert(!name.is_null(), "just checking"); + JavaValue result(T_OBJECT); + JavaCallArguments args; + args.push_oop(instance()); + args.push_oop(name); + JavaCalls::call_interface(&result, vmExitsKlass(), vmSymbols::createRiSignature_name(), vmSymbols::createRiSignature_signature(), &args, THREAD); + check_pending_exception("Error while calling createRiSignature"); + return (oop) result.get_jobject(); +} + +oop VMExits::createCiConstant(Handle kind, jlong value, TRAPS) { + JavaValue result(T_OBJECT); + JavaCallArguments args; + args.push_oop(instance()); + args.push_oop(kind()); + args.push_long(value); + JavaCalls::call_interface(&result, vmExitsKlass(), vmSymbols::createCiConstant_name(), vmSymbols::createCiConstant_signature(), &args, THREAD); + check_pending_exception("Error while calling createCiConstantFloat"); + return (oop) result.get_jobject(); + +} + +oop VMExits::createCiConstantFloat(jfloat value, TRAPS) { + JavaValue result(T_OBJECT); + JavaCallArguments args; + args.push_oop(instance()); + args.push_float(value); + JavaCalls::call_interface(&result, vmExitsKlass(), vmSymbols::createCiConstantFloat_name(), vmSymbols::createCiConstantFloat_signature(), &args, THREAD); + check_pending_exception("Error while calling createCiConstantFloat"); + return (oop) result.get_jobject(); + +} + +oop VMExits::createCiConstantDouble(jdouble value, TRAPS) { + JavaValue result(T_OBJECT); + JavaCallArguments args; + args.push_oop(instance()); + args.push_double(value); + JavaCalls::call_interface(&result, vmExitsKlass(), vmSymbols::createCiConstantDouble_name(), vmSymbols::createCiConstantDouble_signature(), &args, THREAD); + check_pending_exception("Error while calling createCiConstantDouble"); + return (oop) result.get_jobject(); +} + +oop VMExits::createCiConstantObject(Handle object, TRAPS) { + JavaValue result(T_OBJECT); + JavaCallArguments args; + args.push_oop(instance()); + args.push_oop(object); + JavaCalls::call_interface(&result, vmExitsKlass(), vmSymbols::createCiConstantObject_name(), vmSymbols::createCiConstantObject_signature(), &args, THREAD); + check_pending_exception("Error while calling createCiConstantObject"); + return (oop) result.get_jobject(); +} diff -r 102466e70deb -r 91fe28b03d6a src/share/vm/c1x/c1x_VMExits.hpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/vm/c1x/c1x_VMExits.hpp Wed Jan 26 18:17:37 2011 +0100 @@ -0,0 +1,88 @@ +/* + * Copyright 2000-2010 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +class VMExits : public AllStatic { + +private: + static jobject _vmExitsPermObject; + static jobject _vmExitsPermKlass; + + static KlassHandle vmExitsKlass(); + static Handle instance(); + +public: + + // public abstract boolean setOption(String option); + static jboolean setOption(Handle option); + + // public abstract void compileMethod(long vmId, String name, int entry_bci); + static void compileMethod(jlong vmId, Handle name, int entry_bci); + + // public abstract RiMethod createRiMethodResolved(long vmId, String name); + static oop createRiMethodResolved(jlong vmId, Handle name, TRAPS); + + // public abstract RiMethod createRiMethodUnresolved(String name, String signature, RiType holder); + static oop createRiMethodUnresolved(Handle name, Handle signature, Handle holder, TRAPS); + + // public abstract RiField createRiField(RiType holder, String name, RiType type, int offset); + static oop createRiField(Handle holder, Handle name, Handle type, int index, TRAPS); + + // public abstract RiType createRiType(long vmId, String name); + static oop createRiType(jlong vmId, Handle name, TRAPS); + + // public abstract RiType createRiTypeUnresolved(String name); + static oop createRiTypeUnresolved(Handle name, TRAPS); + + // public abstract RiConstantPool createRiConstantPool(long vmId); + static oop createRiConstantPool(jlong vmId, TRAPS); + + // public abstract RiType createRiTypePrimitive(int basicType); + static oop createRiTypePrimitive(int basicType, TRAPS); + + // public abstract RiSignature createRiSignature(String signature); + static oop createRiSignature(Handle name, TRAPS); + + // public abstract CiConstant createCiConstant(CiKind kind, long value); + static oop createCiConstant(Handle kind, jlong value, TRAPS); + + // public abstract CiConstant createCiConstantFloat(float value); + static oop createCiConstantFloat(jfloat value, TRAPS); + + // public abstract CiConstant createCiConstantDouble(double value); + static oop createCiConstantDouble(jdouble value, TRAPS); + + // public abstract CiConstant createCiConstantObject(long vmId); + static oop createCiConstantObject(Handle object, TRAPS); +}; + +inline void check_pending_exception(const char* message) { + Thread* THREAD = Thread::current(); + if (THREAD->has_pending_exception()) { + Handle exception = PENDING_EXCEPTION; + CLEAR_PENDING_EXCEPTION; + java_lang_Throwable::print(exception, tty); + java_lang_Throwable::print_stack_trace(exception(), tty); + fatal(message); + } +} diff -r 102466e70deb -r 91fe28b03d6a src/share/vm/c1x/c1x_VmIds.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/vm/c1x/c1x_VmIds.cpp Wed Jan 26 18:17:37 2011 +0100 @@ -0,0 +1,85 @@ +/* + * Copyright 2000-2010 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +#include "precompiled.hpp" +#include "c1x/c1x_VmIds.hpp" + +// VmIds implementation + +GrowableArray
* VmIds::_stubs = NULL; +GrowableArray* VmIds::_localHandles = NULL; + + +void VmIds::initializeObjects() { + if (_stubs == NULL) { + assert(_localHandles == NULL, "inconsistent state"); + _stubs = new (ResourceObj::C_HEAP) GrowableArray
(64, true); + _localHandles = new (ResourceObj::C_HEAP) GrowableArray (64, true); + } + assert(_localHandles->length() == 0, "invalid state"); +} + +void VmIds::cleanupLocalObjects() { + for (int i = 0; i < _localHandles->length(); i++) { + JNIHandles::destroy_global(_localHandles->at(i)); + } + _localHandles->clear(); +} + +jlong VmIds::addStub(address stub) { + assert(!_stubs->contains(stub), "duplicate stub"); + return _stubs->append(stub) | STUB; +} + +jlong VmIds::add(Handle obj, CompilerObjectType type) { + assert(!obj.is_null(), "cannot add NULL handle"); + int idx = -1; + for (int i = 0; i < _localHandles->length(); i++) + if (JNIHandles::resolve_non_null(_localHandles->at(i)) == obj()) { + idx = i; + break; + } + if (idx == -1) { + if (JavaThread::current()->thread_state() == _thread_in_vm) { + idx = _localHandles->append(JNIHandles::make_global(obj)); + } else { + VM_ENTRY_MARK; + idx = _localHandles->append(JNIHandles::make_global(obj)); + } + } + return idx | type; +} + +address VmIds::getStub(jlong id) { + assert((id & TYPE_MASK) == STUB, "wrong id type, STUB expected"); + assert((id & ~TYPE_MASK) >= 0 && (id & ~TYPE_MASK) < _stubs->length(), "STUB index out of bounds"); + return _stubs->at(id & ~TYPE_MASK); +} + +oop VmIds::getObject(jlong id) { + assert((id & TYPE_MASK) != STUB, "wrong id type"); + assert((id & ~TYPE_MASK) >= 0 && (id & ~TYPE_MASK) < _localHandles->length(), "index out of bounds"); + return JNIHandles::resolve_non_null(_localHandles->at(id & ~TYPE_MASK)); +} + diff -r 102466e70deb -r 91fe28b03d6a src/share/vm/c1x/c1x_VmIds.hpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/vm/c1x/c1x_VmIds.hpp Wed Jan 26 18:17:37 2011 +0100 @@ -0,0 +1,158 @@ +/* + * Copyright 2000-2010 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +class VmIds : public AllStatic { + +private: + static GrowableArray
* _stubs; + static GrowableArray* _localHandles; + + static oop getObject(jlong id); + +public: + // this enum needs to have the same values as the one in HotSpotProxy.java + enum CompilerObjectType { + STUB = 0x100000000000000l, // address + METHOD = 0x200000000000000l, // methodOop + CLASS = 0x300000000000000l, // klassOop + SYMBOL = 0x400000000000000l, // symbolOop + CONSTANT_POOL = 0x500000000000000l, // constantPoolOop + CONSTANT = 0x600000000000000l, // oop + TYPE_MASK = 0xf00000000000000l, + DUMMY_CONSTANT = 0x6ffffffffffffffl + }; + + // Initializes the VmIds for a compilation, by creating the arrays + static void initializeObjects(); + // Cleans up after a compilation, by deallocating the arrays + static void cleanupLocalObjects(); + + // Adds a stub address, and returns the corresponding vmId (which is of type STUB) + static jlong addStub(address stub); + + // Adds an object, and returns the corresponding vmId (with the given type) + static jlong add(Handle obj, CompilerObjectType type); + + // Adds an object, and returns the corresponding vmId (the type of which is determined by the template parameter) + template static jlong add(T obj); + + + // Returns the stub address with the given vmId + static address getStub(jlong id); + // Returns the stub address with the given vmId taken from a java.lang.Long + static address getStub(oop id); + + // Returns the object with the given id, the return type is defined by the template parameter (which must correspond to the actual type of the vmId) + template static T get(jlong id); + + + // Helper function to convert a symbolOop to a java.lang.String object + template static T toString(symbolOop symbol, TRAPS); + + // Helper function to convert a java.lang.String object to a symbolOop (this will return NULL if the symbol doesn't exist in the system) + static symbolOop toSymbol(jstring string); + + // Helper function to get the contents of a java.lang.Long + static jlong getBoxedLong(oop obj); +}; + + +template <> inline jlong VmIds::add(methodOop obj){ + assert(obj != NULL, "trying to add NULL"); + assert(obj->is_method(), "trying to add mistyped object"); + return add(Handle(obj), METHOD); +} +template <> inline jlong VmIds::add(klassOop obj) { + assert(obj != NULL, "trying to add NULL"); + assert(obj->is_klass(), "trying to add mistyped object"); + return add(Handle(obj), CLASS); +} +template <> inline jlong VmIds::add(symbolOop obj) { + assert(obj != NULL, "trying to add NULL"); + assert(obj->is_symbol(), "trying to add mistyped object"); + return add(Handle(obj), SYMBOL); +} +template <> inline jlong VmIds::add(constantPoolOop obj) { + assert(obj != NULL, "trying to add NULL"); + assert(obj->is_constantPool(), "trying to add mistyped object"); + return add(Handle(obj), CONSTANT_POOL); +} +template <> inline jlong VmIds::add(oop obj) { + assert(obj != NULL, "trying to add NULL"); + assert(obj->is_oop(), "trying to add mistyped object"); + return add(Handle(obj), CONSTANT); +} + + +template <> inline methodOop VmIds::get(jlong id){ + assert((id & TYPE_MASK) == METHOD, "METHOD expected"); + assert(getObject(id)->is_method(), "methodOop expected"); + return (methodOop)getObject(id); +} +template <> inline klassOop VmIds::get(jlong id) { + assert((id & TYPE_MASK) == CLASS, "CLASS expected"); + assert(getObject(id)->is_klass(), "klassOop expected"); + return (klassOop)getObject(id); +} +template <> inline symbolOop VmIds::get(jlong id) { + assert((id & TYPE_MASK) == SYMBOL, "SYMBOL expected"); + assert(getObject(id)->is_symbol(), "symbolOop expected"); + return (symbolOop)getObject(id); +} +template <> inline constantPoolOop VmIds::get(jlong id) { + assert((id & TYPE_MASK) == CONSTANT_POOL, "CONSTANT_POOL expected"); + assert(getObject(id)->is_constantPool(), "constantPoolOop expected"); + return (constantPoolOop)getObject(id); +} +template <> inline oop VmIds::get(jlong id) { + assert((id & TYPE_MASK) == CONSTANT, "CONSTANT expected"); + assert(getObject(id)->is_oop(true), "oop expected"); + return (oop)getObject(id); +} + +inline address VmIds::getStub(oop obj) { + return getStub(getBoxedLong(obj)); +} + +template <> inline Handle VmIds::toString(symbolOop symbol, TRAPS) { + return java_lang_String::create_from_symbol(symbol, THREAD); +} +template <> inline oop VmIds::toString(symbolOop symbol, TRAPS) { + return toString(symbol, THREAD)(); +} +template <> inline jstring VmIds::toString(symbolOop symbol, TRAPS) { + return (jstring)JNIHandles::make_local(toString(symbol, THREAD)); +} +template <> inline jobject VmIds::toString(symbolOop symbol, TRAPS) { + return JNIHandles::make_local(toString(symbol, THREAD)); +} + +inline symbolOop VmIds::toSymbol(jstring string) { + return java_lang_String::as_symbol_or_null(JNIHandles::resolve(string)); +} + +inline jlong VmIds::getBoxedLong(oop obj) { + assert(obj->is_oop(true), "cannot unbox null or non-oop"); + return obj->long_field(java_lang_boxing_object::value_offset_in_bytes(T_LONG)); +} diff -r 102466e70deb -r 91fe28b03d6a src/share/vm/ci/ciEnv.cpp --- a/src/share/vm/ci/ciEnv.cpp Thu Jan 20 15:52:05 2011 -0800 +++ b/src/share/vm/ci/ciEnv.cpp Wed Jan 26 18:17:37 2011 +0100 @@ -201,6 +201,7 @@ } ciEnv::~ciEnv() { + _factory->cleanup(); CompilerThread* current_thread = CompilerThread::current(); current_thread->set_env(NULL); } diff -r 102466e70deb -r 91fe28b03d6a src/share/vm/ci/ciEnv.hpp --- a/src/share/vm/ci/ciEnv.hpp Thu Jan 20 15:52:05 2011 -0800 +++ b/src/share/vm/ci/ciEnv.hpp Wed Jan 26 18:17:37 2011 +0100 @@ -106,6 +106,8 @@ ciInstance* _the_null_string; // The Java string "null" ciInstance* _the_min_jint_string; // The Java string "-2147483648" +public: + // Look up a klass by name from a particular class loader (the accessor's). // If require_local, result must be defined in that class loader, or NULL. // If !require_local, a result from remote class loader may be reported, @@ -136,6 +138,8 @@ int method_index, Bytecodes::Code bc, ciInstanceKlass* loading_klass); +private: + // Implementation methods for loading and constant pool access. ciKlass* get_klass_by_name_impl(ciKlass* accessing_klass, ciSymbol* klass_name, @@ -164,6 +168,7 @@ symbolOop sig, Bytecodes::Code bc); + public: // Get a ciObject from the object factory. Ensures uniqueness // of ciObjects. ciObject* get_object(oop o) { @@ -173,6 +178,7 @@ return _factory->get(o); } } + private: ciMethod* get_method_from_handle(jobject method); diff -r 102466e70deb -r 91fe28b03d6a src/share/vm/ci/ciField.cpp --- a/src/share/vm/ci/ciField.cpp Thu Jan 20 15:52:05 2011 -0800 +++ b/src/share/vm/ci/ciField.cpp Wed Jan 26 18:17:37 2011 +0100 @@ -303,15 +303,20 @@ return type; } +bool ciField::will_link(ciInstanceKlass* accessing_klass, + Bytecodes::Code bc) { + VM_ENTRY_MARK; + return will_link_from_vm(accessing_klass, bc); +} // ------------------------------------------------------------------ // ciField::will_link // // Can a specific access to this field be made without causing // link errors? -bool ciField::will_link(ciInstanceKlass* accessing_klass, +bool ciField::will_link_from_vm(ciInstanceKlass* accessing_klass, Bytecodes::Code bc) { - VM_ENTRY_MARK; + Thread* THREAD = Thread::current(); if (_offset == -1) { // at creation we couldn't link to our holder so we need to // maintain that stance, otherwise there's no safe way to use this diff -r 102466e70deb -r 91fe28b03d6a src/share/vm/ci/ciField.hpp --- a/src/share/vm/ci/ciField.hpp Thu Jan 20 15:52:05 2011 -0800 +++ b/src/share/vm/ci/ciField.hpp Wed Jan 26 18:17:37 2011 +0100 @@ -168,6 +168,8 @@ // at each point of access. bool will_link(ciInstanceKlass* accessing_klass, Bytecodes::Code bc); + bool will_link_from_vm(ciInstanceKlass* accessing_klass, + Bytecodes::Code bc); // Java access flags bool is_public () { return flags().is_public(); } diff -r 102466e70deb -r 91fe28b03d6a src/share/vm/ci/ciInstanceKlass.cpp --- a/src/share/vm/ci/ciInstanceKlass.cpp Thu Jan 20 15:52:05 2011 -0800 +++ b/src/share/vm/ci/ciInstanceKlass.cpp Wed Jan 26 18:17:37 2011 +0100 @@ -63,17 +63,16 @@ } Thread *thread = Thread::current(); - if (ciObjectFactory::is_initialized()) { + if (ciObjectFactory::is_initialized() && !UseC1X) { _loader = JNIHandles::make_local(thread, ik->class_loader()); - _protection_domain = JNIHandles::make_local(thread, - ik->protection_domain()); + _protection_domain = JNIHandles::make_local(thread, ik->protection_domain()); _is_shared = false; } else { Handle h_loader(thread, ik->class_loader()); Handle h_protection_domain(thread, ik->protection_domain()); _loader = JNIHandles::make_global(h_loader); _protection_domain = JNIHandles::make_global(h_protection_domain); - _is_shared = true; + _is_shared = !ciObjectFactory::is_initialized(); } // Lazy fields get filled in only upon request. diff -r 102466e70deb -r 91fe28b03d6a src/share/vm/ci/ciInstanceKlass.hpp --- a/src/share/vm/ci/ciInstanceKlass.hpp Thu Jan 20 15:52:05 2011 -0800 +++ b/src/share/vm/ci/ciInstanceKlass.hpp Wed Jan 26 18:17:37 2011 +0100 @@ -71,6 +71,19 @@ GrowableArray* _non_static_fields; +public: + virtual void cleanup() { + ciObject::cleanup(); + if (!_is_shared) { + if (JNIHandles::is_global_handle(_loader)) { + JNIHandles::destroy_global(_loader); + } + if (JNIHandles::is_global_handle(_protection_domain)) { + JNIHandles::destroy_global(_protection_domain); + } + } + } + protected: ciInstanceKlass(KlassHandle h_k); ciInstanceKlass(ciSymbol* name, jobject loader, jobject protection_domain); diff -r 102466e70deb -r 91fe28b03d6a src/share/vm/ci/ciObject.cpp --- a/src/share/vm/ci/ciObject.cpp Thu Jan 20 15:52:05 2011 -0800 +++ b/src/share/vm/ci/ciObject.cpp Wed Jan 26 18:17:37 2011 +0100 @@ -52,13 +52,19 @@ ciObject::ciObject(oop o) { ASSERT_IN_VM; if (ciObjectFactory::is_initialized()) { - _handle = JNIHandles::make_local(o); + if (UseC1X) { + _handle = JNIHandles::make_global(o); + _temp_global = true; + } else { + _handle = JNIHandles::make_local(o); + } } else { _handle = JNIHandles::make_global(o); } _klass = NULL; _ident = 0; init_flags_from(o); + _temp_global = false; } // ------------------------------------------------------------------ @@ -67,13 +73,19 @@ ciObject::ciObject(Handle h) { ASSERT_IN_VM; if (ciObjectFactory::is_initialized()) { - _handle = JNIHandles::make_local(h()); + if (UseC1X) { + _handle = JNIHandles::make_global(h); + _temp_global = true; + } else { + _handle = JNIHandles::make_local(h()); + } } else { _handle = JNIHandles::make_global(h); } _klass = NULL; _ident = 0; init_flags_from(h()); + _temp_global = false; } // ------------------------------------------------------------------ @@ -87,6 +99,7 @@ _handle = NULL; _klass = klass; _ident = 0; + _temp_global = false; } // ------------------------------------------------------------------ @@ -98,6 +111,7 @@ _handle = NULL; _klass = NULL; _ident = 0; + _temp_global = false; } // ------------------------------------------------------------------ diff -r 102466e70deb -r 91fe28b03d6a src/share/vm/ci/ciObject.hpp --- a/src/share/vm/ci/ciObject.hpp Thu Jan 20 15:52:05 2011 -0800 +++ b/src/share/vm/ci/ciObject.hpp Wed Jan 26 18:17:37 2011 +0100 @@ -58,6 +58,7 @@ jobject _handle; ciKlass* _klass; uint _ident; + bool _temp_global; enum { FLAG_BITS = 2 }; enum { @@ -70,12 +71,19 @@ ciObject(Handle h); ciObject(ciKlass* klass); +public: + virtual void cleanup() { + if (_temp_global && _handle != NULL && JNIHandles::is_global_handle(_handle)) { + JNIHandles::destroy_global(_handle); + } + } jobject handle() const { return _handle; } // Get the VM oop that this object holds. oop get_oop() const { assert(_handle != NULL, "null oop"); return JNIHandles::resolve_non_null(_handle); } +protected: void init_flags_from(oop x) { int flags = 0; diff -r 102466e70deb -r 91fe28b03d6a src/share/vm/ci/ciObjectFactory.cpp --- a/src/share/vm/ci/ciObjectFactory.cpp Thu Jan 20 15:52:05 2011 -0800 +++ b/src/share/vm/ci/ciObjectFactory.cpp Wed Jan 26 18:17:37 2011 +0100 @@ -100,6 +100,14 @@ new (arena) GrowableArray(arena, 8, 0, NULL); } +void ciObjectFactory::cleanup() { + int start = 0; + if (_shared_ci_objects != NULL) start = _shared_ci_objects->length(); + for (int i = start; i < _ci_objects->length(); ++i) { + _ci_objects->at(i)->cleanup(); + } +} + // ------------------------------------------------------------------ // ciObjectFactory::ciObjectFactory void ciObjectFactory::initialize() { diff -r 102466e70deb -r 91fe28b03d6a src/share/vm/ci/ciObjectFactory.hpp --- a/src/share/vm/ci/ciObjectFactory.hpp Thu Jan 20 15:52:05 2011 -0800 +++ b/src/share/vm/ci/ciObjectFactory.hpp Wed Jan 26 18:17:37 2011 +0100 @@ -91,6 +91,7 @@ ciObjectFactory(Arena* arena, int expected_size); + void cleanup(); // Get the ciObject corresponding to some oop. ciObject* get(oop key); diff -r 102466e70deb -r 91fe28b03d6a src/share/vm/ci/ciSymbol.hpp --- a/src/share/vm/ci/ciSymbol.hpp Thu Jan 20 15:52:05 2011 -0800 +++ b/src/share/vm/ci/ciSymbol.hpp Wed Jan 26 18:17:37 2011 +0100 @@ -50,8 +50,10 @@ ciSymbol(symbolOop s); // normal case, for symbols not mentioned in vmSymbols ciSymbol(symbolHandle s, vmSymbols::SID sid); // for use with vmSymbolHandles +public: symbolOop get_symbolOop() const { return (symbolOop)get_oop(); } +private: const char* type_string() { return "ciSymbol"; } void print_impl(outputStream* st); diff -r 102466e70deb -r 91fe28b03d6a src/share/vm/classfile/classLoader.cpp diff -r 102466e70deb -r 91fe28b03d6a src/share/vm/classfile/systemDictionary.cpp --- a/src/share/vm/classfile/systemDictionary.cpp Thu Jan 20 15:52:05 2011 -0800 +++ b/src/share/vm/classfile/systemDictionary.cpp Wed Jan 26 18:17:37 2011 +0100 @@ -190,7 +190,8 @@ // Forwards to resolve_instance_class_or_null klassOop SystemDictionary::resolve_or_null(symbolHandle class_name, Handle class_loader, Handle protection_domain, TRAPS) { - assert(!THREAD->is_Compiler_thread(), "Can not load classes with the Compiler thread"); + // (tw) May we do this? + // assert(!THREAD->is_Compiler_thread(), "Can not load classes with the Compiler thread"); if (FieldType::is_array(class_name())) { return resolve_array_class_or_null(class_name, class_loader, protection_domain, CHECK_NULL); } else { @@ -2381,8 +2382,9 @@ if (spe == NULL || spe->property_oop() == NULL) { spe = NULL; // Must create lots of stuff here, but outside of the SystemDictionary lock. - if (THREAD->is_Compiler_thread()) - return NULL; // do not attempt from within compiler + // (tw) May we do this? + //if (THREAD->is_Compiler_thread()) + // return NULL; // do not attempt from within compiler bool for_invokeGeneric = (name_id == vmSymbols::VM_SYMBOL_ENUM_NAME(invokeGeneric_name)); bool found_on_bcp = false; Handle mt = find_method_handle_type(signature(), accessing_klass, diff -r 102466e70deb -r 91fe28b03d6a src/share/vm/classfile/systemDictionary.hpp --- a/src/share/vm/classfile/systemDictionary.hpp Thu Jan 20 15:52:05 2011 -0800 +++ b/src/share/vm/classfile/systemDictionary.hpp Wed Jan 26 18:17:37 2011 +0100 @@ -181,6 +181,39 @@ template(Short_klass, java_lang_Short, Pre) \ template(Integer_klass, java_lang_Integer, Pre) \ template(Long_klass, java_lang_Long, Pre) \ + \ + template(C1XOptions_klass, com_sun_c1x_C1XOptions, Opt) \ + template(HotSpotTypeResolved_klass, com_sun_hotspot_c1x_HotSpotTypeResolved, Opt) \ + template(HotSpotType_klass, com_sun_hotspot_c1x_HotSpotType, Opt) \ + template(HotSpotField_klass, com_sun_hotspot_c1x_HotSpotField, Opt) \ + template(HotSpotMethodResolved_klass, com_sun_hotspot_c1x_HotSpotMethodResolved, Opt) \ + template(HotSpotTargetMethod_klass, com_sun_hotspot_c1x_HotSpotTargetMethod, Opt) \ + template(HotSpotExceptionHandler_klass,com_sun_hotspot_c1x_HotSpotExceptionHandler, Opt) \ + template(HotSpotProxy_klass, com_sun_hotspot_c1x_HotSpotProxy, Opt) \ + template(CiAssumptions_klass, com_sun_cri_ci_CiAssumptions, Opt) \ + template(CiAssumptions_ConcreteSubtype_klass, com_sun_cri_ci_CiAssumptions_ConcreteSubtype, Opt) \ + template(CiAssumptions_ConcreteMethod_klass, com_sun_cri_ci_CiAssumptions_ConcreteMethod, Opt) \ + template(CiTargetMethod_klass, com_sun_cri_ci_CiTargetMethod, Opt) \ + template(CiTargetMethod_Site_klass, com_sun_cri_ci_CiTargetMethod_Site, Opt) \ + template(CiTargetMethod_Call_klass, com_sun_cri_ci_CiTargetMethod_Call, Opt) \ + template(CiTargetMethod_DataPatch_klass, com_sun_cri_ci_CiTargetMethod_DataPatch, Opt) \ + template(CiTargetMethod_Safepoint_klass, com_sun_cri_ci_CiTargetMethod_Safepoint, Opt) \ + template(CiTargetMethod_ExceptionHandler_klass, com_sun_cri_ci_CiTargetMethod_ExceptionHandler, Opt) \ + template(CiTargetMethod_Mark_klass, com_sun_cri_ci_CiTargetMethod_Mark, Opt) \ + template(CiBitMap_klass, com_sun_cri_ci_CiBitMap, Opt) \ + template(CiDebugInfo_klass, com_sun_cri_ci_CiDebugInfo, Opt) \ + template(CiDebugInfo_Frame_klass, com_sun_cri_ci_CiDebugInfo_Frame, Opt) \ + template(CiValue_klass, com_sun_cri_ci_CiValue, Opt) \ + template(CiStackSlot_klass, com_sun_cri_ci_CiStackSlot, Opt) \ + template(CiRegisterValue_klass, com_sun_cri_ci_CiRegisterValue, Opt) \ + template(CiRegister_klass, com_sun_cri_ci_CiRegister, Opt) \ + template(CiCodePos_klass, com_sun_cri_ci_CiCodePos, Opt) \ + template(CiConstant_klass, com_sun_cri_ci_CiConstant, Opt) \ + template(CiKind_klass, com_sun_cri_ci_CiKind, Opt) \ + template(CiRuntimeCall_klass, com_sun_cri_ci_CiRuntimeCall, Opt) \ + template(RiMethod_klass, com_sun_cri_ri_RiMethod, Opt) \ + template(RiExceptionHandler_klass, com_sun_cri_ri_RiExceptionHandler, Opt) \ + /*end*/ diff -r 102466e70deb -r 91fe28b03d6a src/share/vm/classfile/vmSymbols.hpp --- a/src/share/vm/classfile/vmSymbols.hpp Thu Jan 20 15:52:05 2011 -0800 +++ b/src/share/vm/classfile/vmSymbols.hpp Wed Jan 26 18:17:37 2011 +0100 @@ -260,7 +260,75 @@ template(makeDynamicCallSite_signature, "(Ljava/dyn/MethodHandle;Ljava/lang/String;Ljava/dyn/MethodType;Ljava/lang/Object;Lsun/dyn/MemberName;I)Ljava/dyn/CallSite;") \ NOT_LP64( do_alias(machine_word_signature, int_signature) ) \ LP64_ONLY( do_alias(machine_word_signature, long_signature) ) \ - \ + \ + /* support for C1X */ \ + template(com_sun_hotspot_c1x_VMExits, "com/sun/hotspot/c1x/VMExits") \ + template(com_sun_hotspot_c1x_HotSpotMethodResolved, "com/sun/hotspot/c1x/HotSpotMethodResolved") \ + template(com_sun_hotspot_c1x_HotSpotTargetMethod, "com/sun/hotspot/c1x/HotSpotTargetMethod") \ + template(com_sun_hotspot_c1x_HotSpotField, "com/sun/hotspot/c1x/HotSpotField") \ + template(com_sun_c1x_C1XOptions, "com/sun/c1x/C1XOptions") \ + template(com_sun_hotspot_c1x_HotSpotTypeResolved, "com/sun/hotspot/c1x/HotSpotTypeResolved") \ + template(com_sun_hotspot_c1x_HotSpotType, "com/sun/hotspot/c1x/HotSpotType") \ + template(com_sun_hotspot_c1x_HotSpotExceptionHandler,"com/sun/hotspot/c1x/HotSpotExceptionHandler") \ + template(com_sun_hotspot_c1x_HotSpotProxy, "com/sun/hotspot/c1x/HotSpotProxy") \ + template(com_sun_hotspot_c1x_Compiler, "com/sun/hotspot/c1x/Compiler") \ + template(com_sun_cri_ri_RiMethod, "com/sun/cri/ri/RiMethod") \ + template(com_sun_cri_ri_RiField, "com/sun/cri/ri/RiField") \ + template(com_sun_cri_ri_RiType, "com/sun/cri/ri/RiType") \ + template(com_sun_cri_ri_RiConstantPool, "com/sun/cri/ri/RiConstantPool") \ + template(com_sun_cri_ri_RiExceptionHandler, "com/sun/cri/ri/RiExceptionHandler") \ + template(com_sun_cri_ci_CiAssumptions, "com/sun/cri/ci/CiAssumptions") \ + template(com_sun_cri_ci_CiAssumptions_ConcreteSubtype, "com/sun/cri/ci/CiAssumptions$ConcreteSubtype") \ + template(com_sun_cri_ci_CiAssumptions_ConcreteMethod, "com/sun/cri/ci/CiAssumptions$ConcreteMethod") \ + template(com_sun_cri_ci_CiTargetMethod, "com/sun/cri/ci/CiTargetMethod") \ + template(com_sun_cri_ci_CiTargetMethod_Site, "com/sun/cri/ci/CiTargetMethod$Site") \ + template(com_sun_cri_ci_CiTargetMethod_Call, "com/sun/cri/ci/CiTargetMethod$Call") \ + template(com_sun_cri_ci_CiTargetMethod_DataPatch, "com/sun/cri/ci/CiTargetMethod$DataPatch") \ + template(com_sun_cri_ci_CiTargetMethod_Safepoint, "com/sun/cri/ci/CiTargetMethod$Safepoint") \ + template(com_sun_cri_ci_CiTargetMethod_ExceptionHandler, "com/sun/cri/ci/CiTargetMethod$ExceptionHandler") \ + template(com_sun_cri_ci_CiTargetMethod_Mark, "com/sun/cri/ci/CiTargetMethod$Mark") \ + template(com_sun_cri_ci_CiBitMap, "com/sun/cri/ci/CiBitMap") \ + template(com_sun_cri_ci_CiDebugInfo, "com/sun/cri/ci/CiDebugInfo") \ + template(com_sun_cri_ci_CiDebugInfo_Frame, "com/sun/cri/ci/CiDebugInfo$Frame") \ + template(com_sun_cri_ci_CiValue, "com/sun/cri/ci/CiValue") \ + template(com_sun_cri_ci_CiStackSlot, "com/sun/cri/ci/CiStackSlot") \ + template(com_sun_cri_ci_CiRegisterValue, "com/sun/cri/ci/CiRegisterValue") \ + template(com_sun_cri_ci_CiRegister, "com/sun/cri/ci/CiRegister") \ + template(com_sun_cri_ci_CiCodePos, "com/sun/cri/ci/CiCodePos") \ + template(com_sun_cri_ci_CiConstant, "com/sun/cri/ci/CiConstant") \ + template(com_sun_cri_ci_CiKind, "com/sun/cri/ci/CiKind") \ + template(com_sun_cri_ci_CiRuntimeCall, "com/sun/cri/ci/CiRuntimeCall") \ + template(compileMethod_name, "compileMethod") \ + template(compileMethod_signature, "(JLjava/lang/String;I)V") \ + template(setOption_name, "setOption") \ + template(setOption_signature, "(Ljava/lang/String;)Z") \ + template(createRiMethodResolved_name, "createRiMethodResolved") \ + template(createRiMethodResolved_signature, "(JLjava/lang/String;)Lcom/sun/cri/ri/RiMethod;") \ + template(createRiMethodUnresolved_name, "createRiMethodUnresolved") \ + template(createRiMethodUnresolved_signature, "(Ljava/lang/String;Ljava/lang/String;Lcom/sun/cri/ri/RiType;)Lcom/sun/cri/ri/RiMethod;") \ + template(createRiSignature_name, "createRiSignature") \ + template(createRiSignature_signature, "(Ljava/lang/String;)Lcom/sun/cri/ri/RiSignature;") \ + template(createRiField_name, "createRiField") \ + template(createRiField_signature, "(Lcom/sun/cri/ri/RiType;Ljava/lang/String;Lcom/sun/cri/ri/RiType;I)Lcom/sun/cri/ri/RiField;") \ + template(createRiType_name, "createRiType") \ + template(createRiType_signature, "(JLjava/lang/String;)Lcom/sun/cri/ri/RiType;") \ + template(createRiTypePrimitive_name, "createRiTypePrimitive") \ + template(createRiTypePrimitive_signature, "(I)Lcom/sun/cri/ri/RiType;") \ + template(createRiTypeUnresolved_name, "createRiTypeUnresolved") \ + template(createRiTypeUnresolved_signature, "(Ljava/lang/String;)Lcom/sun/cri/ri/RiType;") \ + template(createRiConstantPool_name, "createRiConstantPool") \ + template(createRiConstantPool_signature, "(J)Lcom/sun/cri/ri/RiConstantPool;") \ + template(createCiConstant_name, "createCiConstant") \ + template(createCiConstant_signature, "(Lcom/sun/cri/ci/CiKind;J)Lcom/sun/cri/ci/CiConstant;") \ + template(createCiConstantFloat_name, "createCiConstantFloat") \ + template(createCiConstantFloat_signature, "(F)Lcom/sun/cri/ci/CiConstant;") \ + template(createCiConstantDouble_name, "createCiConstantDouble") \ + template(createCiConstantDouble_signature, "(D)Lcom/sun/cri/ci/CiConstant;") \ + template(createCiConstantObject_name, "createCiConstantObject") \ + template(createCiConstantObject_signature, "(Ljava/lang/Object;)Lcom/sun/cri/ci/CiConstant;") \ + template(getVMExits_name, "getVMExits") \ + template(getVMExits_signature, "()Lcom/sun/hotspot/c1x/VMExits;") \ + \ /* common method and field names */ \ template(object_initializer_name, "") \ template(class_initializer_name, "") \ @@ -355,6 +423,7 @@ template(erasedType_name, "erasedType") \ template(genericInvoker_name, "genericInvoker") \ template(append_name, "append") \ + template(id_name, "id") \ \ /* non-intrinsic name/signature pairs: */ \ template(register_method_name, "register") \ diff -r 102466e70deb -r 91fe28b03d6a src/share/vm/code/codeBlob.hpp --- a/src/share/vm/code/codeBlob.hpp Thu Jan 20 15:52:05 2011 -0800 +++ b/src/share/vm/code/codeBlob.hpp Wed Jan 26 18:17:37 2011 +0100 @@ -352,6 +352,10 @@ int _unpack_with_exception_in_tls; + // (tw) Offset when C1X calls uncommon_trap. + int _uncommon_trap_offset; + + // Creation support DeoptimizationBlob( CodeBuffer* cb, @@ -407,6 +411,14 @@ assert(code_contains(code_begin() + _unpack_with_exception_in_tls), "must be PC inside codeblob"); } address unpack_with_exception_in_tls() const { return code_begin() + _unpack_with_exception_in_tls; } + + // (tw) Offset when C1X calls uncommon_trap. + void set_uncommon_trap_offset(int offset) { + _uncommon_trap_offset = offset; + assert(contains(code_begin() + _uncommon_trap_offset), "must be PC inside codeblob"); + } + address uncommon_trap() const { return code_begin() + _uncommon_trap_offset; } + }; diff -r 102466e70deb -r 91fe28b03d6a src/share/vm/code/compiledIC.cpp --- a/src/share/vm/code/compiledIC.cpp Thu Jan 20 15:52:05 2011 -0800 +++ b/src/share/vm/code/compiledIC.cpp Wed Jan 26 18:17:37 2011 +0100 @@ -529,7 +529,7 @@ NativeJump* jump = nativeJump_at(method_holder->next_instruction_address()); assert(method_holder->data() == 0 || method_holder->data() == (intptr_t)callee(), "a) MT-unsafe modification of inline cache"); - assert(jump->jump_destination() == (address)-1 || jump->jump_destination() == entry, "b) MT-unsafe modification of inline cache"); + assert(UseC1X || jump->jump_destination() == (address)-1 || jump->jump_destination() == entry, "b) MT-unsafe modification of inline cache"); // Update stub method_holder->set_data((intptr_t)callee()); diff -r 102466e70deb -r 91fe28b03d6a src/share/vm/code/nmethod.cpp --- a/src/share/vm/code/nmethod.cpp Thu Jan 20 15:52:05 2011 -0800 +++ b/src/share/vm/code/nmethod.cpp Wed Jan 26 18:17:37 2011 +0100 @@ -813,12 +813,23 @@ // Exception handler and deopt handler are in the stub section assert(offsets->value(CodeOffsets::Exceptions) != -1, "must be set"); assert(offsets->value(CodeOffsets::Deopt ) != -1, "must be set"); - _exception_offset = _stub_offset + offsets->value(CodeOffsets::Exceptions); - _deoptimize_offset = _stub_offset + offsets->value(CodeOffsets::Deopt); - if (offsets->value(CodeOffsets::DeoptMH) != -1) { - _deoptimize_mh_offset = _stub_offset + offsets->value(CodeOffsets::DeoptMH); + if (UseC1X) { + // c1x produces no (!) stub section + _exception_offset = code_offset() + offsets->value(CodeOffsets::Exceptions); + _deoptimize_offset = code_offset() + offsets->value(CodeOffsets::Deopt); + if (offsets->value(CodeOffsets::DeoptMH) != -1) { + _deoptimize_mh_offset = code_offset() + offsets->value(CodeOffsets::DeoptMH); + } else { + _deoptimize_mh_offset = -1; + } } else { - _deoptimize_mh_offset = -1; + _exception_offset = _stub_offset + offsets->value(CodeOffsets::Exceptions); + _deoptimize_offset = _stub_offset + offsets->value(CodeOffsets::Deopt); + if (offsets->value(CodeOffsets::DeoptMH) != -1) { + _deoptimize_mh_offset = _stub_offset + offsets->value(CodeOffsets::DeoptMH); + } else { + _deoptimize_mh_offset = -1; + } } if (offsets->value(CodeOffsets::UnwindHandler) != -1) { _unwind_handler_offset = code_offset() + offsets->value(CodeOffsets::UnwindHandler); @@ -1108,6 +1119,12 @@ ScopeDesc* nmethod::scope_desc_at(address pc) { PcDesc* pd = pc_desc_at(pc); +#ifdef ASSERT + if (pd == NULL) { + tty->print_cr(err_msg("Missing scope at relative pc %d of method %s", pc - code_begin(), this->method()->name()->as_C_string())); + print_pcs(); + } +#endif guarantee(pd != NULL, "scope must be present"); return new ScopeDesc(this, pd->scope_decode_offset(), pd->obj_decode_offset(), pd->should_reexecute(), @@ -2320,7 +2337,7 @@ // information in a table. break; } - assert(stub == NULL || stub_contains(stub), "static call stub outside stub section"); + assert(UseC1X || stub == NULL || stub_contains(stub), "static call stub outside stub section"); } } @@ -2562,6 +2579,7 @@ if (block_begin == entry_point()) stream->print_cr("[Entry Point]"); if (block_begin == verified_entry_point()) stream->print_cr("[Verified Entry Point]"); if (block_begin == exception_begin()) stream->print_cr("[Exception Handler]"); + if (block_begin == unwind_handler_begin()) stream->print_cr("[Unwind Handler]"); if (block_begin == stub_begin()) stream->print_cr("[Stub Code]"); if (block_begin == deopt_handler_begin()) stream->print_cr("[Deopt Handler Code]"); diff -r 102466e70deb -r 91fe28b03d6a src/share/vm/code/nmethod.hpp --- a/src/share/vm/code/nmethod.hpp Thu Jan 20 15:52:05 2011 -0800 +++ b/src/share/vm/code/nmethod.hpp Wed Jan 26 18:17:37 2011 +0100 @@ -587,7 +587,10 @@ // Deopt // Return true is the PC is one would expect if the frame is being deopted. bool is_deopt_pc (address pc) { return is_deopt_entry(pc) || is_deopt_mh_entry(pc); } - bool is_deopt_entry (address pc) { return pc == deopt_handler_begin(); } + + // (tw) When using C1X, the address might be off by 5 (because this is the size of the call instruction. + // (tw) TODO: Replace this by a more general mechanism. + bool is_deopt_entry (address pc) { return pc == deopt_handler_begin() || (UseC1X && pc == deopt_handler_begin() + 5); } bool is_deopt_mh_entry(address pc) { return pc == deopt_mh_handler_begin(); } // Accessor/mutator for the original pc of a frame before a frame was deopted. address get_original_pc(const frame* fr) { return *orig_pc_addr(fr); } diff -r 102466e70deb -r 91fe28b03d6a src/share/vm/code/pcDesc.cpp --- a/src/share/vm/code/pcDesc.cpp Thu Jan 20 15:52:05 2011 -0800 +++ b/src/share/vm/code/pcDesc.cpp Wed Jan 26 18:17:37 2011 +0100 @@ -44,7 +44,7 @@ void PcDesc::print(nmethod* code) { #ifndef PRODUCT ResourceMark rm; - tty->print_cr("PcDesc(pc=0x%lx offset=%x):", real_pc(code), pc_offset()); + tty->print_cr("PcDesc(pc=0x%lx offset=%d):", real_pc(code), pc_offset()); if (scope_decode_offset() == DebugInformationRecorder::serialized_null) { return; diff -r 102466e70deb -r 91fe28b03d6a src/share/vm/compiler/abstractCompiler.hpp --- a/src/share/vm/compiler/abstractCompiler.hpp Thu Jan 20 15:52:05 2011 -0800 +++ b/src/share/vm/compiler/abstractCompiler.hpp Wed Jan 26 18:17:37 2011 +0100 @@ -72,9 +72,6 @@ #endif // SHARK #endif // TIERED - // Customization - virtual bool needs_stubs () = 0; - void mark_initialized() { _is_initialized = true; } bool is_initialized() { return _is_initialized; } diff -r 102466e70deb -r 91fe28b03d6a src/share/vm/compiler/compileBroker.cpp --- a/src/share/vm/compiler/compileBroker.cpp Thu Jan 20 15:52:05 2011 -0800 +++ b/src/share/vm/compiler/compileBroker.cpp Wed Jan 26 18:17:37 2011 +0100 @@ -44,6 +44,7 @@ #include "runtime/sharedRuntime.hpp" #include "runtime/sweeper.hpp" #include "utilities/dtrace.hpp" +#include "c1x/c1x_Compiler.hpp" #ifdef COMPILER1 #include "c1/c1_Compiler.hpp" #endif @@ -491,6 +492,9 @@ assert(task == _last, "Sanity"); _last = task->prev(); } + + // (tw) Immediately set compiling flag. + JavaThread::current()->as_CompilerThread()->set_compiling(true); --_size; } @@ -544,6 +548,74 @@ } } +// Bootstrap the C1X compiler. Compiles all methods until compile queue is empty and no compilation is active. +void CompileBroker::bootstrap_c1x() { + HandleMark hm; + Thread* THREAD = Thread::current(); + tty->print_cr("Bootstrapping C1X..."); + + C1XCompiler* compiler = C1XCompiler::instance(); + if (compiler == NULL) fatal("must use flag -XX:+UseC1X"); + + jlong start = os::javaTimeMillis(); + + instanceKlass* klass = (instanceKlass*)SystemDictionary::Object_klass()->klass_part(); + methodOop method = klass->find_method(vmSymbols::object_initializer_name(), vmSymbols::void_method_signature()); + CompileBroker::compile_method(method, -1, 0, method, 0, "initial compile of object initializer", THREAD); + if (HAS_PENDING_EXCEPTION) { + CLEAR_PENDING_EXCEPTION; + fatal("error inserting object initializer into compile queue"); + } + + int z = 0; + while (true) { + { + HandleMark hm; + ResourceMark rm; + MutexLocker locker(_c1_method_queue->lock(), Thread::current()); + if (_c1_method_queue->is_empty()) { + MutexLocker mu(Threads_lock); // grab Threads_lock + JavaThread* current = Threads::first(); + bool compiling = false; + while (current != NULL) { + if (current->is_Compiler_thread()) { + CompilerThread* comp_thread = current->as_CompilerThread(); + if (comp_thread->is_compiling()) { + if (TraceC1X >= 4) { + tty->print_cr("Compile queue empty, but following thread is still compiling:"); + comp_thread->print(); + } + compiling = true; + } + } + current = current->next(); + } + if (!compiling) { + break; + } + } + if (TraceC1X >= 5) { + _c1_method_queue->print(); + } + } + + { + ThreadToNativeFromVM trans(JavaThread::current()); + usleep(1000); + } + ++z; + } + + // Do a full garbage collection. + Universe::heap()->collect(GCCause::_java_lang_system_gc); + + jlong diff = os::javaTimeMillis() - start; + tty->print_cr("Finished bootstrap in %d ms", diff); + if (CITime) CompileBroker::print_times(); + tty->print_cr("==========================================================================="); +} + + // ------------------------------------------------------------------ // CompileBroker::compilation_init // @@ -556,9 +628,14 @@ int c1_count = CompilationPolicy::policy()->compiler_count(CompLevel_simple); int c2_count = CompilationPolicy::policy()->compiler_count(CompLevel_full_optimization); #ifdef COMPILER1 - if (c1_count > 0) { - _compilers[0] = new Compiler(); + if (UseC1X) { + _compilers[0] = new C1XCompiler(); + } else if (c1_count > 0) { + _compilers[0] = new Compiler(); } +#ifndef COMPILER2 + _compilers[1] = _compilers[0]; +#endif #endif // COMPILER1 #ifdef COMPILER2 @@ -896,6 +973,13 @@ { MutexLocker locker(queue->lock(), THREAD); + if (Thread::current()->is_Compiler_thread() && CompilerThread::current()->is_compiling() && !BackgroundCompilation) { + + TRACE_C1X_1("Recursive compile %s!", method->name_and_sig_as_C_string()); + method->set_not_compilable(); + return; + } + // Make sure the method has not slipped into the queues since // last we checked; note that those checks were "fast bail-outs". // Here we need to be more careful, see 14012000 below. @@ -1349,6 +1433,9 @@ while (true) { { + // Unset compiling flag. + thread->set_compiling(false); + // We need this HandleMark to avoid leaking VM handles. HandleMark hm(thread); @@ -1492,6 +1579,7 @@ void CompileBroker::invoke_compiler_on_method(CompileTask* task) { if (PrintCompilation) { ResourceMark rm; + tty->print("%s: ", compiler(task->comp_level())->name()); task->print_line(); } elapsedTimer time; @@ -1527,15 +1615,17 @@ // Allocate a new set of JNI handles. push_jni_handle_block(); jobject target_handle = JNIHandles::make_local(thread, JNIHandles::resolve(task->method_handle())); - int compilable = ciEnv::MethodCompilable; - { + int compilable = ciEnv::MethodCompilable_never; + if (MaxCompilationID == -1 || compile_id <= (uint)MaxCompilationID) { + compilable = ciEnv::MethodCompilable; int system_dictionary_modification_counter; { MutexLocker locker(Compile_lock, thread); system_dictionary_modification_counter = SystemDictionary::number_of_modifications(); } - NoHandleMark nhm; + // (tw) Check if we may do this? + // NoHandleMark nhm; ThreadToNativeFromVM ttn(thread); ciEnv ci_env(task, system_dictionary_modification_counter); diff -r 102466e70deb -r 91fe28b03d6a src/share/vm/compiler/compileBroker.hpp --- a/src/share/vm/compiler/compileBroker.hpp Thu Jan 20 15:52:05 2011 -0800 +++ b/src/share/vm/compiler/compileBroker.hpp Wed Jan 26 18:17:37 2011 +0100 @@ -386,6 +386,8 @@ static void print_last_compile(); static void print_compiler_threads_on(outputStream* st); + + static void bootstrap_c1x(); }; #endif // SHARE_VM_COMPILER_COMPILEBROKER_HPP diff -r 102466e70deb -r 91fe28b03d6a src/share/vm/compiler/oopMap.hpp --- a/src/share/vm/compiler/oopMap.hpp Thu Jan 20 15:52:05 2011 -0800 +++ b/src/share/vm/compiler/oopMap.hpp Wed Jan 26 18:17:37 2011 +0100 @@ -47,7 +47,7 @@ class OopMapValue: public StackObj { friend class VMStructs; private: - short _value; + int _value; int value() const { return _value; } void set_value(int value) { _value = value; } short _content_reg; @@ -55,7 +55,7 @@ public: // Constants enum { type_bits = 5, - register_bits = BitsPerShort - type_bits }; + register_bits = BitsPerJavaInteger - type_bits }; enum { type_shift = 0, register_shift = type_bits }; diff -r 102466e70deb -r 91fe28b03d6a src/share/vm/gc_implementation/g1/heapRegion.cpp diff -r 102466e70deb -r 91fe28b03d6a src/share/vm/interpreter/rewriter.cpp --- a/src/share/vm/interpreter/rewriter.cpp Thu Jan 20 15:52:05 2011 -0800 +++ b/src/share/vm/interpreter/rewriter.cpp Wed Jan 26 18:17:37 2011 +0100 @@ -119,7 +119,7 @@ while (!bcs.is_last_bytecode()) { Bytecodes::Code opcode = bcs.raw_next(); switch (opcode) { - case Bytecodes::_return: *bcs.bcp() = Bytecodes::_return_register_finalizer; break; + case Bytecodes::_return: if (!UseC1X) { *bcs.bcp() = Bytecodes::_return_register_finalizer; } break; case Bytecodes::_istore: case Bytecodes::_lstore: @@ -237,12 +237,14 @@ switch (c) { case Bytecodes::_lookupswitch : { #ifndef CC_INTERP - Bytecode_lookupswitch* bc = Bytecode_lookupswitch_at(bcp); - (*bcp) = ( - bc->number_of_pairs() < BinarySwitchThreshold - ? Bytecodes::_fast_linearswitch - : Bytecodes::_fast_binaryswitch - ); + if (!UseC1X) { + Bytecode_lookupswitch* bc = Bytecode_lookupswitch_at(bcp); + (*bcp) = ( + bc->number_of_pairs() < BinarySwitchThreshold + ? Bytecodes::_fast_linearswitch + : Bytecodes::_fast_binaryswitch + ); + } #endif break; } diff -r 102466e70deb -r 91fe28b03d6a src/share/vm/interpreter/templateTable.cpp --- a/src/share/vm/interpreter/templateTable.cpp Thu Jan 20 15:52:05 2011 -0800 +++ b/src/share/vm/interpreter/templateTable.cpp Wed Jan 26 18:17:37 2011 +0100 @@ -429,7 +429,8 @@ def(Bytecodes::_jsr , ubcp|disp|____|____, vtos, vtos, jsr , _ ); // result is not an oop, so do not transition to atos def(Bytecodes::_ret , ubcp|disp|____|____, vtos, vtos, ret , _ ); def(Bytecodes::_tableswitch , ubcp|disp|____|____, itos, vtos, tableswitch , _ ); - def(Bytecodes::_lookupswitch , ubcp|disp|____|____, itos, itos, lookupswitch , _ ); +// def(Bytecodes::_lookupswitch , ubcp|disp|____|____, itos, itos, lookupswitch , _ ); + def(Bytecodes::_lookupswitch , ubcp|disp|____|____, itos, vtos, fast_linearswitch , _ ); def(Bytecodes::_ireturn , ____|disp|clvm|____, itos, itos, _return , itos ); def(Bytecodes::_lreturn , ____|disp|clvm|____, ltos, ltos, _return , ltos ); def(Bytecodes::_freturn , ____|disp|clvm|____, ftos, ftos, _return , ftos ); diff -r 102466e70deb -r 91fe28b03d6a src/share/vm/oops/instanceKlass.cpp --- a/src/share/vm/oops/instanceKlass.cpp Thu Jan 20 15:52:05 2011 -0800 +++ b/src/share/vm/oops/instanceKlass.cpp Wed Jan 26 18:17:37 2011 +0100 @@ -620,7 +620,9 @@ } objArrayOop instanceKlass::allocate_objArray(int n, int length, TRAPS) { - if (length < 0) THROW_0(vmSymbols::java_lang_NegativeArraySizeException()); + if (length < 0) { + THROW_0(vmSymbols::java_lang_NegativeArraySizeException()); + } if (length > arrayOopDesc::max_array_length(T_OBJECT)) { report_java_out_of_memory("Requested array size exceeds VM limit"); THROW_OOP_0(Universe::out_of_memory_error_array_size()); diff -r 102466e70deb -r 91fe28b03d6a src/share/vm/oops/klass.cpp --- a/src/share/vm/oops/klass.cpp Thu Jan 20 15:52:05 2011 -0800 +++ b/src/share/vm/oops/klass.cpp Wed Jan 26 18:17:37 2011 +0100 @@ -144,6 +144,7 @@ } kl->set_java_mirror(NULL); + kl->set_c1x_mirror(NULL); kl->set_modifier_flags(0); kl->set_layout_helper(Klass::_lh_neutral_value); kl->set_name(NULL); diff -r 102466e70deb -r 91fe28b03d6a src/share/vm/oops/klass.hpp --- a/src/share/vm/oops/klass.hpp Thu Jan 20 15:52:05 2011 -0800 +++ b/src/share/vm/oops/klass.hpp Wed Jan 26 18:17:37 2011 +0100 @@ -233,6 +233,8 @@ klassOop _primary_supers[_primary_super_limit]; // java/lang/Class instance mirroring this class oop _java_mirror; + // com/sun/hotspot/c1x/HotSpotTypeResolved mirroring this class + oop _c1x_mirror; // Superclass klassOop _super; // Class name. Instance classes: java/lang/String, etc. Array classes: [I, @@ -333,6 +335,10 @@ oop java_mirror() const { return _java_mirror; } void set_java_mirror(oop m) { oop_store((oop*) &_java_mirror, m); } + // c1x mirror + oop c1x_mirror() const { return _c1x_mirror; } + void set_c1x_mirror(oop m) { oop_store((oop*) &_c1x_mirror, m); } + // modifier flags jint modifier_flags() const { return _modifier_flags; } void set_modifier_flags(jint flags) { _modifier_flags = flags; } @@ -361,6 +367,7 @@ oop* adr_secondary_super_cache() const { return (oop*)&_secondary_super_cache; } oop* adr_secondary_supers()const { return (oop*)&_secondary_supers; } oop* adr_java_mirror() const { return (oop*)&_java_mirror; } + oop* adr_c1x_mirror() const { return (oop*)&_c1x_mirror; } oop* adr_name() const { return (oop*)&_name; } oop* adr_subklass() const { return (oop*)&_subklass; } oop* adr_next_sibling() const { return (oop*)&_next_sibling; } diff -r 102466e70deb -r 91fe28b03d6a src/share/vm/oops/klassKlass.cpp --- a/src/share/vm/oops/klassKlass.cpp Thu Jan 20 15:52:05 2011 -0800 +++ b/src/share/vm/oops/klassKlass.cpp Wed Jan 26 18:17:37 2011 +0100 @@ -70,6 +70,7 @@ MarkSweep::mark_and_push(k->adr_secondary_super_cache()); MarkSweep::mark_and_push(k->adr_secondary_supers()); MarkSweep::mark_and_push(k->adr_java_mirror()); + MarkSweep::mark_and_push(k->adr_c1x_mirror()); MarkSweep::mark_and_push(k->adr_name()); // We follow the subklass and sibling links at the end of the // marking phase, since otherwise following them will prevent @@ -90,6 +91,7 @@ PSParallelCompact::mark_and_push(cm, k->adr_secondary_super_cache()); PSParallelCompact::mark_and_push(cm, k->adr_secondary_supers()); PSParallelCompact::mark_and_push(cm, k->adr_java_mirror()); + PSParallelCompact::mark_and_push(cm, k->adr_c1x_mirror()); PSParallelCompact::mark_and_push(cm, k->adr_name()); // We follow the subklass and sibling links at the end of the // marking phase, since otherwise following them will prevent @@ -110,6 +112,7 @@ blk->do_oop(k->adr_secondary_super_cache()); blk->do_oop(k->adr_secondary_supers()); blk->do_oop(k->adr_java_mirror()); + blk->do_oop(k->adr_c1x_mirror()); blk->do_oop(k->adr_name()); // The following are in the perm gen and are treated // specially in a later phase of a perm gen collection; ... @@ -144,6 +147,8 @@ if (mr.contains(adr)) blk->do_oop(adr); adr = k->adr_java_mirror(); if (mr.contains(adr)) blk->do_oop(adr); + adr = k->adr_c1x_mirror(); + if (mr.contains(adr)) blk->do_oop(adr); adr = k->adr_name(); if (mr.contains(adr)) blk->do_oop(adr); // The following are "weak links" in the perm gen and are @@ -174,6 +179,7 @@ MarkSweep::adjust_pointer(k->adr_secondary_super_cache()); MarkSweep::adjust_pointer(k->adr_secondary_supers()); MarkSweep::adjust_pointer(k->adr_java_mirror()); + MarkSweep::adjust_pointer(k->adr_c1x_mirror()); MarkSweep::adjust_pointer(k->adr_name()); MarkSweep::adjust_pointer(k->adr_subklass()); MarkSweep::adjust_pointer(k->adr_next_sibling()); diff -r 102466e70deb -r 91fe28b03d6a src/share/vm/oops/oop.inline.hpp --- a/src/share/vm/oops/oop.inline.hpp Thu Jan 20 15:52:05 2011 -0800 +++ b/src/share/vm/oops/oop.inline.hpp Wed Jan 26 18:17:37 2011 +0100 @@ -564,8 +564,8 @@ // used only for asserts inline bool oopDesc::is_oop(bool ignore_mark_word) const { oop obj = (oop) this; - if (!check_obj_alignment(obj)) return false; - if (!Universe::heap()->is_in_reserved(obj)) return false; + if (!check_obj_alignment(obj)) { tty->print_cr("unaligned"); return false; } + if (!Universe::heap()->is_in_reserved(obj)) { tty->print_cr("not in reserved"); return false; } // obj is aligned and accessible in heap // try to find metaclass cycle safely without seg faulting on bad input // we should reach klassKlassObj by following klass link at most 3 times diff -r 102466e70deb -r 91fe28b03d6a src/share/vm/prims/jni.cpp --- a/src/share/vm/prims/jni.cpp Thu Jan 20 15:52:05 2011 -0800 +++ b/src/share/vm/prims/jni.cpp Wed Jan 26 18:17:37 2011 +0100 @@ -3355,8 +3355,14 @@ if (JvmtiExport::should_post_thread_life()) { JvmtiExport::post_thread_start(thread); } + + if (BootstrapC1X) { + CompileBroker::bootstrap_c1x(); + } + // Check if we should compile all classes on bootclasspath NOT_PRODUCT(if (CompileTheWorld) ClassLoader::compile_the_world();) + // Since this is not a JVM_ENTRY we have to set the thread state manually before leaving. ThreadStateTransition::transition_and_fence(thread, _thread_in_vm, _thread_in_native); } else { diff -r 102466e70deb -r 91fe28b03d6a src/share/vm/runtime/arguments.cpp --- a/src/share/vm/runtime/arguments.cpp Thu Jan 20 15:52:05 2011 -0800 +++ b/src/share/vm/runtime/arguments.cpp Wed Jan 26 18:17:37 2011 +0100 @@ -66,6 +66,8 @@ int Arguments::_num_jvm_flags = 0; char** Arguments::_jvm_args_array = NULL; int Arguments::_num_jvm_args = 0; +char** Arguments::_c1x_args_array = NULL; +int Arguments::_num_c1x_args = 0; char* Arguments::_java_command = NULL; SystemProperty* Arguments::_system_properties = NULL; const char* Arguments::_gc_log_filename = NULL; @@ -743,6 +745,10 @@ add_string(&_jvm_flags_array, &_num_jvm_flags, arg); } +void Arguments::add_c1x_arg(const char* arg) { + add_string(&_c1x_args_array, &_num_c1x_args, arg); +} + // utility function to return a string that concatenates all // strings in a given char** array const char* Arguments::build_resource_string(char** args, int count) { @@ -2727,6 +2733,42 @@ return JNI_EINVAL; } } + } else if (match_option(option, "-graal", &tail)) { + if (PrintVMOptions) { + tty->print("Running Graal VM... "); + } + UseC1X = true; + BootstrapC1X = true; + const int BUFFER_SIZE = 1024; + char maxine_dir[BUFFER_SIZE]; + char graal_dir[BUFFER_SIZE]; + char temp[BUFFER_SIZE]; + if (!os::getenv("MAXINE", maxine_dir, sizeof(maxine_dir))) { + fatal("Must set MAXINE environment variable to a Maxine project directory."); + } + if (PrintVMOptions) tty->print("MAXINE=%s", maxine_dir); + if (!os::getenv("GRAAL", graal_dir, sizeof(graal_dir))) { + fatal("Must set GRAAL environment variable to a Graal project directory."); + } + if (PrintVMOptions) tty->print_cr(" GRAAL=%s", graal_dir); + sprintf(temp, "%s/C1X/bin", maxine_dir); + scp_p->add_prefix(temp); + sprintf(temp, "%s/CRI/bin", maxine_dir); + scp_p->add_prefix(temp); + sprintf(temp, "%s/Base/bin", maxine_dir); + scp_p->add_prefix(temp); + sprintf(temp, "%s/Assembler/bin", maxine_dir); + scp_p->add_prefix(temp); + sprintf(temp, "%s/c1x4hotspotsrc/HotSpotVM/bin", graal_dir); + scp_p->add_prefix(temp); + *scp_assembly_required_p = true; + } else if (match_option(option, "-C1X:", &tail)) { // -C1X:xxxx + // Option for the C1X compiler. + if (PrintVMOptions) { + tty->print_cr("C1X option %s", tail); + } + Arguments::add_c1x_arg(tail); + // Unknown option } else if (is_bad_option(option, args->ignoreUnrecognized)) { return JNI_ERR; diff -r 102466e70deb -r 91fe28b03d6a src/share/vm/runtime/arguments.hpp --- a/src/share/vm/runtime/arguments.hpp Thu Jan 20 15:52:05 2011 -0800 +++ b/src/share/vm/runtime/arguments.hpp Wed Jan 26 18:17:37 2011 +0100 @@ -228,6 +228,9 @@ // an array containing all jvm arguments specified in the command line static char** _jvm_args_array; static int _num_jvm_args; + // an array containing all c1x arguments specified in the command line + static char** _c1x_args_array; + static int _num_c1x_args; // string containing all java command (class/jarfile name and app args) static char* _java_command; @@ -364,6 +367,7 @@ // methods to build strings from individual args static void build_jvm_args(const char* arg); static void build_jvm_flags(const char* arg); + static void add_c1x_arg(const char* arg); static void add_string(char*** bldarray, int* count, const char* arg); static const char* build_resource_string(char** args, int count); @@ -419,7 +423,9 @@ // return a char* array containing all options static char** jvm_flags_array() { return _jvm_flags_array; } static char** jvm_args_array() { return _jvm_args_array; } + static char** c1x_args_array() { return _c1x_args_array; } static int num_jvm_flags() { return _num_jvm_flags; } + static int num_c1x_args() { return _num_c1x_args; } static int num_jvm_args() { return _num_jvm_args; } // return the arguments passed to the Java application static const char* java_command() { return _java_command; } diff -r 102466e70deb -r 91fe28b03d6a src/share/vm/runtime/deoptimization.cpp --- a/src/share/vm/runtime/deoptimization.cpp Thu Jan 20 15:52:05 2011 -0800 +++ b/src/share/vm/runtime/deoptimization.cpp Wed Jan 26 18:17:37 2011 +0100 @@ -163,6 +163,10 @@ // the vframeArray is created. // + if (TraceDeoptimization) { + tty->print_cr("fetching unroll info"); + } + // Allocate our special deoptimization ResourceMark DeoptResourceMark* dmark = new DeoptResourceMark(thread); assert(thread->deopt_mark() == NULL, "Pending deopt!"); @@ -1145,7 +1149,6 @@ JRT_END -#if defined(COMPILER2) || defined(SHARK) void Deoptimization::load_class_by_index(constantPoolHandle constant_pool, int index, TRAPS) { // in case of an unresolved klass entry, load the class. if (constant_pool->tag_at(index).is_unresolved_klass()) { @@ -1888,40 +1891,3 @@ if (xtty != NULL) xtty->tail("statistics"); } } -#else // COMPILER2 || SHARK - - -// Stubs for C1 only system. -bool Deoptimization::trap_state_is_recompiled(int trap_state) { - return false; -} - -const char* Deoptimization::trap_reason_name(int reason) { - return "unknown"; -} - -void Deoptimization::print_statistics() { - // no output -} - -void -Deoptimization::update_method_data_from_interpreter(methodDataHandle trap_mdo, int trap_bci, int reason) { - // no udpate -} - -int Deoptimization::trap_state_has_reason(int trap_state, int reason) { - return 0; -} - -void Deoptimization::gather_statistics(DeoptReason reason, DeoptAction action, - Bytecodes::Code bc) { - // no update -} - -const char* Deoptimization::format_trap_state(char* buf, size_t buflen, - int trap_state) { - jio_snprintf(buf, buflen, "#%d", trap_state); - return buf; -} - -#endif // COMPILER2 || SHARK diff -r 102466e70deb -r 91fe28b03d6a src/share/vm/runtime/globals.hpp --- a/src/share/vm/runtime/globals.hpp Thu Jan 20 15:52:05 2011 -0800 +++ b/src/share/vm/runtime/globals.hpp Wed Jan 26 18:17:37 2011 +0100 @@ -808,13 +808,16 @@ diagnostic(bool, LogCompilation, false, \ "Log compilation activity in detail to hotspot.log or LogFile") \ \ + product(intx, MaxCompilationID, -1, \ + "All methods with greater compilation ID are skipped") \ + \ product(bool, PrintCompilation, false, \ "Print compilations") \ \ diagnostic(bool, TraceNMethodInstalls, false, \ "Trace nmethod intallation") \ \ - diagnostic(intx, ScavengeRootsInCode, 0, \ + diagnostic(intx, ScavengeRootsInCode, 1, \ "0: do not allow scavengable oops in the code cache; " \ "1: allow scavenging from the code cache; " \ "2: emit as many constants as the compiler can see") \ @@ -1229,7 +1232,7 @@ develop(bool, TraceClassInitialization, false, \ "Trace class initialization") \ \ - develop(bool, TraceExceptions, false, \ + product(bool, TraceExceptions, false, \ "Trace exceptions") \ \ develop(bool, TraceICs, false, \ diff -r 102466e70deb -r 91fe28b03d6a src/share/vm/runtime/javaCalls.cpp --- a/src/share/vm/runtime/javaCalls.cpp Thu Jan 20 15:52:05 2011 -0800 +++ b/src/share/vm/runtime/javaCalls.cpp Wed Jan 26 18:17:37 2011 +0100 @@ -58,7 +58,8 @@ guarantee(thread->is_Java_thread(), "crucial check - the VM thread cannot and must not escape to Java code"); assert(!thread->owns_locks(), "must release all locks when leaving VM"); - guarantee(!thread->is_Compiler_thread(), "cannot make java calls from the compiler"); + // (tw) may we do this? + // guarantee(!thread->is_Compiler_thread(), "cannot make java calls from the compiler"); _result = result; // Allocate handle block for Java code. This must be done before we change thread_state to _thread_in_Java_or_stub, @@ -198,6 +199,23 @@ } } +// ============ Interface calls ============ + +void JavaCalls::call_interface(JavaValue* result, KlassHandle spec_klass, symbolHandle name, symbolHandle signature, JavaCallArguments* args, TRAPS) { + CallInfo callinfo; + Handle receiver = args->receiver(); + KlassHandle recvrKlass(THREAD, receiver.is_null() ? (klassOop)NULL : receiver->klass()); + LinkResolver::resolve_interface_call( + callinfo, receiver, recvrKlass, spec_klass, name, signature, + KlassHandle(), false, true, CHECK); + methodHandle method = callinfo.selected_method(); + assert(method.not_null(), "should have thrown exception"); + + // Invoke the method + JavaCalls::call(result, method, args, CHECK); +} + + // ============ Virtual calls ============ void JavaCalls::call_virtual(JavaValue* result, KlassHandle spec_klass, symbolHandle name, symbolHandle signature, JavaCallArguments* args, TRAPS) { @@ -352,7 +370,8 @@ #endif - assert(!thread->is_Compiler_thread(), "cannot compile from the compiler"); + // (tw) may we do this? + //assert(!thread->is_Compiler_thread(), "cannot compile from the compiler"); if (CompilationPolicy::must_be_compiled(method)) { CompileBroker::compile_method(method, InvocationEntryBci, CompLevel_initial_compile, diff -r 102466e70deb -r 91fe28b03d6a src/share/vm/runtime/javaCalls.hpp --- a/src/share/vm/runtime/javaCalls.hpp Thu Jan 20 15:52:05 2011 -0800 +++ b/src/share/vm/runtime/javaCalls.hpp Wed Jan 26 18:17:37 2011 +0100 @@ -195,6 +195,12 @@ static void call_special(JavaValue* result, Handle receiver, KlassHandle klass, symbolHandle name, symbolHandle signature, Handle arg1, TRAPS); static void call_special(JavaValue* result, Handle receiver, KlassHandle klass, symbolHandle name, symbolHandle signature, Handle arg1, Handle arg2, TRAPS); + // interface call + // ------------ + + // The receiver must be first oop in argument list + static void call_interface(JavaValue* result, KlassHandle spec_klass, symbolHandle name, symbolHandle signature, JavaCallArguments* args, TRAPS); + // virtual call // ------------ diff -r 102466e70deb -r 91fe28b03d6a src/share/vm/runtime/sharedRuntime.cpp --- a/src/share/vm/runtime/sharedRuntime.cpp Thu Jan 20 15:52:05 2011 -0800 +++ b/src/share/vm/runtime/sharedRuntime.cpp Wed Jan 26 18:17:37 2011 +0100 @@ -777,7 +777,14 @@ #ifndef PRODUCT _implicit_null_throws++; #endif - target_pc = nm->continuation_for_implicit_exception(pc); + if (UseC1X) { + if (TraceSignals) { + tty->print_cr(err_msg("calling implicit call stub relative pc=%d method name = %s", pc - nm->entry_point(), nm->method()->name()->as_C_string())); + } + target_pc = Runtime1::entry_for(Runtime1::c1x_global_implicit_null_id); + } else { + target_pc = nm->continuation_for_implicit_exception(pc); + } // If there's an unexpected fault, target_pc might be NULL, // in which case we want to fall through into the normal // error handling code. @@ -793,7 +800,12 @@ #ifndef PRODUCT _implicit_div0_throws++; #endif - target_pc = nm->continuation_for_implicit_exception(pc); + if (UseC1X) { + tty->print_cr("c1x implicit div0"); + target_pc = Runtime1::entry_for(Runtime1::c1x_throw_div0_exception_id); + } else { + target_pc = nm->continuation_for_implicit_exception(pc); + } // If there's an unexpected fault, target_pc might be NULL, // in which case we want to fall through into the normal // error handling code. diff -r 102466e70deb -r 91fe28b03d6a src/share/vm/runtime/stackValue.cpp --- a/src/share/vm/runtime/stackValue.cpp Thu Jan 20 15:52:05 2011 -0800 +++ b/src/share/vm/runtime/stackValue.cpp Wed Jan 26 18:17:37 2011 +0100 @@ -118,6 +118,22 @@ val = (oop)NULL; } #endif +#ifndef PRODUCT + if (val != NULL && !val->is_oop()) { + ResourceMark rm; + tty->print_cr("found wrong oop " INTPTR_FORMAT " at location " INTPTR_FORMAT " (%d):", val, value_addr, val->is_oop()); + if (fr->cb() != NULL) { + CodeBlob* cb = fr->cb(); + if (cb->is_nmethod()) { + nmethod* nm = (nmethod*)cb; + tty->print_cr("method is %s", nm->method()->name()->as_C_string()); + } + } + sv->print(); + tty->print_cr(""); + tty->print_cr("one less %d; one more %d", (*(((oop *)value_addr) - 1))->is_oop(), (*(((oop *)value_addr) + 1))->is_oop()); + } +#endif Handle h(val); // Wrap a handle around the oop return new StackValue(h); } diff -r 102466e70deb -r 91fe28b03d6a src/share/vm/runtime/synchronizer.cpp diff -r 102466e70deb -r 91fe28b03d6a src/share/vm/runtime/thread.cpp --- a/src/share/vm/runtime/thread.cpp Thu Jan 20 15:52:05 2011 -0800 +++ b/src/share/vm/runtime/thread.cpp Wed Jan 26 18:17:37 2011 +0100 @@ -1980,7 +1980,9 @@ // Do not throw asynchronous exceptions against the compiler thread // (the compiler thread should not be a Java thread -- fix in 1.4.2) - if (is_Compiler_thread()) return; + + // (tw) May we do this? + //if (is_Compiler_thread()) return; // This is a change from JDK 1.1, but JDK 1.2 will also do it: if (java_throwable->is_a(SystemDictionary::ThreadDeath_klass())) { @@ -2923,6 +2925,7 @@ _task = NULL; _queue = queue; _counters = counters; + _is_compiling = false; _buffer_blob = NULL; #ifndef PRODUCT @@ -3885,7 +3888,9 @@ { MutexLockerEx ml(doLock ? Threads_lock : NULL); ALL_JAVA_THREADS(p) { - if (p->is_Compiler_thread()) continue; + + // (tw) May we do this? + //if (p->is_Compiler_thread()) continue; address pending = (address)p->current_pending_monitor(); if (pending == monitor) { // found a match diff -r 102466e70deb -r 91fe28b03d6a src/share/vm/runtime/thread.hpp --- a/src/share/vm/runtime/thread.hpp Thu Jan 20 15:52:05 2011 -0800 +++ b/src/share/vm/runtime/thread.hpp Wed Jan 26 18:17:37 2011 +0100 @@ -833,6 +833,9 @@ private: + // c1x needs some place to put the dimensions + jint c1x_multinewarray_storage[256]; + StackGuardState _stack_guard_state; // Compiler exception handling (NOTE: The _exception_oop is *NOT* the same as _pending_exception. It is @@ -1268,6 +1271,7 @@ static ByteSize is_method_handle_return_offset() { return byte_offset_of(JavaThread, _is_method_handle_return); } static ByteSize stack_guard_state_offset() { return byte_offset_of(JavaThread, _stack_guard_state ); } static ByteSize suspend_flags_offset() { return byte_offset_of(JavaThread, _suspend_flags ); } + static ByteSize c1x_multinewarray_storage_offset() { return byte_offset_of(JavaThread, c1x_multinewarray_storage); } static ByteSize do_not_unlock_if_synchronized_offset() { return byte_offset_of(JavaThread, _do_not_unlock_if_synchronized); } static ByteSize should_post_on_exceptions_flag_offset() { @@ -1694,6 +1698,7 @@ CompileLog* _log; CompileTask* _task; CompileQueue* _queue; + bool _is_compiling; BufferBlob* _buffer_blob; public: @@ -1702,6 +1707,8 @@ CompilerThread(CompileQueue* queue, CompilerCounters* counters); + bool is_compiling() const { return _is_compiling; } + void set_compiling(bool b) { _is_compiling = b; } bool is_Compiler_thread() const { return true; } // Hide this compiler thread from external view. bool is_hidden_from_external_view() const { return true; } diff -r 102466e70deb -r 91fe28b03d6a src/share/vm/runtime/vframe.cpp --- a/src/share/vm/runtime/vframe.cpp Thu Jan 20 15:52:05 2011 -0800 +++ b/src/share/vm/runtime/vframe.cpp Wed Jan 26 18:17:37 2011 +0100 @@ -570,6 +570,14 @@ if (size > 4*K) warning("SUSPICIOUSLY LARGE FRAME (%d)", size); #endif } + + tty->print_cr(""); + int i = -1; + for (intptr_t* a = _fr.sp() - 1; a <= _fr.fp(); a++) { + oop o = (oop)(*a); + tty->print_cr("sp[%d] = " INTPTR_FORMAT " (%d)", i, *a, o->is_oop()); + ++i; + } } diff -r 102466e70deb -r 91fe28b03d6a src/share/vm/runtime/vframeArray.cpp --- a/src/share/vm/runtime/vframeArray.cpp Thu Jan 20 15:52:05 2011 -0800 +++ b/src/share/vm/runtime/vframeArray.cpp Wed Jan 26 18:17:37 2011 +0100 @@ -317,9 +317,25 @@ switch(value->type()) { case T_INT: *addr = value->get_int(); +#ifndef PRODUCT + if (TraceDeoptimization) { + tty->print_cr("Reconstructed expression %d (INT): %d", i, (int)(*addr)); + } +#endif break; case T_OBJECT: *addr = value->get_int(T_OBJECT); +#ifndef PRODUCT + if (TraceDeoptimization) { + tty->print("Reconstructed expression %d (OBJECT): ", i); + oop o = (oop)(*addr); + if (o == NULL) { + tty->print_cr("NULL"); + } else { + tty->print_cr(err_msg("%s", o->blueprint()->name()->as_C_string())); + } + } +#endif break; case T_CONFLICT: // A dead stack slot. Initialize to null in case it is an oop. @@ -338,9 +354,25 @@ switch(value->type()) { case T_INT: *addr = value->get_int(); +#ifndef PRODUCT + if (TraceDeoptimization) { + tty->print_cr("Reconstructed local %d (INT): %d", i, (int)(*addr)); + } +#endif break; case T_OBJECT: *addr = value->get_int(T_OBJECT); +#ifndef PRODUCT + if (TraceDeoptimization) { + tty->print("Reconstructed local %d (OBJECT): ", i); + oop o = (oop)(*addr); + if (o == NULL) { + tty->print_cr("NULL"); + } else { + tty->print_cr(err_msg("%s", o->blueprint()->name()->as_C_string())); + } + } +#endif break; case T_CONFLICT: // A dead location. If it is an oop then we need a NULL to prevent GC from following it diff -r 102466e70deb -r 91fe28b03d6a src/share/vm/runtime/vframe_hp.cpp --- a/src/share/vm/runtime/vframe_hp.cpp Thu Jan 20 15:52:05 2011 -0800 +++ b/src/share/vm/runtime/vframe_hp.cpp Wed Jan 26 18:17:37 2011 +0100 @@ -70,6 +70,12 @@ } } + if (TraceDeoptimization) { + tty->print_cr("bci=%d length=%d", this->bci(), length); + tty->print_cr(err_msg("method name = %s", this->method()->name()->as_C_string())); + tty->print_cr("relative pc=%d", this->fr().pc() - this->nm()->code_begin()); + } + for( int i = 0; i < length; i++ ) { result->add( create_stack_value(scv_list->at(i)) ); } diff -r 102466e70deb -r 91fe28b03d6a src/share/vm/utilities/exceptions.cpp --- a/src/share/vm/utilities/exceptions.cpp Thu Jan 20 15:52:05 2011 -0800 +++ b/src/share/vm/utilities/exceptions.cpp Wed Jan 26 18:17:37 2011 +0100 @@ -92,7 +92,8 @@ #endif // ASSERT if (thread->is_VM_thread() - || thread->is_Compiler_thread() ) { + // (tw) May we do this? + /*|| thread->is_Compiler_thread()*/ ) { // We do not care what kind of exception we get for the vm-thread or a thread which // is compiling. We just install a dummy exception object thread->set_pending_exception(Universe::vm_exception(), file, line); @@ -115,7 +116,8 @@ } if (thread->is_VM_thread() - || thread->is_Compiler_thread() ) { + // (tw) May we do this? + /* || thread->is_Compiler_thread()*/ ) { // We do not care what kind of exception we get for the vm-thread or a thread which // is compiling. We just install a dummy exception object thread->set_pending_exception(Universe::vm_exception(), file, line); diff -r 102466e70deb -r 91fe28b03d6a src/share/vm/utilities/globalDefinitions.hpp --- a/src/share/vm/utilities/globalDefinitions.hpp Thu Jan 20 15:52:05 2011 -0800 +++ b/src/share/vm/utilities/globalDefinitions.hpp Wed Jan 26 18:17:37 2011 +0100 @@ -102,9 +102,9 @@ // log2_intptr(sizeof(class JavaThread)) - log2_intptr(64); // see os::set_memory_serialize_page() #ifdef _LP64 -const int SerializePageShiftCount = 4; +const int SerializePageShiftCount = 5; #else -const int SerializePageShiftCount = 3; +const int SerializePageShiftCount = 4; #endif // An opaque struct of heap-word width, so that HeapWord* can be a generic