# HG changeset patch # User Thomas Wuerthinger # Date 1312931782 -7200 # Node ID a97b5881c222f08390a21aa8f3f5bc78d481e4d9 # Parent 83de46612a8df633a63755c30bb0ac5b4aad6c74 Remove Java projects from repository. diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.compiler/.checkstyle --- a/graal/com.oracle.max.graal.compiler/.checkstyle Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,9 +0,0 @@ - - - - - - - - - diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.compiler/.checkstyle_checks.xml --- a/graal/com.oracle.max.graal.compiler/.checkstyle_checks.xml Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,191 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.compiler/.classpath --- a/graal/com.oracle.max.graal.compiler/.classpath Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,12 +0,0 @@ - - - - - - - - - - - - diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.compiler/.project --- a/graal/com.oracle.max.graal.compiler/.project Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,29 +0,0 @@ - - - com.oracle.max.graal.compiler - - - - - - 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 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.compiler/.settings/JavaSourceCodeFormatting.xml --- a/graal/com.oracle.max.graal.compiler/.settings/JavaSourceCodeFormatting.xml Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,264 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.compiler/.settings/org.eclipse.jdt.core.prefs --- a/graal/com.oracle.max.graal.compiler/.settings/org.eclipse.jdt.core.prefs Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,355 +0,0 @@ -#Tue Jul 13 10:33:43 PDT 2010 -eclipse.preferences.version=1 -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.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=warning -org.eclipse.jdt.core.compiler.problem.deadCode=ignore -org.eclipse.jdt.core.compiler.problem.deprecation=warning -org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled -org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled -org.eclipse.jdt.core.compiler.problem.discouragedReference=warning -org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore -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=warning -org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning -org.eclipse.jdt.core.compiler.problem.forbiddenReference=error -org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning -org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning -org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=ignore -org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=warning -org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore -org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning -org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore -org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=ignore -org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=error -org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=disabled -org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning -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=warning -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=warning -org.eclipse.jdt.core.compiler.problem.redundantNullCheck=warning -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=ignore -org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore -org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=warning -org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore -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.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=16 -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=0 -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_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_header=false -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_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=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=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 diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.compiler/.settings/org.eclipse.jdt.ui.prefs --- a/graal/com.oracle.max.graal.compiler/.settings/org.eclipse.jdt.ui.prefs Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,64 +0,0 @@ -#Thu Feb 18 11:36:17 PST 2010 -eclipse.preferences.version=1 -editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true -formatter_profile=_MaxineJavaCodeStyle -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.keywordthis=false -org.eclipse.jdt.ui.ondemandthreshold=0 -org.eclipse.jdt.ui.overrideannotation=true -org.eclipse.jdt.ui.staticondemandthreshold=0 -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_type_abstract_if_missing_method=false -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 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.compiler/LICENSE --- a/graal/com.oracle.max.graal.compiler/LICENSE Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,347 +0,0 @@ -The GNU General Public License (GPL) - -Version 2, June 1991 - -Copyright (C) 1989, 1991 Free Software Foundation, Inc. -59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -Everyone is permitted to copy and distribute verbatim copies of this license -document, but changing it is not allowed. - -Preamble - -The licenses for most software are designed to take away your freedom to share -and change it. By contrast, the GNU General Public License is intended to -guarantee your freedom to share and change free software--to make sure the -software is free for all its users. This General Public License applies to -most of the Free Software Foundation's software and to any other program whose -authors commit to using it. (Some other Free Software Foundation software is -covered by the GNU Library General Public License instead.) You can apply it to -your programs, too. - -When we speak of free software, we are referring to freedom, not price. Our -General Public Licenses are designed to make sure that you have the freedom to -distribute copies of free software (and charge for this service if you wish), -that you receive source code or can get it if you want it, that you can change -the software or use pieces of it in new free programs; and that you know you -can do these things. - -To protect your rights, we need to make restrictions that forbid anyone to deny -you these rights or to ask you to surrender the rights. These restrictions -translate to certain responsibilities for you if you distribute copies of the -software, or if you modify it. - -For example, if you distribute copies of such a program, whether gratis or for -a fee, you must give the recipients all the rights that you have. You must -make sure that they, too, receive or can get the source code. And you must -show them these terms so they know their rights. - -We protect your rights with two steps: (1) copyright the software, and (2) -offer you this license which gives you legal permission to copy, distribute -and/or modify the software. - -Also, for each author's protection and ours, we want to make certain that -everyone understands that there is no warranty for this free software. If the -software is modified by someone else and passed on, we want its recipients to -know that what they have is not the original, so that any problems introduced -by others will not reflect on the original authors' reputations. - -Finally, any free program is threatened constantly by software patents. We -wish to avoid the danger that redistributors of a free program will -individually obtain patent licenses, in effect making the program proprietary. -To prevent this, we have made it clear that any patent must be licensed for -everyone's free use or not licensed at all. - -The precise terms and conditions for copying, distribution and modification -follow. - -TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - -0. This License applies to any program or other work which contains a notice -placed by the copyright holder saying it may be distributed under the terms of -this General Public License. The "Program", below, refers to any such program -or work, and a "work based on the Program" means either the Program or any -derivative work under copyright law: that is to say, a work containing the -Program or a portion of it, either verbatim or with modifications and/or -translated into another language. (Hereinafter, translation is included -without limitation in the term "modification".) Each licensee is addressed as -"you". - -Activities other than copying, distribution and modification are not covered by -this License; they are outside its scope. The act of running the Program is -not restricted, and the output from the Program is covered only if its contents -constitute a work based on the Program (independent of having been made by -running the Program). Whether that is true depends on what the Program does. - -1. You may copy and distribute verbatim copies of the Program's source code as -you receive it, in any medium, provided that you conspicuously and -appropriately publish on each copy an appropriate copyright notice and -disclaimer of warranty; keep intact all the notices that refer to this License -and to the absence of any warranty; and give any other recipients of the -Program a copy of this License along with the Program. - -You may charge a fee for the physical act of transferring a copy, and you may -at your option offer warranty protection in exchange for a fee. - -2. You may modify your copy or copies of the Program or any portion of it, thus -forming a work based on the Program, and copy and distribute such modifications -or work under the terms of Section 1 above, provided that you also meet all of -these conditions: - - a) You must cause the modified files to carry prominent notices stating - that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in whole or - in part contains or is derived from the Program or any part thereof, to be - licensed as a whole at no charge to all third parties under the terms of - this License. - - c) If the modified program normally reads commands interactively when run, - you must cause it, when started running for such interactive use in the - most ordinary way, to print or display an announcement including an - appropriate copyright notice and a notice that there is no warranty (or - else, saying that you provide a warranty) and that users may redistribute - the program under these conditions, and telling the user how to view a copy - of this License. (Exception: if the Program itself is interactive but does - not normally print such an announcement, your work based on the Program is - not required to print an announcement.) - -These requirements apply to the modified work as a whole. If identifiable -sections of that work are not derived from the Program, and can be reasonably -considered independent and separate works in themselves, then this License, and -its terms, do not apply to those sections when you distribute them as separate -works. But when you distribute the same sections as part of a whole which is a -work based on the Program, the distribution of the whole must be on the terms -of this License, whose permissions for other licensees extend to the entire -whole, and thus to each and every part regardless of who wrote it. - -Thus, it is not the intent of this section to claim rights or contest your -rights to work written entirely by you; rather, the intent is to exercise the -right to control the distribution of derivative or collective works based on -the Program. - -In addition, mere aggregation of another work not based on the Program with the -Program (or with a work based on the Program) on a volume of a storage or -distribution medium does not bring the other work under the scope of this -License. - -3. You may copy and distribute the Program (or a work based on it, under -Section 2) in object code or executable form under the terms of Sections 1 and -2 above provided that you also do one of the following: - - a) Accompany it with the complete corresponding machine-readable source - code, which must be distributed under the terms of Sections 1 and 2 above - on a medium customarily used for software interchange; or, - - b) Accompany it with a written offer, valid for at least three years, to - give any third party, for a charge no more than your cost of physically - performing source distribution, a complete machine-readable copy of the - corresponding source code, to be distributed under the terms of Sections 1 - and 2 above on a medium customarily used for software interchange; or, - - c) Accompany it with the information you received as to the offer to - distribute corresponding source code. (This alternative is allowed only - for noncommercial distribution and only if you received the program in - object code or executable form with such an offer, in accord with - Subsection b above.) - -The source code for a work means the preferred form of the work for making -modifications to it. For an executable work, complete source code means all -the source code for all modules it contains, plus any associated interface -definition files, plus the scripts used to control compilation and installation -of the executable. However, as a special exception, the source code -distributed need not include anything that is normally distributed (in either -source or binary form) with the major components (compiler, kernel, and so on) -of the operating system on which the executable runs, unless that component -itself accompanies the executable. - -If distribution of executable or object code is made by offering access to copy -from a designated place, then offering equivalent access to copy the source -code from the same place counts as distribution of the source code, even though -third parties are not compelled to copy the source along with the object code. - -4. You may not copy, modify, sublicense, or distribute the Program except as -expressly provided under this License. Any attempt otherwise to copy, modify, -sublicense or distribute the Program is void, and will automatically terminate -your rights under this License. However, parties who have received copies, or -rights, from you under this License will not have their licenses terminated so -long as such parties remain in full compliance. - -5. You are not required to accept this License, since you have not signed it. -However, nothing else grants you permission to modify or distribute the Program -or its derivative works. These actions are prohibited by law if you do not -accept this License. Therefore, by modifying or distributing the Program (or -any work based on the Program), you indicate your acceptance of this License to -do so, and all its terms and conditions for copying, distributing or modifying -the Program or works based on it. - -6. Each time you redistribute the Program (or any work based on the Program), -the recipient automatically receives a license from the original licensor to -copy, distribute or modify the Program subject to these terms and conditions. -You may not impose any further restrictions on the recipients' exercise of the -rights granted herein. You are not responsible for enforcing compliance by -third parties to this License. - -7. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), conditions -are imposed on you (whether by court order, agreement or otherwise) that -contradict the conditions of this License, they do not excuse you from the -conditions of this License. If you cannot distribute so as to satisfy -simultaneously your obligations under this License and any other pertinent -obligations, then as a consequence you may not distribute the Program at all. -For example, if a patent license would not permit royalty-free redistribution -of the Program by all those who receive copies directly or indirectly through -you, then the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Program. - -If any portion of this section is held invalid or unenforceable under any -particular circumstance, the balance of the section is intended to apply and -the section as a whole is intended to apply in other circumstances. - -It is not the purpose of this section to induce you to infringe any patents or -other property right claims or to contest validity of any such claims; this -section has the sole purpose of protecting the integrity of the free software -distribution system, which is implemented by public license practices. Many -people have made generous contributions to the wide range of software -distributed through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing to -distribute software through any other system and a licensee cannot impose that -choice. - -This section is intended to make thoroughly clear what is believed to be a -consequence of the rest of this License. - -8. If the distribution and/or use of the Program is restricted in certain -countries either by patents or by copyrighted interfaces, the original -copyright holder who places the Program under this License may add an explicit -geographical distribution limitation excluding those countries, so that -distribution is permitted only in or among countries not thus excluded. In -such case, this License incorporates the limitation as if written in the body -of this License. - -9. The Free Software Foundation may publish revised and/or new versions of the -General Public License from time to time. Such new versions will be similar in -spirit to the present version, but may differ in detail to address new problems -or concerns. - -Each version is given a distinguishing version number. If the Program -specifies a version number of this License which applies to it and "any later -version", you have the option of following the terms and conditions either of -that version or of any later version published by the Free Software Foundation. -If the Program does not specify a version number of this License, you may -choose any version ever published by the Free Software Foundation. - -10. If you wish to incorporate parts of the Program into other free programs -whose distribution conditions are different, write to the author to ask for -permission. For software which is copyrighted by the Free Software Foundation, -write to the Free Software Foundation; we sometimes make exceptions for this. -Our decision will be guided by the two goals of preserving the free status of -all derivatives of our free software and of promoting the sharing and reuse of -software generally. - -NO WARRANTY - -11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR -THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE -STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE -PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND -PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, -YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - -12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL -ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE -PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY -GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR -INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA -BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A -FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER -OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. - -END OF TERMS AND CONDITIONS - -How to Apply These Terms to Your New Programs - -If you develop a new program, and you want it to be of the greatest possible -use to the public, the best way to achieve this is to make it free software -which everyone can redistribute and change under these terms. - -To do so, attach the following notices to the program. It is safest to attach -them to the start of each source file to most effectively convey the exclusion -of warranty; and each file should have at least the "copyright" line and a -pointer to where the full notice is found. - - One line to give the program's name and a brief idea of what it does. - - Copyright (C) - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the Free - Software Foundation; either version 2 of the License, or (at your option) - any later version. - - This program 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 for - more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., 59 - Temple Place, Suite 330, Boston, MA 02111-1307 USA - -Also add information on how to contact you by electronic and paper mail. - -If the program is interactive, make it output a short notice like this when it -starts in an interactive mode: - - Gnomovision version 69, Copyright (C) year name of author Gnomovision comes - with ABSOLUTELY NO WARRANTY; for details type 'show w'. This is free - software, and you are welcome to redistribute it under certain conditions; - type 'show c' for details. - -The hypothetical commands 'show w' and 'show c' should show the appropriate -parts of the General Public License. Of course, the commands you use may be -called something other than 'show w' and 'show c'; they could even be -mouse-clicks or menu items--whatever suits your program. - -You should also get your employer (if you work as a programmer) or your school, -if any, to sign a "copyright disclaimer" for the program, if necessary. Here -is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the program - 'Gnomovision' (which makes passes at compilers) written by James Hacker. - - signature of Ty Coon, 1 April 1989 - - Ty Coon, President of Vice - -This General Public License does not permit incorporating your program into -proprietary programs. If your program is a subroutine library, you may -consider it more useful to permit linking proprietary applications with the -library. If this is what you want to do, use the GNU Library General Public -License instead of this License. - - -"CLASSPATH" EXCEPTION TO THE GPL - -Certain source files distributed by Sun Microsystems, Inc. are subject to -the following clarification and special exception to the GPL, but only where -Sun has expressly included in the particular source file's header the words -"Sun designates this particular file as subject to the "Classpath" exception -as provided by Sun in the LICENSE file that accompanied this code." - - Linking this library statically or dynamically with other modules is making - a combined work based on this library. Thus, the terms and conditions of - the GNU General Public License cover the whole combination. - - As a special exception, the copyright holders of this library give you - permission to link this library with independent modules to produce an - executable, regardless of the license terms of these independent modules, - and to copy and distribute the resulting executable under terms of your - choice, provided that you also meet, for each linked independent module, - the terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. If - you modify this library, you may extend this exception to your version of - the library, but you are not obligated to do so. If you do not wish to do - so, delete this exception statement from your version. diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/GraalCompilation.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/GraalCompilation.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,316 +0,0 @@ -/* - * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package com.oracle.max.graal.compiler; - -import java.util.*; - -import com.oracle.max.asm.*; -import com.oracle.max.graal.compiler.alloc.*; -import com.oracle.max.graal.compiler.asm.*; -import com.oracle.max.graal.compiler.debug.*; -import com.oracle.max.graal.compiler.gen.*; -import com.oracle.max.graal.compiler.gen.LIRGenerator.DeoptimizationStub; -import com.oracle.max.graal.compiler.graph.*; -import com.oracle.max.graal.compiler.lir.*; -import com.oracle.max.graal.compiler.observer.*; -import com.oracle.max.graal.nodes.*; -import com.sun.cri.ci.*; -import com.sun.cri.ri.*; - -/** - * This class encapsulates global information about the compilation of a particular method, - * including a reference to the runtime, statistics about the compiled code, etc. - */ -public final class GraalCompilation { - - private static ThreadLocal currentCompilation = new ThreadLocal(); - - public final GraalCompiler compiler; - public final CiTarget target; - public final RiRuntime runtime; - public final RiMethod method; - public final RiRegisterConfig registerConfig; - public final CiStatistics stats; - public final FrameState placeholderState; - - public final CompilerGraph graph; - - private boolean hasExceptionHandlers; - private final GraalCompilation parent; - - /** - * @see #setNotTypesafe() - * @see #isTypesafe() - */ - private boolean typesafe = true; - - private int nextID = 1; - - private FrameMap frameMap; - private TargetMethodAssembler assembler; - - private IR hir; - - private LIRGenerator lirGenerator; - - /** - * Creates a new compilation for the specified method and runtime. - * - * @param compiler the compiler - * @param method the method to be compiled or {@code null} if generating code for a stub - * @param osrBCI the bytecode index for on-stack replacement, if requested - * @param stats externally supplied statistics object to be used if not {@code null} - */ - public GraalCompilation(GraalCompiler compiler, RiMethod method, int osrBCI, CiStatistics stats) { - if (osrBCI != -1) { - throw new CiBailout("No OSR supported"); - } - this.parent = currentCompilation.get(); - currentCompilation.set(this); - this.compiler = compiler; - this.target = compiler.target; - this.runtime = compiler.runtime; - this.graph = new CompilerGraph(runtime); - this.method = method; - this.stats = stats == null ? new CiStatistics() : stats; - this.registerConfig = method == null ? compiler.globalStubRegisterConfig : runtime.getRegisterConfig(method); - this.placeholderState = method != null && method.minimalDebugInfo() ? new FrameState(method, 0, 0, 0, 0, false, graph) : null; - - if (compiler.isObserved()) { - compiler.fireCompilationStarted(new CompilationEvent(this)); - } - } - - public void close() { - currentCompilation.set(parent); - } - - public IR hir() { - return hir; - } - - /** - * Records that this compilation has exception handlers. - */ - public void setHasExceptionHandlers() { - hasExceptionHandlers = true; - } - - /** - * Translates a given kind to a canonical architecture kind. - * This is an identity function for all but {@link CiKind#Word} - * which is translated to {@link CiKind#Int} or {@link CiKind#Long} - * depending on whether or not this is a {@linkplain #is64Bit() 64-bit} - * compilation. - */ - public CiKind archKind(CiKind kind) { - if (kind.isWord()) { - return target.arch.is64bit() ? CiKind.Long : CiKind.Int; - } - return kind; - } - - /** - * Determines if two given kinds are equal at the {@linkplain #archKind(CiKind) architecture} level. - */ - public boolean archKindsEqual(CiKind kind1, CiKind kind2) { - return archKind(kind1) == archKind(kind2); - } - - /** - * Converts this compilation to a string. - * - * @return a string representation of this compilation - */ - @Override - public String toString() { - return "compile: " + method; - } - - /** - * Builds the block map for the specified method. - * - * @param method the method for which to build the block map - * @param osrBCI the OSR bytecode index; {@code -1} if this is not an OSR - * @return the block map for the specified method - */ - public BlockMap getBlockMap(RiMethod method) { - BlockMap map = new BlockMap(method); - map.build(); - if (compiler.isObserved()) { - String label = CiUtil.format("BlockListBuilder %f %r %H.%n(%p)", method, true); - compiler.fireCompilationEvent(new CompilationEvent(this, label, map, method.codeSize())); - } - stats.bytecodeCount += method.code().length; - return map; - } - - /** - * Returns the frame map of this compilation. - * @return the frame map - */ - public FrameMap frameMap() { - return frameMap; - } - - public TargetMethodAssembler assembler() { - if (assembler == null) { - AbstractAssembler asm = compiler.backend.newAssembler(registerConfig); - assembler = new TargetMethodAssembler(asm); - assembler.setFrameSize(frameMap.frameSize()); - assembler.targetMethod.setCustomStackAreaOffset(frameMap.offsetToCustomArea()); - } - return assembler; - } - - public boolean hasExceptionHandlers() { - return hasExceptionHandlers; - } - - public CiResult compile() { - CiTargetMethod targetMethod; - try { - emitHIR(); - emitLIR(); - targetMethod = emitCode(); - - if (GraalOptions.Meter) { - GraalMetrics.BytecodesCompiled += method.codeSize(); - } - } catch (CiBailout b) { - return new CiResult(null, b, stats); - } catch (Throwable t) { - if (GraalOptions.BailoutOnException) { - return new CiResult(null, new CiBailout("Exception while compiling: " + method, t), stats); - } else { - if (t instanceof RuntimeException) { - throw (RuntimeException) t; - } else { - throw new RuntimeException("Exception while compiling: " + method, t); - } - } - } finally { - if (compiler.isObserved()) { - compiler.fireCompilationFinished(new CompilationEvent(this)); - } - } - - return new CiResult(targetMethod, null, stats); - } - - public IR emitHIR() { - hir = new IR(this); - hir.build(); - return hir; - } - - public void initFrameMap(int numberOfLocks) { - frameMap = this.compiler.backend.newFrameMap(method, numberOfLocks); - } - - private void emitLIR() { - try { - if (GraalOptions.GenLIR) { - if (GraalOptions.Time) { - GraalTimers.LIR_CREATE.start(); - } - - initFrameMap(hir.maxLocks()); - - lirGenerator = compiler.backend.newLIRGenerator(this); - - for (LIRBlock b : hir.linearScanOrder()) { - lirGenerator.doBlock(b); - } - - if (GraalOptions.Time) { - GraalTimers.LIR_CREATE.stop(); - } - - if (GraalOptions.PrintLIR && !TTY.isSuppressed()) { - LIRList.printLIR(hir.linearScanOrder()); - } - - new LinearScan(this, hir, lirGenerator, frameMap()).allocate(); - } - } catch (AssertionError e) { - if (compiler.isObserved() && GraalOptions.PlotOnError) { - compiler.fireCompilationEvent(new CompilationEvent(this, "AssertionError in emitLIR", graph, true, false, true)); - } - throw e; - } catch (RuntimeException e) { - if (compiler.isObserved() && GraalOptions.PlotOnError) { - compiler.fireCompilationEvent(new CompilationEvent(this, "RuntimeException in emitLIR", graph, true, false, true)); - } - throw e; - } - } - - private CiTargetMethod emitCode() { - if (GraalOptions.GenLIR && GraalOptions.GenCode) { - final LIRAssembler lirAssembler = compiler.backend.newLIRAssembler(this); - lirAssembler.emitCode(hir.codeEmittingOrder()); - - // generate code for slow cases - lirAssembler.emitLocalStubs(); - - // generate deoptimization stubs - ArrayList deoptimizationStubs = lirGenerator.deoptimizationStubs(); - if (deoptimizationStubs != null) { - for (DeoptimizationStub stub : deoptimizationStubs) { - lirAssembler.emitDeoptizationStub(stub); - } - } - - // generate traps at the end of the method - lirAssembler.emitTraps(); - - CiTargetMethod targetMethod = assembler().finishTargetMethod(method, runtime, lirAssembler.registerRestoreEpilogueOffset, false); - if (graph.assumptions().count() > 0) { - targetMethod.setAssumptions(graph.assumptions()); - } - - if (compiler.isObserved()) { - compiler.fireCompilationEvent(new CompilationEvent(this, "After code generation", graph, false, true, targetMethod)); - } - - if (GraalOptions.Time) { - GraalTimers.CODE_CREATE.stop(); - } - return targetMethod; - } - - return null; - } - - public int nextID() { - return nextID++; - } - - public static GraalCompilation compilation() { - GraalCompilation compilation = currentCompilation.get(); - assert compilation != null; - return compilation; - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/GraalCompiler.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/GraalCompiler.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,182 +0,0 @@ -/* - * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.compiler; - -import java.util.*; - -import com.oracle.max.graal.compiler.debug.*; -import com.oracle.max.graal.compiler.globalstub.*; -import com.oracle.max.graal.compiler.observer.*; -import com.oracle.max.graal.compiler.target.*; -import com.oracle.max.graal.graph.*; -import com.sun.cri.ci.*; -import com.sun.cri.ri.*; -import com.sun.cri.xir.*; - -public class GraalCompiler extends ObservableCompiler { - - public final Map stubs = new HashMap(); - - /** - * The target that this compiler has been configured for. - */ - public final CiTarget target; - - /** - * The runtime that this compiler has been configured for. - */ - public final RiRuntime runtime; - - /** - * The XIR generator that lowers Java operations to machine operations. - */ - public final RiXirGenerator xir; - - /** - * The backend that this compiler has been configured for. - */ - public final Backend backend; - - public final RiRegisterConfig globalStubRegisterConfig; - - private GraalCompilation currentCompilation; - - public GraalCompiler(RiRuntime runtime, CiTarget target, RiXirGenerator xirGen, RiRegisterConfig globalStubRegisterConfig) { - this.runtime = runtime; - this.target = target; - this.xir = xirGen; - this.globalStubRegisterConfig = globalStubRegisterConfig; - this.backend = Backend.create(target.arch, this); - init(); - - Graph.verificationListeners.add(new VerificationListener() { - @Override - public void verificationFailed(Node n, String message) { - GraalCompiler.this.fireCompilationEvent(new CompilationEvent(currentCompilation, "Verification Error on Node " + n.id(), currentCompilation.graph, true, false, true)); - TTY.println(n.toString()); - if (n.predecessor() != null) { - TTY.println("predecessor: " + n.predecessor()); - } - for (Node p : n.usages()) { - TTY.println("usage: " + p); - } - assert false : "Verification of node " + n + " failed: " + message; - } - }); - } - - public CiResult compileMethod(RiMethod method, int osrBCI, RiXirGenerator xirGenerator, CiStatistics stats) { - GraalTimers.TOTAL.start(); - long startTime = 0; - int index = GraalMetrics.CompiledMethods++; - if (GraalOptions.PrintCompilation) { - TTY.print(String.format("Graal %4d %-70s %-45s | ", index, method.holder().name(), method.name())); - startTime = System.nanoTime(); - } - - CiResult result = null; - TTY.Filter filter = new TTY.Filter(GraalOptions.PrintFilter, CiUtil.format("%H.%n", method, false)); - GraalCompilation compilation = new GraalCompilation(this, method, osrBCI, stats); - currentCompilation = compilation; - try { - result = compilation.compile(); - } finally { - filter.remove(); - compilation.close(); - if (GraalOptions.PrintCompilation && !TTY.isSuppressed()) { - long time = (System.nanoTime() - startTime) / 100000; - TTY.println(String.format("%3d.%dms", time / 10, time % 10)); - } - GraalTimers.TOTAL.stop(); - } - - return result; - } - - private void init() { - final List xirTemplateStubs = xir.buildTemplates(backend.newXirAssembler()); - final GlobalStubEmitter emitter = backend.newGlobalStubEmitter(); - - if (xirTemplateStubs != null) { - for (XirTemplate template : xirTemplateStubs) { - TTY.Filter filter = new TTY.Filter(GraalOptions.PrintFilter, template.name); - try { - stubs.put(template, emitter.emit(template, runtime)); - } finally { - filter.remove(); - } - } - } - - for (GlobalStub.Id id : GlobalStub.Id.values()) { - TTY.Filter suppressor = new TTY.Filter(GraalOptions.PrintFilter, id); - try { - stubs.put(id, emitter.emit(id, runtime)); - } finally { - suppressor.remove(); - } - } - - if (GraalOptions.PrintCFGToFile) { - addCompilationObserver(new CFGPrinterObserver()); - } - if (GraalOptions.PrintDOTGraphToFile) { - addCompilationObserver(new GraphvizPrinterObserver(false)); - } - if (GraalOptions.PrintDOTGraphToPdf) { - addCompilationObserver(new GraphvizPrinterObserver(true)); - } - if (GraalOptions.PrintIdealGraphLevel != 0 || GraalOptions.Plot || GraalOptions.PlotOnError) { - CompilationObserver observer; - if (GraalOptions.PrintIdealGraphFile) { - observer = new IdealGraphPrinterObserver(); - } else { - observer = new IdealGraphPrinterObserver(GraalOptions.PrintIdealGraphAddress, GraalOptions.PrintIdealGraphPort); - } - addCompilationObserver(observer); - } - } - - public GlobalStub lookupGlobalStub(GlobalStub.Id id) { - GlobalStub globalStub = stubs.get(id); - assert globalStub != null : "no stub for global stub id: " + id; - return globalStub; - } - - public GlobalStub lookupGlobalStub(XirTemplate template) { - GlobalStub globalStub = stubs.get(template); - assert globalStub != null : "no stub for XirTemplate: " + template; - return globalStub; - } - - public GlobalStub lookupGlobalStub(CiRuntimeCall runtimeCall) { - GlobalStub globalStub = stubs.get(runtimeCall); - if (globalStub == null) { - globalStub = backend.newGlobalStubEmitter().emit(runtimeCall, runtime); - stubs.put(runtimeCall, globalStub); - } - - assert globalStub != null : "could not find global stub for runtime call: " + runtimeCall; - return globalStub; - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/GraalMetrics.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/GraalMetrics.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,167 +0,0 @@ -/* - * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.compiler; - -import java.lang.reflect.*; -import java.util.*; -import java.util.Map.Entry; - -import com.oracle.max.graal.compiler.debug.*; - - -/** - * This class contains a number of fields that collect metrics about compilation, particularly - * the number of times certain optimizations are performed. - */ -public final class GraalMetrics { - public static int CompiledMethods; - public static int TargetMethods; - public static int LocalValueNumberHits; - public static int ValueMapResizes; - public static int InlinedFinalizerChecks; - public static int InlineForcedMethods; - public static int InlineForbiddenMethods; - public static int InlineConsidered; - public static int InlinePerformed; - public static int InlineUncompiledConsidered; - public static int InlineUncompiledPerformed; - public static int BlocksDeleted; - public static int BytecodesCompiled; - public static int CodeBytesEmitted; - public static int SafepointsEmitted; - public static int ExceptionHandlersEmitted; - public static int DataPatches; - public static int DirectCallSitesEmitted; - public static int IndirectCallSitesEmitted; - public static int LiveHIRInstructions; - public static int LIRInstructions; - public static int LIRVariables; - public static int LIRXIRInstructions; - public static int LIRMoveInstructions; - public static int LSRAIntervalsCreated; - public static int LSRASpills; - public static int LoadConstantIterations; - public static int CodeBufferCopies; - public static int UniqueValueIdsAssigned; - public static int FrameStatesCreated; - public static int FrameStateValuesCreated; - public static int NodesCanonicalized; - public static int LoopsPeeled; - public static int LoopsInverted; - public static int PartialUsageProbability; - public static int FullUsageProbability; - public static int Rematerializations; - public static int GlobalValueNumberingHits; - - public static void print() { - for (Entry m : map.entrySet()) { - printField(m.getKey(), m.getValue().value); - } - printClassFields(GraalMetrics.class); - } - - private static LinkedHashMap map = new LinkedHashMap(); - - public static GraalMetrics get(String name) { - if (!map.containsKey(name)) { - map.put(name, new GraalMetrics(name)); - } - return map.get(name); - } - - private GraalMetrics(String name) { - this.name = name; - } - - private int value; - private String name; - - public void increment() { - increment(1); - } - - public void increment(int val) { - value += val; - } - - public static void printClassFields(Class javaClass) { - final String className = javaClass.getSimpleName(); - TTY.println(className + " {"); - for (final Field field : javaClass.getFields()) { - printField(field, false); - } - TTY.println("}"); - } - - public static void printField(final Field field, boolean tabbed) { - final String fieldName = String.format("%35s", field.getName()); - try { - String prefix = tabbed ? "" : " " + fieldName + " = "; - String postfix = tabbed ? "\t" : "\n"; - if (field.getType() == int.class) { - TTY.print(prefix + field.getInt(null) + postfix); - } else if (field.getType() == boolean.class) { - TTY.print(prefix + field.getBoolean(null) + postfix); - } else if (field.getType() == float.class) { - TTY.print(prefix + field.getFloat(null) + postfix); - } else if (field.getType() == String.class) { - TTY.print(prefix + field.get(null) + postfix); - } else if (field.getType() == Map.class) { - Map m = (Map) field.get(null); - TTY.print(prefix + printMap(m) + postfix); - } else { - TTY.print(prefix + field.get(null) + postfix); - } - } catch (IllegalAccessException e) { - // do nothing. - } - } - - private static String printMap(Map m) { - StringBuilder sb = new StringBuilder(); - - List keys = new ArrayList(); - for (Object key : m.keySet()) { - keys.add((String) key); - } - Collections.sort(keys); - - for (String key : keys) { - sb.append(key); - sb.append("\t"); - sb.append(m.get(key)); - sb.append("\n"); - } - - return sb.toString(); - } - - private static void printField(String fieldName, long value) { - TTY.print(" " + fieldName + " = " + value + "\n"); - } - - private static void printField(String fieldName, double value) { - TTY.print(" " + fieldName + " = " + value + "\n"); - } -} - diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/GraalOptions.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/GraalOptions.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,179 +0,0 @@ -/* - * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.compiler; - -import com.oracle.max.graal.compiler.debug.TTY.Filter; - -/** - * This class encapsulates options that control the behavior of the Graal compiler. - * The help message for each option is specified by a {@linkplain #helpMap help map}. - * - * (tw) WARNING: Fields of this class are treated as final by Graal. - */ -public final class GraalOptions { - - // Checkstyle: stop - private static final boolean ____ = false; - // Checkstyle: resume - - public static boolean Lower = true; - - // inlining settings - public static boolean Inline = true; - public static boolean Intrinsify = true; - public static boolean CacheGraphs = ____; - public static boolean InlineWithTypeCheck = ____; - public static int MaximumInstructionCount = 3000; - public static float MaximumInlineRatio = 0.90f; - public static int MaximumInlineSize = 35; - public static int MaximumInlineCompSize = 350; - public static int MaximumFreqInlineSize = 200; - public static int MaximumFreqInlineCompSize = 1500; - public static int FreqInlineRatio = 20; - public static int MaximumTrivialSize = 6; - public static int MaximumTrivialCompSize = 120; - public static int MaximumInlineLevel = 9; - public static int MaximumRecursiveInlineLevel = 2; - public static int MaximumDesiredSize = 8000; - public static int MaximumShortLoopSize = 5; - - // escape analysis settings - public static boolean EscapeAnalysis = ____; - public static int ForcedInlineEscapeWeight = 100; - public static boolean PrintEscapeAnalysis = ____; - - // absolute probability analysis - public static boolean ProbabilityAnalysis = true; - - //rematerialize settings - public static double MinimumUsageProbability = 0.95; - - // debugging settings - public static boolean VerifyPointerMaps = ____; - public static int MethodEndBreakpointGuards = 0; - public static boolean ZapStackOnMethodEntry = ____; - public static boolean StressLinearScan = ____; - public static boolean BailoutOnException = ____; - public static boolean DeoptALot = ____; - public static boolean Verify = true; - public static boolean TestGraphDuplication = ____; - - /** - * See {@link Filter#Filter(String, Object)}. - */ - public static String PrintFilter = null; - - // printing settings - public static boolean PrintLIR = ____; - public static boolean PrintCFGToFile = ____; - - // DOT output settings - public static boolean PrintDOTGraphToFile = ____; - public static boolean PrintDOTGraphToPdf = ____; - public static boolean OmitDOTFrameStates = ____; - - public static boolean Extend = ____; - - // Ideal graph visualizer output settings - public static boolean Plot = ____; - public static boolean PlotVerbose = ____; - public static boolean PlotOnError = ____; - public static boolean PrintIdealGraphBytecodes = true; - public static int PrintIdealGraphLevel = 0; - public static boolean PrintIdealGraphFile = ____; - public static String PrintIdealGraphAddress = "127.0.0.1"; - public static int PrintIdealGraphPort = 4444; - - // Other printing settings - public static boolean Meter = ____; - public static boolean Time = ____; - public static boolean PrintCompilation = ____; - public static boolean PrintXirTemplates = ____; - public static boolean PrintIRWithLIR = ____; - public static boolean PrintAssembly = ____; - public static boolean PrintCodeBytes = ____; - public static int PrintAssemblyBytesPerLine = 16; - public static int TraceLinearScanLevel = 0; - public static int TraceLIRGeneratorLevel = 0; - public static boolean TraceRelocation = ____; - public static boolean TraceLIRVisit = ____; - public static boolean TraceAssembler = ____; - public static boolean TraceInlining = ____; - public static boolean TraceDeadCodeElimination = ____; - public static boolean TraceEscapeAnalysis = ____; - public static boolean TraceCanonicalizer = ____; - public static boolean TraceMemoryMaps = ____; - public static boolean TraceProbability = ____; - public static boolean TraceReadElimination = ____; - public static boolean TraceGVN = ____; - public static int TraceBytecodeParserLevel = 0; - public static boolean QuietBailout = ____; - - // state merging settings - public static boolean AssumeVerifiedBytecode = ____; - - // Linear scan settings - public static boolean CopyPointerStackArguments = true; - - // Code generator settings - public static boolean GenLIR = true; - public static boolean GenCode = true; - public static boolean UseBranchPrediction = true; - public static boolean UseExceptionProbability = ____; - public static int MatureInvocationCount = 100; - public static boolean GenSafepoints = true; - - public static boolean UseConstDirectCall = ____; - - public static boolean GenSpecialDivChecks = true; - public static boolean GenAssertionCode = ____; - public static boolean AlignCallsForPatching = true; - public static boolean NullCheckUniquePc = ____; - public static boolean InvokeSnippetAfterArguments = ____; - public static boolean ResolveClassBeforeStaticInvoke = true; - - // Translating tableswitch instructions - public static int SequentialSwitchLimit = 4; - public static int RangeTestsSwitchDensity = 5; - - public static boolean DetailedAsserts = ____; - - // Runtime settings - public static int ReadPrefetchInstr = 0; - public static int StackShadowPages = 2; - - // Assembler settings - public static boolean CommentedAssembly = ____; - public static boolean PrintLIRWithAssembly = ____; - - public static boolean OptReadElimination = ____; - public static boolean OptGVN = ____; - public static boolean Rematerialize = ____; - public static boolean SplitMaterialization = ____; - public static boolean OptCanonicalizer = true; - public static boolean OptLoops = ____; - public static boolean ScheduleOutOfLoops = true; - public static boolean OptReorderLoops = ____; - public static boolean LoopPeeling = ____; - public static boolean LoopInversion = ____; -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/GraalTimers.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/GraalTimers.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,90 +0,0 @@ -/* - * Copyright (c) 2009, 2009, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.compiler; - -import java.util.*; -import java.util.Map.Entry; - -import com.oracle.max.graal.compiler.debug.*; - -/** - * This class contains timers that record the amount of time spent in various - * parts of the compiler. - */ -public final class GraalTimers { - private static LinkedHashMap map = new LinkedHashMap(); - - - public static final GraalTimers TOTAL = get("Total compilation time"); - public static final GraalTimers COMPUTE_LINEAR_SCAN_ORDER = get("Compute Linear Scan Order"); - public static final GraalTimers LIR_CREATE = get("Create LIR"); - public static final GraalTimers LIFETIME_ANALYSIS = get("Lifetime Analysis"); - public static final GraalTimers LINEAR_SCAN = get("Linear Scan"); - public static final GraalTimers RESOLUTION = get("Resolution"); - public static final GraalTimers DEBUG_INFO = get("Create Debug Info"); - public static final GraalTimers CODE_CREATE = get("Create Code"); - - private final String name; - private long start; - private long total; - - private GraalTimers(String name) { - this.name = name; - } - - - public static GraalTimers get(String name) { - if (!map.containsKey(name)) { - map.put(name, new GraalTimers(name)); - } - return map.get(name); - } - - public void start() { - start = System.nanoTime(); - } - - public void stop() { - total += System.nanoTime() - start; - } - - public static void reset() { - for (Entry e : map.entrySet()) { - e.getValue().total = 0; - } - } - - public static void print() { - - TTY.println(); - TTY.println("%-30s: %7.4f s", TOTAL.name, TOTAL.total / 1000000000.0); - for (Entry e : map.entrySet()) { - GraalTimers timer = e.getValue(); - if (timer != TOTAL) { - TTY.println("%-30s: %7.4f s (%5.2f%%)", timer.name, timer.total / 1000000000.0, timer.total * 100.0 / TOTAL.total); - timer.total = 0; - } - } - TTY.println(); - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/alloc/ComputeLinearScanOrder.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/alloc/ComputeLinearScanOrder.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,357 +0,0 @@ -/* - * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package com.oracle.max.graal.compiler.alloc; - -import java.util.*; - -import com.oracle.max.graal.compiler.*; -import com.oracle.max.graal.compiler.debug.*; -import com.oracle.max.graal.compiler.lir.*; -import com.oracle.max.graal.graph.*; - -public final class ComputeLinearScanOrder { - - private final int maxBlockId; // the highest blockId of a block - private int numBlocks; // total number of blocks (smaller than maxBlockId) - - List linearScanOrder; // the resulting list of blocks in correct order - List codeEmittingOrder; - - final BitMap visitedBlocks; // used for recursive processing of blocks - final BitMap activeBlocks; // used for recursive processing of blocks - final BitMap dominatorBlocks; // temporary BitMap used for computation of dominator - final int[] forwardBranches; // number of incoming forward branches for each block - final List workList; // temporary list (used in markLoops and computeOrder) - final LIRBlock[] loopHeaders; - - // accessors for visitedBlocks and activeBlocks - void initVisited() { - activeBlocks.clearAll(); - visitedBlocks.clearAll(); - } - - boolean isVisited(LIRBlock b) { - return visitedBlocks.get(b.blockID()); - } - - boolean isActive(LIRBlock b) { - return activeBlocks.get(b.blockID()); - } - - void setVisited(LIRBlock b) { - assert !isVisited(b) : "already set"; - visitedBlocks.set(b.blockID()); - } - - void setActive(LIRBlock b) { - assert !isActive(b) : "already set"; - activeBlocks.set(b.blockID()); - } - - void clearActive(LIRBlock b) { - assert isActive(b) : "not already"; - activeBlocks.clear(b.blockID()); - } - - // accessors for forwardBranches - void incForwardBranches(LIRBlock b) { - forwardBranches[b.blockID()]++; - } - - int decForwardBranches(LIRBlock b) { - return --forwardBranches[b.blockID()]; - } - - // accessors for final result - public List linearScanOrder() { - return linearScanOrder; - } - - public ComputeLinearScanOrder(int maxBlockId, int loopCount, LIRBlock startBlock) { - loopHeaders = new LIRBlock[loopCount]; - - this.maxBlockId = maxBlockId; - visitedBlocks = new BitMap(maxBlockId); - activeBlocks = new BitMap(maxBlockId); - dominatorBlocks = new BitMap(maxBlockId); - forwardBranches = new int[maxBlockId]; - workList = new ArrayList(8); - - countEdges(startBlock, null); - computeOrder(startBlock); - printBlocks(); - } - - /** - * Traverses the CFG to analyze block and edge info. The analysis performed is: - * - * 1. Count of total number of blocks. - * 2. Count of all incoming edges and backward incoming edges. - * 3. Number loop header blocks. - * 4. Create a list with all loop end blocks. - */ - void countEdges(LIRBlock cur, LIRBlock parent) { - if (GraalOptions.TraceLinearScanLevel >= 3) { - TTY.println("Counting edges for block B%d%s", cur.blockID(), parent == null ? "" : " coming from B" + parent.blockID()); - } - - if (isActive(cur)) { - return; - } - - // increment number of incoming forward branches - incForwardBranches(cur); - - if (isVisited(cur)) { - if (GraalOptions.TraceLinearScanLevel >= 3) { - TTY.println("block already visited"); - } - return; - } - - numBlocks++; - setVisited(cur); - setActive(cur); - - // recursive call for all successors - int i; - for (i = cur.numberOfSux() - 1; i >= 0; i--) { - countEdges(cur.suxAt(i), cur); - } - - clearActive(cur); - - if (GraalOptions.TraceLinearScanLevel >= 3) { - TTY.println("Finished counting edges for block B%d", cur.blockID()); - } - } - - int computeWeight(LIRBlock cur) { - - // limit loop-depth to 15 bit (only for security reason, it will never be so big) - int weight = (cur.loopDepth() & 0x7FFF) << 16; - - int curBit = 15; - - // this is necessary for the (very rare) case that two successive blocks have - // the same loop depth, but a different loop index (can happen for endless loops - // with exception handlers) -// if (!cur.isLinearScanLoopHeader()) { -// weight |= 1 << curBit; -// } -// curBit--; - - // loop end blocks (blocks that end with a backward branch) are added - // after all other blocks of the loop. - if (!cur.isLinearScanLoopEnd()) { - weight |= 1 << curBit; - } - curBit--; - - // critical edge split blocks are preferred because then they have a greater - // probability to be completely empty - //if (cur.isCriticalEdgeSplit()) { - // weight |= 1 << curBit; - //} - //curBit--; - - // exceptions should not be thrown in normal control flow, so these blocks - // are added as late as possible -// if (!(cur.end() instanceof Throw) && (singleSux == null || !(singleSux.end() instanceof Throw))) { -// weight |= 1 << curBit; -// } -// curBit--; -// if (!(cur.end() instanceof Return) && (singleSux == null || !(singleSux.end() instanceof Return))) { -// weight |= 1 << curBit; -// } -// curBit--; - - // exceptions handlers are added as late as possible - if (!cur.isExceptionEntry()) { - weight |= 1 << curBit; - } - curBit--; - - // guarantee that weight is > 0 - weight |= 1; - - assert curBit >= 0 : "too many flags"; - assert weight > 0 : "weight cannot become negative"; - - return weight; - } - - private boolean readyForProcessing(LIRBlock cur) { - // Discount the edge just traveled. - // When the number drops to zero, all forward branches were processed - if (decForwardBranches(cur) != 0) { - return false; - } - - assert !linearScanOrder.contains(cur) : "block already processed (block can be ready only once)"; - assert !workList.contains(cur) : "block already in work-list (block can be ready only once)"; - return true; - } - - private void sortIntoWorkList(LIRBlock cur) { - assert !workList.contains(cur) : "block already in work list"; - - int curWeight = computeWeight(cur); - - // the linearScanNumber is used to cache the weight of a block - cur.setLinearScanNumber(curWeight); - - if (GraalOptions.StressLinearScan) { - workList.add(0, cur); - return; - } - - workList.add(null); // provide space for new element - - int insertIdx = workList.size() - 1; - while (insertIdx > 0 && workList.get(insertIdx - 1).linearScanNumber() > curWeight) { - workList.set(insertIdx, workList.get(insertIdx - 1)); - insertIdx--; - } - workList.set(insertIdx, cur); - - if (GraalOptions.TraceLinearScanLevel >= 3) { - TTY.println("Sorted B%d into worklist. new worklist:", cur.blockID()); - for (int i = 0; i < workList.size(); i++) { - TTY.println(String.format("%8d B%02d weight:%6x", i, workList.get(i).blockID(), workList.get(i).linearScanNumber())); - } - } - - for (int i = 0; i < workList.size(); i++) { - assert workList.get(i).linearScanNumber() > 0 : "weight not set"; - assert i == 0 || workList.get(i - 1).linearScanNumber() <= workList.get(i).linearScanNumber() : "incorrect order in worklist"; - } - } - - private void appendBlock(LIRBlock cur) { - if (GraalOptions.TraceLinearScanLevel >= 3) { - TTY.println("appending block B%d (weight 0x%06x) to linear-scan order", cur.blockID(), cur.linearScanNumber()); - } - assert !linearScanOrder.contains(cur) : "cannot add the same block twice"; - - // currently, the linear scan order and code emit order are equal. - // therefore the linearScanNumber and the weight of a block must also - // be equal. - cur.setLinearScanNumber(linearScanOrder.size()); - linearScanOrder.add(cur); - - if (!cur.isLinearScanLoopHeader() || !GraalOptions.OptReorderLoops) { - codeEmittingOrder.add(cur); - - if (cur.isLinearScanLoopEnd() && GraalOptions.OptReorderLoops) { - LIRBlock loopHeader = loopHeaders[cur.loopIndex()]; - assert loopHeader != null; - codeEmittingOrder.add(loopHeader); - - for (LIRBlock succ : loopHeader.blockSuccessors()) { - if (succ.loopDepth() == loopHeader.loopDepth()) { - succ.setAlign(true); - } - } - } - } else { - loopHeaders[cur.loopIndex()] = cur; - } - } - - private void computeOrder(LIRBlock startBlock) { - if (GraalOptions.TraceLinearScanLevel >= 3) { - TTY.println("----- computing final block order"); - } - - // the start block is always the first block in the linear scan order - linearScanOrder = new ArrayList(numBlocks); - - codeEmittingOrder = new ArrayList(numBlocks); - - // start processing with standard entry block - assert workList.isEmpty() : "list must be empty before processing"; - - assert readyForProcessing(startBlock); - sortIntoWorkList(startBlock); - - do { - LIRBlock cur = workList.remove(workList.size() - 1); - appendBlock(cur); - - int i; - int numSux = cur.numberOfSux(); - // changed loop order to get "intuitive" order of if- and else-blocks - for (i = 0; i < numSux; i++) { - LIRBlock sux = cur.suxAt(i); - if (readyForProcessing(sux)) { - sortIntoWorkList(sux); - } - } - } while (workList.size() > 0); - } - - public void printBlocks() { - if (GraalOptions.TraceLinearScanLevel >= 2) { - TTY.println("----- loop information:"); - for (LIRBlock cur : linearScanOrder) { - TTY.print(String.format("%4d: B%02d: ", cur.linearScanNumber(), cur.blockID())); - TTY.println(String.format(" . loopIndex: %2d, loopDepth: %2d", cur.loopIndex(), cur.loopDepth())); - } - } - - if (GraalOptions.TraceLinearScanLevel >= 1) { - TTY.println("----- linear-scan block order:"); - for (LIRBlock cur : linearScanOrder) { - TTY.print(String.format("%4d: B%02d loop: %2d depth: %2d", cur.linearScanNumber(), cur.blockID(), cur.loopIndex(), cur.loopDepth())); - - TTY.print(cur.isLinearScanLoopHeader() ? " lh" : " "); - TTY.print(cur.isLinearScanLoopEnd() ? " le" : " "); - - TTY.print(" dom: null "); - - - if (cur.numberOfPreds() > 0) { - TTY.print(" preds: "); - for (int j = 0; j < cur.numberOfPreds(); j++) { - LIRBlock pred = cur.predAt(j); - TTY.print("B%d ", pred.blockID()); - } - } - if (cur.numberOfSux() > 0) { - TTY.print(" sux: "); - for (int j = 0; j < cur.numberOfSux(); j++) { - LIRBlock sux = cur.suxAt(j); - TTY.print("B%d ", sux.blockID()); - } - } - TTY.println(); - } - } - } - - public List codeEmittingOrder() { - return codeEmittingOrder; - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/alloc/ControlFlowOptimizer.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/alloc/ControlFlowOptimizer.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,267 +0,0 @@ -/* - * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.compiler.alloc; - -import java.util.*; - -import com.oracle.max.graal.compiler.*; -import com.oracle.max.graal.compiler.graph.*; -import com.oracle.max.graal.compiler.lir.*; -import com.oracle.max.graal.compiler.util.*; -import com.oracle.max.graal.nodes.calc.*; -import com.sun.cri.ci.*; - -/** - * This class performs basic optimizations on the control flow graph after LIR generation. - */ -final class ControlFlowOptimizer { - - /** - * Performs control flow optimizations on the given IR graph. - * @param ir the IR graph that should be optimized - */ - public static void optimize(IR ir) { - ControlFlowOptimizer optimizer = new ControlFlowOptimizer(ir); - List code = ir.codeEmittingOrder(); - optimizer.reorderShortLoops(code); - optimizer.deleteEmptyBlocks(code); - optimizer.deleteUnnecessaryJumps(code); - optimizer.deleteJumpsToReturn(code); - } - - private final IR ir; - - private ControlFlowOptimizer(IR ir) { - this.ir = ir; - } - - private void reorderShortLoop(List code, LIRBlock headerBlock, int headerIdx) { - int i = headerIdx + 1; - int maxEnd = Math.min(headerIdx + GraalOptions.MaximumShortLoopSize, code.size()); - while (i < maxEnd && code.get(i).loopDepth() >= headerBlock.loopDepth()) { - i++; - } - - if (i == code.size() || code.get(i).loopDepth() < headerBlock.loopDepth()) { - int endIdx = i - 1; - LIRBlock endBlock = code.get(endIdx); - - if (endBlock.numberOfSux() == 1 && endBlock.suxAt(0) == headerBlock) { - // short loop from headerIdx to endIdx found . reorder blocks such that - // the headerBlock is the last block instead of the first block of the loop - - for (int j = headerIdx; j < endIdx; j++) { - code.set(j, code.get(j + 1)); - } - code.set(endIdx, headerBlock); - } - } - } - - private void reorderShortLoops(List code) { - for (int i = code.size() - 1; i >= 0; i--) { - LIRBlock block = code.get(i); - - if (block.isLinearScanLoopHeader()) { - reorderShortLoop(code, block, i); - } - } - - assert verify(code); - } - - // only blocks with exactly one successor can be deleted. Such blocks - // must always end with an unconditional branch to this successor - private boolean canDeleteBlock(LIRBlock block) { - if (block.numberOfSux() != 1 || - block == ir.startBlock || - block.suxAt(0) == block) { - return false; - } - - List instructions = block.lir().instructionsList(); - - assert instructions.size() >= 2 : "block must have label and branch"; - assert instructions.get(0).code == LIROpcode.Label : "first instruction must always be a label"; - assert instructions.get(instructions.size() - 1) instanceof LIRBranch : "last instruction must always be a branch but is " + instructions.get(instructions.size() - 1); - assert ((LIRBranch) instructions.get(instructions.size() - 1)).cond() == Condition.TRUE : "branch must be unconditional"; - assert ((LIRBranch) instructions.get(instructions.size() - 1)).block() == block.suxAt(0) : "branch target must be the successor " + ((LIRBranch) instructions.get(instructions.size() - 1)).block(); - - // block must have exactly one successor - - return instructions.size() == 2 && instructions.get(instructions.size() - 1).info == null; - } - - private void deleteEmptyBlocks(List code) { - int oldPos = 0; - int newPos = 0; - int numBlocks = code.size(); - - while (oldPos < numBlocks) { - LIRBlock block = code.get(oldPos); - - if (canDeleteBlock(block)) { - LIRBlock newTarget = block.suxAt(0); - - // update the block references in any branching LIR instructions - for (LIRBlock pred : block.blockPredecessors()) { - for (LIRInstruction instr : pred.lir().instructionsList()) { - if (instr instanceof LIRBranch) { - ((LIRBranch) instr).substitute(block, newTarget); - } else if (instr instanceof LIRTableSwitch) { - ((LIRTableSwitch) instr).substitute(block, newTarget); - } else if (instr instanceof LIRXirInstruction) { - ((LIRXirInstruction) instr).substitute(block, newTarget); - } - } - } - - // adjust successor and predecessor lists - block.replaceWith(newTarget); - GraalMetrics.BlocksDeleted++; - } else { - // adjust position of this block in the block list if blocks before - // have been deleted - if (newPos != oldPos) { - code.set(newPos, code.get(oldPos)); - } - newPos++; - } - oldPos++; - } - assert verify(code); - Util.truncate(code, newPos); - - assert verify(code); - } - - private void deleteUnnecessaryJumps(List code) { - // skip the last block because there a branch is always necessary - for (int i = code.size() - 2; i >= 0; i--) { - LIRBlock block = code.get(i); - List instructions = block.lir().instructionsList(); - - LIRInstruction lastOp = instructions.get(instructions.size() - 1); - if (lastOp.code == LIROpcode.Branch) { - assert lastOp instanceof LIRBranch : "branch must be of type LIRBranch"; - LIRBranch lastBranch = (LIRBranch) lastOp; - - if (lastBranch.block() == null) { - // this might target a deoptimization stub... - // TODO check if the target is really a deopt stub... -// assert lastBranch.block() != null : "last branch must always have a block as target, current block #" + block.blockID(); - continue; - } - assert lastBranch.label() == lastBranch.block().label() : "must be equal"; - - if (lastBranch.info == null) { - if (lastBranch.block() == code.get(i + 1)) { - // delete last branch instruction - Util.truncate(instructions, instructions.size() - 1); - - } else { - LIRInstruction prevOp = instructions.get(instructions.size() - 2); - if (prevOp.code == LIROpcode.Branch || prevOp.code == LIROpcode.CondFloatBranch) { - assert prevOp instanceof LIRBranch : "branch must be of type LIRBranch"; - LIRBranch prevBranch = (LIRBranch) prevOp; - - if (prevBranch.block() == code.get(i + 1) && prevBranch.info == null) { - // eliminate a conditional branch to the immediate successor - prevBranch.changeBlock(lastBranch.block()); - prevBranch.negateCondition(); - Util.truncate(instructions, instructions.size() - 1); - } - } - } - } - } - } - - assert verify(code); - } - - private void deleteJumpsToReturn(List code) { - for (int i = code.size() - 1; i >= 0; i--) { - LIRBlock block = code.get(i); - List curInstructions = block.lir().instructionsList(); - LIRInstruction curLastOp = curInstructions.get(curInstructions.size() - 1); - - assert curInstructions.get(0).code == LIROpcode.Label : "first instruction must always be a label"; - if (curInstructions.size() == 2 && curLastOp.code == LIROpcode.Return) { - // the block contains only a label and a return - // if a predecessor ends with an unconditional jump to this block, then the jump - // can be replaced with a return instruction - // - // Note: the original block with only a return statement cannot be deleted completely - // because the predecessors might have other (conditional) jumps to this block. - // this may lead to unnecesary return instructions in the final code - - assert curLastOp.info == null : "return instructions do not have debug information"; - - assert curLastOp instanceof LIROp1 : "return must be LIROp1"; - CiValue returnOpr = ((LIROp1) curLastOp).operand(); - - for (int j = block.numberOfPreds() - 1; j >= 0; j--) { - LIRBlock pred = block.predAt(j); - List predInstructions = pred.lir().instructionsList(); - LIRInstruction predLastOp = predInstructions.get(predInstructions.size() - 1); - - if (predLastOp.code == LIROpcode.Branch) { - assert predLastOp instanceof LIRBranch : "branch must be LIRBranch"; - LIRBranch predLastBranch = (LIRBranch) predLastOp; - - if (predLastBranch.block() == block && predLastBranch.cond() == Condition.TRUE && predLastBranch.info == null) { - // replace the jump to a return with a direct return - // Note: currently the edge between the blocks is not deleted - predInstructions.set(predInstructions.size() - 1, new LIROp1(LIROpcode.Return, returnOpr)); - } - } - } - } - } - } - - private boolean verify(List code) { - for (LIRBlock block : code) { - List instructions = block.lir().instructionsList(); - - for (LIRInstruction instr : instructions) { - if (instr instanceof LIRBranch) { - LIRBranch opBranch = (LIRBranch) instr; - assert opBranch.block() == null || opBranch.block().blockID() == -1 || code.contains(opBranch.block()) : "missing successor branch from: " + block + " to: " + opBranch.block(); - assert opBranch.unorderedBlock() == null || opBranch.unorderedBlock().blockID() == -1 || code.contains(opBranch.unorderedBlock()) : "missing successor branch from: " + block + " to: " + opBranch.unorderedBlock(); - } - } - - for (LIRBlock sux : block.blockSuccessors()) { - assert code.contains(sux) : "missing successor from: " + block + "to: " + sux; - } - - for (LIRBlock pred : block.blockPredecessors()) { - assert code.contains(pred) : "missing predecessor from: " + block + "to: " + pred; - } - } - - return true; - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/alloc/EdgeMoveOptimizer.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/alloc/EdgeMoveOptimizer.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,308 +0,0 @@ -/* - * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.compiler.alloc; - -import java.util.*; - -import com.oracle.max.graal.compiler.*; -import com.oracle.max.graal.compiler.lir.*; -import com.oracle.max.graal.nodes.calc.*; - -/** - * This class optimizes moves, particularly those that result from eliminating SSA form. - * - * When a block has more than one predecessor, and all predecessors end with - * the {@linkplain #same(LIRInstruction, LIRInstruction) same} sequence of - * {@linkplain LIROpcode#Move move} instructions, then these sequences - * can be replaced with a single copy of the sequence at the beginning of the block. - * - * Similarly, when a block has more than one successor, then same sequences of - * moves at the beginning of the successors can be placed once at the end of - * the block. But because the moves must be inserted before all branch - * instructions, this works only when there is exactly one conditional branch - * at the end of the block (because the moves must be inserted before all - * branches, but after all compares). - * - * This optimization affects all kind of moves (reg->reg, reg->stack and - * stack->reg). Because this optimization works best when a block contains only - * a few moves, it has a huge impact on the number of blocks that are totally - * empty. - * - * @author Christian Wimmer (original HotSpot implementation) - * @author Thomas Wuerthinger - * @author Doug Simon - */ -final class EdgeMoveOptimizer { - - /** - * Optimizes moves on block edges. - * - * @param blockList a list of blocks whose moves should be optimized - */ - public static void optimize(List blockList) { - EdgeMoveOptimizer optimizer = new EdgeMoveOptimizer(); - - // ignore the first block in the list (index 0 is not processed) - for (int i = blockList.size() - 1; i >= 1; i--) { - LIRBlock block = blockList.get(i); - - if (block.numberOfPreds() > 1) { - optimizer.optimizeMovesAtBlockEnd(block); - } - if (block.numberOfSux() == 2) { - optimizer.optimizeMovesAtBlockBegin(block); - } - } - } - - private final List> edgeInstructionSeqences; - - private EdgeMoveOptimizer() { - edgeInstructionSeqences = new ArrayList>(4); - } - - /** - * Determines if two operations are both {@linkplain LIROpcode#Move moves} - * that have the same {@linkplain LIROp1#operand() source} and {@linkplain LIROp1#result() destination} - * operands and they have the same {@linkplain LIRInstruction#info debug info}. - * - * @param op1 the first instruction to compare - * @param op2 the second instruction to compare - * @return {@code true} if {@code op1} and {@code op2} are the same by the above algorithm - */ - private boolean same(LIRInstruction op1, LIRInstruction op2) { - assert op1 != null; - assert op2 != null; - - if (op1.code == LIROpcode.Move && op2.code == LIROpcode.Move) { - assert op1 instanceof LIROp1 : "move must be LIROp1"; - assert op2 instanceof LIROp1 : "move must be LIROp1"; - LIROp1 move1 = (LIROp1) op1; - LIROp1 move2 = (LIROp1) op2; - if (move1.info == move2.info && move1.operand().equals(move2.operand()) && move1.result().equals(move2.result())) { - // these moves are exactly equal and can be optimized - return true; - } - } - return false; - } - - /** - * Moves the longest {@linkplain #same common} subsequence at the end all - * predecessors of {@code block} to the start of {@code block}. - */ - private void optimizeMovesAtBlockEnd(LIRBlock block) { - if (block.isPredecessor(block)) { - // currently we can't handle this correctly. - return; - } - - // clear all internal data structures - edgeInstructionSeqences.clear(); - - int numPreds = block.numberOfPreds(); - assert numPreds > 1 : "do not call otherwise"; - - // setup a list with the LIR instructions of all predecessors - for (int i = 0; i < numPreds; i++) { - LIRBlock pred = block.predAt(i); - assert pred != null; - assert pred.lir() != null; - List predInstructions = pred.lir().instructionsList(); - - if (pred.numberOfSux() != 1) { - // this can happen with switch-statements where multiple edges are between - // the same blocks. - return; - } - - if (predInstructions.get(predInstructions.size() - 1).code == LIROpcode.Xir) { - return; - } - - assert pred.suxAt(0) == block : "invalid control flow"; - assert predInstructions.get(predInstructions.size() - 1).code == LIROpcode.Branch : "block with successor must end with branch" + predInstructions.get(predInstructions.size() - 1); - assert predInstructions.get(predInstructions.size() - 1) instanceof LIRBranch : "branch must be LIROpBranch"; - assert ((LIRBranch) predInstructions.get(predInstructions.size() - 1)).cond() == Condition.TRUE : "block must end with unconditional branch"; - - if (predInstructions.get(predInstructions.size() - 1).info != null) { - // can not optimize instructions that have debug info - return; - } - - // ignore the unconditional branch at the end of the block - List seq = predInstructions.subList(0, predInstructions.size() - 1); - edgeInstructionSeqences.add(seq); - } - - // process lir-instructions while all predecessors end with the same instruction - while (true) { - List seq = edgeInstructionSeqences.get(0); - if (seq.isEmpty()) { - return; - } - - LIRInstruction op = last(seq); - for (int i = 1; i < numPreds; ++i) { - List otherSeq = edgeInstructionSeqences.get(i); - if (otherSeq.isEmpty() || !same(op, last(otherSeq))) { - return; - } - } - - // insert the instruction at the beginning of the current block - block.lir().insertBefore(1, op); - - // delete the instruction at the end of all predecessors - for (int i = 0; i < numPreds; i++) { - seq = edgeInstructionSeqences.get(i); - removeLast(seq); - } - } - } - - /** - * Moves the longest {@linkplain #same common} subsequence at the start of all - * successors of {@code block} to the end of {@code block} just prior to the - * branch instruction ending {@code block}. - */ - private void optimizeMovesAtBlockBegin(LIRBlock block) { - - edgeInstructionSeqences.clear(); - int numSux = block.numberOfSux(); - - List instructions = block.lir().instructionsList(); - - assert numSux == 2 : "method should not be called otherwise"; - - if (instructions.get(instructions.size() - 1).code == LIROpcode.Xir) { - // cannot optimize when last instruction is Xir. - return; - } - - assert instructions.get(instructions.size() - 1).code == LIROpcode.Branch : "block with successor must end with branch block=B" + block.blockID(); - assert instructions.get(instructions.size() - 1) instanceof LIRBranch : "branch must be LIROpBranch"; - assert ((LIRBranch) instructions.get(instructions.size() - 1)).cond() == Condition.TRUE : "block must end with unconditional branch"; - - if (instructions.get(instructions.size() - 1).info != null) { - // cannot optimize instructions when debug info is needed - return; - } - - LIRInstruction branch = instructions.get(instructions.size() - 2); - if (branch.info != null || (branch.code != LIROpcode.Branch && branch.code != LIROpcode.CondFloatBranch)) { - // not a valid case for optimization - // currently, only blocks that end with two branches (conditional branch followed - // by unconditional branch) are optimized - return; - } - - // now it is guaranteed that the block ends with two branch instructions. - // the instructions are inserted at the end of the block before these two branches - int insertIdx = instructions.size() - 2; - - if (GraalOptions.DetailedAsserts && false) { // not true anymore with guards - for (int i = insertIdx - 1; i >= 0; i--) { - LIRInstruction op = instructions.get(i); - if ((op.code == LIROpcode.Branch || op.code == LIROpcode.CondFloatBranch) && ((LIRBranch) op).block() != null) { - throw new Error("block with two successors can have only two branch instructions : error in " + block); - } - } - } - - // setup a list with the lir-instructions of all successors - for (int i = 0; i < numSux; i++) { - LIRBlock sux = block.suxAt(i); - List suxInstructions = sux.lir().instructionsList(); - - assert suxInstructions.get(0).code == LIROpcode.Label : "block must start with label"; - - if (sux.numberOfPreds() != 1) { - // this can happen with switch-statements where multiple edges are between - // the same blocks. - return; - } - assert sux.predAt(0) == block : "invalid control flow"; - - // ignore the label at the beginning of the block - List seq = suxInstructions.subList(1, suxInstructions.size()); - edgeInstructionSeqences.add(seq); - } - - // process LIR instructions while all successors begin with the same instruction - while (true) { - List seq = edgeInstructionSeqences.get(0); - if (seq.isEmpty()) { - return; - } - - LIRInstruction op = first(seq); - for (int i = 1; i < numSux; i++) { - List otherSeq = edgeInstructionSeqences.get(i); - if (otherSeq.isEmpty() || !same(op, first(otherSeq))) { - // these instructions are different and cannot be optimized . - // no further optimization possible - return; - } - } - - // insert instruction at end of current block - block.lir().insertBefore(insertIdx, op); - insertIdx++; - - // delete the instructions at the beginning of all successors - for (int i = 0; i < numSux; i++) { - seq = edgeInstructionSeqences.get(i); - removeFirst(seq); - } - } - } - - /** - * Gets the first element from a LIR instruction sequence. - */ - private static LIRInstruction first(List seq) { - return seq.get(0); - } - - /** - * Gets the last element from a LIR instruction sequence. - */ - private static LIRInstruction last(List seq) { - return seq.get(seq.size() - 1); - } - - /** - * Removes the first element from a LIR instruction sequence. - */ - private static void removeFirst(List seq) { - seq.remove(0); - } - - /** - * Removes the last element from a LIR instruction sequence. - */ - private static void removeLast(List seq) { - seq.remove(seq.size() - 1); - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/alloc/Interval.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/alloc/Interval.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1173 +0,0 @@ -/* - * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.compiler.alloc; - -import java.util.*; - -import com.oracle.max.graal.compiler.*; -import com.oracle.max.graal.compiler.debug.*; -import com.oracle.max.graal.compiler.lir.*; -import com.oracle.max.graal.compiler.util.*; -import com.sun.cri.ci.*; - -/** - * Represents an interval in the {@linkplain LinearScan linear scan register allocator}. - * - * @author Thomas Wuerthinger - * @author Doug Simon - */ -public final class Interval { - - /** - * A pair of intervals. - */ - static final class Pair { - public final Interval first; - public final Interval second; - public Pair(Interval first, Interval second) { - this.first = first; - this.second = second; - } - } - - /** - * A set of interval lists, one per {@linkplain RegisterBinding binding} type. - */ - static final class RegisterBindingLists { - - /** - * List of intervals whose binding is currently {@link RegisterBinding#Fixed}. - */ - public Interval fixed; - - /** - * List of intervals whose binding is currently {@link RegisterBinding#Any}. - */ - public Interval any; - - public RegisterBindingLists(Interval fixed, Interval any) { - this.fixed = fixed; - this.any = any; - } - - /** - * Gets the list for a specified binding. - * - * @param binding specifies the list to be returned - * @return the list of intervals whose binding is {@code binding} - */ - public Interval get(RegisterBinding binding) { - if (binding == RegisterBinding.Any) { - return any; - } - assert binding == RegisterBinding.Fixed; - return fixed; - } - - /** - * Sets the list for a specified binding. - * - * @param binding specifies the list to be replaced - * @param a list of intervals whose binding is {@code binding} - */ - public void set(RegisterBinding binding, Interval list) { - assert list != null; - if (binding == RegisterBinding.Any) { - any = list; - } else { - assert binding == RegisterBinding.Fixed; - fixed = list; - } - } - - /** - * Adds an interval to a list sorted by {@linkplain Interval#currentFrom() current from} positions. - * - * @param binding specifies the list to be updated - * @param interval the interval to add - */ - public void addToListSortedByCurrentFromPositions(RegisterBinding binding, Interval interval) { - Interval list = get(binding); - Interval prev = null; - Interval cur = list; - while (cur.currentFrom() < interval.currentFrom()) { - prev = cur; - cur = cur.next; - } - Interval result = list; - if (prev == null) { - // add to head of list - result = interval; - } else { - // add before 'cur' - prev.next = interval; - } - interval.next = cur; - set(binding, result); - } - - /** - * Adds an interval to a list sorted by {@linkplain Interval#from() start} positions and - * {@linkplain Interval#firstUsage(RegisterPriority) first usage} positions. - * - * @param binding specifies the list to be updated - * @param interval the interval to add - */ - public void addToListSortedByStartAndUsePositions(RegisterBinding binding, Interval interval) { - Interval list = get(binding); - Interval prev = null; - Interval cur = list; - while (cur.from() < interval.from() || (cur.from() == interval.from() && cur.firstUsage(RegisterPriority.None) < interval.firstUsage(RegisterPriority.None))) { - prev = cur; - cur = cur.next; - } - if (prev == null) { - list = interval; - } else { - prev.next = interval; - } - interval.next = cur; - set(binding, list); - } - - /** - * Removes an interval from a list. - * - * @param binding specifies the list to be updated - * @param interval the interval to remove - */ - public void remove(RegisterBinding binding, Interval i) { - Interval list = get(binding); - Interval prev = null; - Interval cur = list; - while (cur != i) { - assert cur != null && cur != Interval.EndMarker : "interval has not been found in list: " + i; - prev = cur; - cur = cur.next; - } - if (prev == null) { - set(binding, cur.next); - } else { - prev.next = cur.next; - } - } - } - - /** - * Constants denoting the register usage priority for an interval. - * The constants are declared in increasing order of priority are - * are used to optimize spilling when multiple overlapping intervals - * compete for limited registers. - */ - enum RegisterPriority { - /** - * No special reason for an interval to be allocated a register. - */ - None, - - /** - * Priority level for intervals live at the end of a loop. - */ - LiveAtLoopEnd, - - /** - * Priority level for intervals that should be allocated to a register. - */ - ShouldHaveRegister, - - /** - * Priority level for intervals that must be allocated to a register. - */ - MustHaveRegister; - - public static final RegisterPriority[] VALUES = values(); - - /** - * Determines if this priority is higher than or equal to a given priority. - */ - public boolean greaterEqual(RegisterPriority other) { - return ordinal() >= other.ordinal(); - } - - /** - * Determines if this priority is lower than a given priority. - */ - public boolean lessThan(RegisterPriority other) { - return ordinal() < other.ordinal(); - } - } - - /** - * Constants denoting whether an interval is bound to a specific register. This models - * platform dependencies on register usage for certain instructions. - */ - enum RegisterBinding { - /** - * Interval is bound to a specific register as required by the platform. - */ - Fixed, - - /** - * Interval has no specific register requirements. - */ - Any; - - public static final RegisterBinding[] VALUES = values(); - } - - /** - * Constants denoting the linear-scan states an interval may be in with respect to the - * {@linkplain Interval#from() start} {@code position} of the interval being processed. - */ - enum State { - /** - * An interval that starts after {@code position}. - */ - Unhandled, - - /** - * An interval that {@linkplain Interval#covers covers} {@code position} and has an assigned register. - */ - Active, - - /** - * An interval that starts before and ends after {@code position} but does not - * {@linkplain Interval#covers cover} it due to a lifetime hole. - */ - Inactive, - - /** - * An interval that ends before {@code position} or is spilled to memory. - */ - Handled; - } - - /** - * Constants used in optimization of spilling of an interval. - */ - enum SpillState { - /** - * Starting state of calculation: no definition found yet. - */ - NoDefinitionFound, - - /** - * One definition has already been found. Two consecutive definitions are treated as one - * (e.g. a consecutive move and add because of two-operand LIR form). - * The position of this definition is given by {@link Interval#spillDefinitionPos()}. - */ - NoSpillStore, - - /** - * One spill move has already been inserted. - */ - OneSpillStore, - - /** - * The interval should be stored immediately after its definition to prevent - * multiple redundant stores. - */ - StoreAtDefinition, - - /** - * The interval starts in memory (e.g. method parameter), so a store is never necessary. - */ - StartInMemory, - - /** - * The interval has more than one definition (e.g. resulting from phi moves), so stores - * to memory are not optimized. - */ - NoOptimization - } - - /** - * List of use positions. Each entry in the list records the use position and register - * priority associated with the use position. The entries in the list are in descending - * order of use position. - * - * @author Doug Simon - */ - public static final class UsePosList { - private IntList list; - - /** - * Creates a use list. - * - * @param initialCapacity the initial capacity of the list in terms of entries - */ - public UsePosList(int initialCapacity) { - list = new IntList(initialCapacity * 2); - } - - private UsePosList(IntList list) { - this.list = list; - } - - /** - * Splits this list around a given position. All entries in this list with a use position greater or equal than - * {@code splitPos} are removed from this list and added to the returned list. - * - * @param splitPos the position for the split - * @return a use position list containing all entries removed from this list that have a use position greater or equal - * than {@code splitPos} - */ - public UsePosList splitAt(int splitPos) { - int i = size() - 1; - int len = 0; - while (i >= 0 && usePos(i) < splitPos) { - --i; - len += 2; - } - int listSplitIndex = (i + 1) * 2; - IntList childList = list; - list = IntList.copy(this.list, listSplitIndex, len); - childList.setSize(listSplitIndex); - UsePosList child = new UsePosList(childList); - return child; - } - - /** - * Gets the use position at a specified index in this list. - * - * @param index the index of the entry for which the use position is returned - * @return the use position of entry {@code index} in this list - */ - public int usePos(int index) { - return list.get(index << 1); - } - - /** - * Gets the register priority for the use position at a specified index in this list. - * - * @param index the index of the entry for which the register priority is returned - * @return the register priority of entry {@code index} in this list - */ - public RegisterPriority registerPriority(int index) { - return RegisterPriority.VALUES[list.get((index << 1) + 1)]; - } - - public void add(int usePos, RegisterPriority registerPriority) { - assert list.size() == 0 || usePos(size() - 1) > usePos; - list.add(usePos); - list.add(registerPriority.ordinal()); - } - - public int size() { - return list.size() >> 1; - } - - public void removeLowestUsePos() { - list.setSize(list.size() - 2); - } - - public void setRegisterPriority(int index, RegisterPriority registerPriority) { - list.set(index * 2, registerPriority.ordinal()); - } - - @Override - public String toString() { - StringBuilder buf = new StringBuilder("["); - for (int i = size() - 1; i >= 0; --i) { - if (buf.length() != 1) { - buf.append(", "); - } - RegisterPriority prio = registerPriority(i); - buf.append(usePos(i)).append(" -> ").append(prio.ordinal()).append(':').append(prio); - } - return buf.append("]").toString(); - } - } - - /** - * The {@linkplain CiRegisterValue register} or {@linkplain CiVariable variable} for this interval prior to register allocation. - */ - public final CiValue operand; - - /** - * The {@linkplain OperandPool#operandNumber(CiValue) operand number} for this interval's {@linkplain #operand operand}. - */ - public final int operandNumber; - - /** - * The {@linkplain CiRegisterValue register}, {@linkplain CiStackSlot spill slot} or {@linkplain CiAddress address} assigned to this interval. - */ - private CiValue location; - - /** - * The stack slot to which all splits of this interval are spilled if necessary. - */ - private CiStackSlot spillSlot; - - /** - * The kind of this interval. - * Only valid if this is a {@linkplain #isVariable() variable}. - */ - private CiKind kind; - - /** - * The head of the list of ranges describing this interval. This list is sorted by {@linkplain LIRInstruction#id instruction ids}. - */ - private Range first; - - /** - * List of (use-positions, register-priorities) pairs, sorted by use-positions. - */ - private UsePosList usePosList; - - /** - * Iterator used to traverse the ranges of an interval. - */ - private Range current; - - /** - * Link to next interval in a sorted list of intervals that ends with {@link #EndMarker}. - */ - Interval next; - - /** - * The linear-scan state of this interval. - */ - State state; - - private int cachedTo; // cached value: to of last range (-1: not cached) - - /** - * The interval from which this one is derived. If this is a {@linkplain #isSplitParent() split parent}, it points to itself. - */ - private Interval splitParent; - - /** - * List of all intervals that are split off from this interval. This is only used if this is a {@linkplain #isSplitParent() split parent}. - */ - private List splitChildren = Collections.emptyList(); - - /** - * Current split child that has been active or inactive last (always stored in split parents). - */ - private Interval currentSplitChild; - - /** - * Specifies if move is inserted between currentSplitChild and this interval when interval gets active the first time. - */ - private boolean insertMoveWhenActivated; - - /** - * For spill move optimization. - */ - private SpillState spillState; - - /** - * Position where this interval is defined (if defined only once). - */ - private int spillDefinitionPos; - - /** - * This interval should be assigned the same location as the hint interval. - */ - private Interval locationHint; - - void assignLocation(CiValue location) { - if (location.isRegister()) { - assert this.location == null : "cannot re-assign location for " + this; - if (location.kind == CiKind.Illegal && kind != CiKind.Illegal) { - location = location.asRegister().asValue(kind); - } - } else { - assert this.location == null || this.location.isRegister() : "cannot re-assign location for " + this; - assert location.isStackSlot(); - assert location.kind != CiKind.Illegal; - assert location.kind == this.kind; - } - this.location = location; - } - - /** - * Gets the {@linkplain CiRegisterValue register}, {@linkplain CiStackSlot spill slot} or {@linkplain CiAddress address} assigned to this interval. - */ - public CiValue location() { - return location; - } - - public CiKind kind() { - assert !operand.isRegister() : "cannot access type for fixed interval"; - return kind; - } - - void setKind(CiKind kind) { - assert operand.isRegister() || this.kind == CiKind.Illegal || this.kind == kind : "overwriting existing type"; - assert kind == kind.stackKind() || kind == CiKind.Short : "these kinds should have int type registers"; - this.kind = kind; - } - - public Range first() { - return first; - } - - int from() { - return first.from; - } - - int to() { - if (cachedTo == -1) { - cachedTo = calcTo(); - } - assert cachedTo == calcTo() : "invalid cached value"; - return cachedTo; - } - - int numUsePositions() { - return usePosList.size(); - } - - void setLocationHint(Interval interval) { - locationHint = interval; - } - - boolean isSplitParent() { - return splitParent == this; - } - - boolean isSplitChild() { - return splitParent != this; - } - - /** - * Gets the split parent for this interval. - */ - public Interval splitParent() { - assert splitParent.isSplitParent() : "not a split parent: " + this; - return splitParent; - } - - /** - * Gets the canonical spill slot for this interval. - */ - CiStackSlot spillSlot() { - return splitParent().spillSlot; - } - - void setSpillSlot(CiStackSlot slot) { - assert splitParent().spillSlot == null : "connot overwrite existing spill slot"; - splitParent().spillSlot = slot; - } - - Interval currentSplitChild() { - return splitParent().currentSplitChild; - } - - void makeCurrentSplitChild() { - splitParent().currentSplitChild = this; - } - - boolean insertMoveWhenActivated() { - return insertMoveWhenActivated; - } - - void setInsertMoveWhenActivated(boolean b) { - insertMoveWhenActivated = b; - } - - // for spill optimization - public SpillState spillState() { - return splitParent().spillState; - } - - int spillDefinitionPos() { - return splitParent().spillDefinitionPos; - } - - void setSpillState(SpillState state) { - assert state.ordinal() >= spillState().ordinal() : "state cannot decrease"; - splitParent().spillState = state; - } - - void setSpillDefinitionPos(int pos) { - assert spillDefinitionPos() == -1 : "cannot set the position twice"; - splitParent().spillDefinitionPos = pos; - } - - // returns true if this interval has a shadow copy on the stack that is always correct - boolean alwaysInMemory() { - return splitParent().spillState == SpillState.StoreAtDefinition || splitParent().spillState == SpillState.StartInMemory; - } - - void removeFirstUsePos() { - usePosList.removeLowestUsePos(); - } - - // test intersection - boolean intersects(Interval i) { - return first.intersects(i.first); - } - - int intersectsAt(Interval i) { - return first.intersectsAt(i.first); - } - - // range iteration - void rewindRange() { - current = first; - } - - void nextRange() { - assert this != EndMarker : "not allowed on sentinel"; - current = current.next; - } - - int currentFrom() { - return current.from; - } - - int currentTo() { - return current.to; - } - - boolean currentAtEnd() { - return current == Range.EndMarker; - } - - boolean currentIntersects(Interval it) { - return current.intersects(it.current); - } - - int currentIntersectsAt(Interval it) { - return current.intersectsAt(it.current); - } - - /** - * Sentinel interval to denote the end of an interval list. - */ - static final Interval EndMarker = new Interval(CiValue.IllegalValue, -1); - - Interval(CiValue operand, int operandNumber) { - GraalMetrics.LSRAIntervalsCreated++; - assert operand != null; - this.operand = operand; - this.operandNumber = operandNumber; - if (operand.isRegister()) { - location = operand; - } else { - assert operand.isIllegal() || operand.isVariable(); - } - this.kind = CiKind.Illegal; - this.first = Range.EndMarker; - this.usePosList = new UsePosList(4); - this.current = Range.EndMarker; - this.next = EndMarker; - this.cachedTo = -1; - this.spillState = SpillState.NoDefinitionFound; - this.spillDefinitionPos = -1; - splitParent = this; - currentSplitChild = this; - } - - int calcTo() { - assert first != Range.EndMarker : "interval has no range"; - - Range r = first; - while (r.next != Range.EndMarker) { - r = r.next; - } - return r.to; - } - - // consistency check of split-children - boolean checkSplitChildren() { - if (!splitChildren.isEmpty()) { - assert isSplitParent() : "only split parents can have children"; - - for (int i = 0; i < splitChildren.size(); i++) { - Interval i1 = splitChildren.get(i); - - assert i1.splitParent() == this : "not a split child of this interval"; - assert i1.kind() == kind() : "must be equal for all split children"; - assert i1.spillSlot() == spillSlot() : "must be equal for all split children"; - - for (int j = i + 1; j < splitChildren.size(); j++) { - Interval i2 = splitChildren.get(j); - - assert i1.operand != i2.operand : "same register number"; - - if (i1.from() < i2.from()) { - assert i1.to() <= i2.from() && i1.to() < i2.to() : "intervals overlapping"; - } else { - assert i2.from() < i1.from() : "intervals start at same opId"; - assert i2.to() <= i1.from() && i2.to() < i1.to() : "intervals overlapping"; - } - } - } - } - - return true; - } - - public Interval locationHint(boolean searchSplitChild, LinearScan allocator) { - if (!searchSplitChild) { - return locationHint; - } - - if (locationHint != null) { - assert locationHint.isSplitParent() : "ony split parents are valid hint registers"; - - if (locationHint.location != null && locationHint.location.isRegister()) { - return locationHint; - } else if (!locationHint.splitChildren.isEmpty()) { - // search the first split child that has a register assigned - int len = locationHint.splitChildren.size(); - for (int i = 0; i < len; i++) { - Interval interval = locationHint.splitChildren.get(i); - if (interval.location != null && interval.location.isRegister()) { - return interval; - } - } - } - } - - // no hint interval found that has a register assigned - return null; - } - - Interval getSplitChildAtOpId(int opId, LIRInstruction.OperandMode mode, LinearScan allocator) { - assert isSplitParent() : "can only be called for split parents"; - assert opId >= 0 : "invalid opId (method cannot be called for spill moves)"; - - if (splitChildren.isEmpty()) { - assert this.covers(opId, mode) : this + " does not cover " + opId; - return this; - } else { - Interval result = null; - int len = splitChildren.size(); - - // in outputMode, the end of the interval (opId == cur.to()) is not valid - int toOffset = (mode == LIRInstruction.OperandMode.Output ? 0 : 1); - - int i; - for (i = 0; i < len; i++) { - Interval cur = splitChildren.get(i); - if (cur.from() <= opId && opId < cur.to() + toOffset) { - if (i > 0) { - // exchange current split child to start of list (faster access for next call) - Util.atPutGrow(splitChildren, i, splitChildren.get(0), null); - Util.atPutGrow(splitChildren, 0, cur, null); - } - - // interval found - result = cur; - break; - } - } - - assert checkSplitChild(result, opId, allocator, toOffset, mode); - return result; - } - } - - private boolean checkSplitChild(Interval result, int opId, LinearScan allocator, int toOffset, LIRInstruction.OperandMode mode) { - if (result == null) { - // this is an error - StringBuilder msg = new StringBuilder(this.toString()).append(" has no child at ").append(opId); - if (!splitChildren.isEmpty()) { - Interval first = splitChildren.get(0); - Interval last = splitChildren.get(splitChildren.size() - 1); - msg.append(" (first = ").append(first).append(", last = ").append(last).append(")"); - } - throw new CiBailout("Linear Scan Error: " + msg); - } - - if (!splitChildren.isEmpty()) { - for (Interval interval : splitChildren) { - if (interval != result && interval.from() <= opId && opId < interval.to() + toOffset) { - TTY.println(String.format("two valid result intervals found for opId %d: %d and %d", opId, result.operandNumber, interval.operandNumber)); - TTY.println(result.logString(allocator)); - TTY.println(interval.logString(allocator)); - throw new CiBailout("two valid result intervals found"); - } - } - } - assert result.covers(opId, mode) : "opId not covered by interval"; - return true; - } - - // returns the last split child that ends before the given opId - Interval getSplitChildBeforeOpId(int opId) { - assert opId >= 0 : "invalid opId"; - - Interval parent = splitParent(); - Interval result = null; - - assert !parent.splitChildren.isEmpty() : "no split children available"; - int len = parent.splitChildren.size(); - - for (int i = len - 1; i >= 0; i--) { - Interval cur = parent.splitChildren.get(i); - if (cur.to() <= opId && (result == null || result.to() < cur.to())) { - result = cur; - } - } - - assert result != null : "no split child found"; - return result; - } - - // checks if opId is covered by any split child - boolean splitChildCovers(int opId, LIRInstruction.OperandMode mode) { - assert isSplitParent() : "can only be called for split parents"; - assert opId >= 0 : "invalid opId (method can not be called for spill moves)"; - - if (splitChildren.isEmpty()) { - // simple case if interval was not split - return covers(opId, mode); - - } else { - // extended case: check all split children - int len = splitChildren.size(); - for (int i = 0; i < len; i++) { - Interval cur = splitChildren.get(i); - if (cur.covers(opId, mode)) { - return true; - } - } - return false; - } - } - - // Note: use positions are sorted descending . first use has highest index - int firstUsage(RegisterPriority minRegisterPriority) { - assert operand.isVariable() : "cannot access use positions for fixed intervals"; - - for (int i = usePosList.size() - 1; i >= 0; --i) { - RegisterPriority registerPriority = usePosList.registerPriority(i); - if (registerPriority.greaterEqual(minRegisterPriority)) { - return usePosList.usePos(i); - } - } - return Integer.MAX_VALUE; - } - - int nextUsage(RegisterPriority minRegisterPriority, int from) { - assert operand.isVariable() : "cannot access use positions for fixed intervals"; - - for (int i = usePosList.size() - 1; i >= 0; --i) { - int usePos = usePosList.usePos(i); - if (usePos >= from && usePosList.registerPriority(i).greaterEqual(minRegisterPriority)) { - return usePos; - } - } - return Integer.MAX_VALUE; - } - - int nextUsageExact(RegisterPriority exactRegisterPriority, int from) { - assert operand.isVariable() : "cannot access use positions for fixed intervals"; - - for (int i = usePosList.size() - 1; i >= 0; --i) { - int usePos = usePosList.usePos(i); - if (usePos >= from && usePosList.registerPriority(i) == exactRegisterPriority) { - return usePos; - } - } - return Integer.MAX_VALUE; - } - - int previousUsage(RegisterPriority minRegisterPriority, int from) { - assert operand.isVariable() : "cannot access use positions for fixed intervals"; - - int prev = 0; - for (int i = usePosList.size() - 1; i >= 0; --i) { - int usePos = usePosList.usePos(i); - if (usePos > from) { - return prev; - } - if (usePosList.registerPriority(i).greaterEqual(minRegisterPriority)) { - prev = usePos; - } - } - return prev; - } - - void addUsePos(int pos, RegisterPriority registerPriority) { - assert covers(pos, LIRInstruction.OperandMode.Input) : "use position not covered by live range"; - - // do not add use positions for precolored intervals because they are never used - if (registerPriority != RegisterPriority.None && operand.isVariable()) { - if (GraalOptions.DetailedAsserts) { - for (int i = 0; i < usePosList.size(); i++) { - assert pos <= usePosList.usePos(i) : "already added a use-position with lower position"; - if (i > 0) { - assert usePosList.usePos(i) < usePosList.usePos(i - 1) : "not sorted descending"; - } - } - } - - // Note: addUse is called in descending order, so list gets sorted - // automatically by just appending new use positions - int len = usePosList.size(); - if (len == 0 || usePosList.usePos(len - 1) > pos) { - usePosList.add(pos, registerPriority); - } else if (usePosList.registerPriority(len - 1).lessThan(registerPriority)) { - assert usePosList.usePos(len - 1) == pos : "list not sorted correctly"; - usePosList.setRegisterPriority(len - 1, registerPriority); - } - } - } - - void addRange(int from, int to) { - assert from < to : "invalid range"; - assert first() == Range.EndMarker || to < first().next.from : "not inserting at begin of interval"; - assert from <= first().to : "not inserting at begin of interval"; - - if (first.from <= to) { - assert first != Range.EndMarker; - // join intersecting ranges - first.from = Math.min(from, first().from); - first.to = Math.max(to, first().to); - } else { - // insert new range - first = new Range(from, to, first()); - } - } - - Interval newSplitChild(LinearScan allocator) { - // allocate new interval - Interval parent = splitParent(); - Interval result = allocator.createDerivedInterval(parent); - result.setKind(kind()); - - result.splitParent = parent; - result.setLocationHint(parent); - - // insert new interval in children-list of parent - if (parent.splitChildren.isEmpty()) { - assert isSplitParent() : "list must be initialized at first split"; - - // Create new non-shared list - parent.splitChildren = new ArrayList(4); - parent.splitChildren.add(this); - } - parent.splitChildren.add(result); - - return result; - } - - /** - * Splits this interval at a specified position and returns the remainder as a new child interval - * of this interval's {@linkplain #splitParent() parent} interval. - *

- * When an interval is split, a bi-directional link is established between the original parent - * interval and the children intervals that are split off this interval. - * When a split child is split again, the new created interval is a direct child - * of the original parent. That is, there is no tree of split children stored, just a flat list. - * All split children are spilled to the same {@linkplain #spillSlot spill slot}. - * - * @param splitPos the position at which to split this interval - * @param allocator the register allocator context - * @return the child interval split off from this interval - */ - Interval split(int splitPos, LinearScan allocator) { - assert operand.isVariable() : "cannot split fixed intervals"; - - // allocate new interval - Interval result = newSplitChild(allocator); - - // split the ranges - Range prev = null; - Range cur = first; - while (cur != Range.EndMarker && cur.to <= splitPos) { - prev = cur; - cur = cur.next; - } - assert cur != Range.EndMarker : "split interval after end of last range"; - - if (cur.from < splitPos) { - result.first = new Range(splitPos, cur.to, cur.next); - cur.to = splitPos; - cur.next = Range.EndMarker; - - } else { - assert prev != null : "split before start of first range"; - result.first = cur; - prev.next = Range.EndMarker; - } - result.current = result.first; - cachedTo = -1; // clear cached value - - // split list of use positions - result.usePosList = usePosList.splitAt(splitPos); - - if (GraalOptions.DetailedAsserts) { - for (int i = 0; i < usePosList.size(); i++) { - assert usePosList.usePos(i) < splitPos; - } - for (int i = 0; i < result.usePosList.size(); i++) { - assert result.usePosList.usePos(i) >= splitPos; - } - } - return result; - } - - /** - * Splits this interval at a specified position and returns - * the head as a new interval (this interval is the tail). - * - * Currently, only the first range can be split, and the new interval must not have split positions - */ - Interval splitFromStart(int splitPos, LinearScan allocator) { - assert operand.isVariable() : "cannot split fixed intervals"; - assert splitPos > from() && splitPos < to() : "can only split inside interval"; - assert splitPos > first.from && splitPos <= first.to : "can only split inside first range"; - assert firstUsage(RegisterPriority.None) > splitPos : "can not split when use positions are present"; - - // allocate new interval - Interval result = newSplitChild(allocator); - - // the new interval has only one range (checked by assertion above, - // so the splitting of the ranges is very simple - result.addRange(first.from, splitPos); - - if (splitPos == first.to) { - assert first.next != Range.EndMarker : "must not be at end"; - first = first.next; - } else { - first.from = splitPos; - } - - return result; - } - - // returns true if the opId is inside the interval - boolean covers(int opId, LIRInstruction.OperandMode mode) { - Range cur = first; - - while (cur != Range.EndMarker && cur.to < opId) { - cur = cur.next; - } - if (cur != Range.EndMarker) { - assert cur.to != cur.next.from : "ranges not separated"; - - if (mode == LIRInstruction.OperandMode.Output) { - return cur.from <= opId && opId < cur.to; - } else { - return cur.from <= opId && opId <= cur.to; - } - } - return false; - } - - // returns true if the interval has any hole between holeFrom and holeTo - // (even if the hole has only the length 1) - boolean hasHoleBetween(int holeFrom, int holeTo) { - assert holeFrom < holeTo : "check"; - assert from() <= holeFrom && holeTo <= to() : "index out of interval"; - - Range cur = first; - while (cur != Range.EndMarker) { - assert cur.to < cur.next.from : "no space between ranges"; - - // hole-range starts before this range . hole - if (holeFrom < cur.from) { - return true; - - // hole-range completely inside this range . no hole - } else { - if (holeTo <= cur.to) { - return false; - - // overlapping of hole-range with this range . hole - } else { - if (holeFrom <= cur.to) { - return true; - } - } - } - - cur = cur.next; - } - - return false; - } - - @Override - public String toString() { - String from = "?"; - String to = "?"; - if (first != null && first != Range.EndMarker) { - from = String.valueOf(from()); - to = String.valueOf(to()); - } - String location = this.location == null ? "" : "@" + this.location.name(); - return operandNumber + ":" + operand + (operand.isRegister() ? "" : location) + "[" + from + "," + to + "]"; - } - - /** - * Gets the use position information for this interval. - */ - public UsePosList usePosList() { - return usePosList; - } - - /** - * Gets a single line string for logging the details of this interval to a log stream. - * - * @param allocator the register allocator context - */ - public String logString(LinearScan allocator) { - StringBuilder buf = new StringBuilder(100); - buf.append(operandNumber).append(':').append(operand).append(' '); - if (!operand.isRegister()) { - if (location != null) { - buf.append("location{").append(location).append("} "); - } - } - - buf.append("hints{").append(splitParent.operandNumber); - Interval hint = locationHint(false, allocator); - if (hint != null && hint.operandNumber != splitParent.operandNumber) { - buf.append(", ").append(hint.operandNumber); - } - buf.append("} ranges{"); - - // print ranges - Range cur = first; - while (cur != Range.EndMarker) { - if (cur != first) { - buf.append(", "); - } - buf.append(cur); - cur = cur.next; - assert cur != null : "range list not closed with range sentinel"; - } - buf.append("} uses{"); - - // print use positions - int prev = 0; - for (int i = usePosList.size() - 1; i >= 0; --i) { - assert prev < usePosList.usePos(i) : "use positions not sorted"; - if (i != usePosList.size() - 1) { - buf.append(", "); - } - buf.append(usePosList.usePos(i)).append(':').append(usePosList.registerPriority(i)); - prev = usePosList.usePos(i); - } - return buf.append("} spill-state{").append(spillState()).append("}").toString(); - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/alloc/IntervalWalker.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/alloc/IntervalWalker.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,248 +0,0 @@ -/* - * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.compiler.alloc; - -import com.oracle.max.graal.compiler.*; -import com.oracle.max.graal.compiler.alloc.Interval.RegisterBinding; -import com.oracle.max.graal.compiler.alloc.Interval.RegisterBindingLists; -import com.oracle.max.graal.compiler.alloc.Interval.State; -import com.oracle.max.graal.compiler.debug.*; - -/** - * - * @author Thomas Wuerthinger - */ -public class IntervalWalker { - - protected final GraalCompilation compilation; - protected final LinearScan allocator; - - /** - * Sorted list of intervals, not live before the current position. - */ - RegisterBindingLists unhandledLists; - - /** - * Sorted list of intervals, live at the current position. - */ - RegisterBindingLists activeLists; - - /** - * Sorted list of intervals in a life time hole at the current position. - */ - RegisterBindingLists inactiveLists; - - /** - * The current interval (taken from the unhandled list) being processed. - */ - protected Interval current; - - /** - * The current position (intercept point through the intervals). - */ - protected int currentPosition; - - /** - * The binding of the current interval being processed. - */ - protected RegisterBinding currentBinding; - - /** - * Processes the {@linkplain #current} interval in an attempt to allocate a physical - * register to it and thus allow it to be moved to a list of {@linkplain #activeLists active} intervals. - * - * @return {@code true} if a register was allocated to the {@linkplain #current} interval - */ - boolean activateCurrent() { - return true; - } - - void walkBefore(int lirOpId) { - walkTo(lirOpId - 1); - } - - void walk() { - walkTo(Integer.MAX_VALUE); - } - - /** - * Creates a new interval walker. - * - * @param allocator the register allocator context - * @param unhandledFixed the list of unhandled {@linkplain RegisterBinding#Fixed fixed} intervals - * @param unhandledAny the list of unhandled {@linkplain RegisterBinding#Any non-fixed} intervals - */ - IntervalWalker(LinearScan allocator, Interval unhandledFixed, Interval unhandledAny) { - this.compilation = allocator.compilation; - this.allocator = allocator; - - unhandledLists = new RegisterBindingLists(unhandledFixed, unhandledAny); - activeLists = new RegisterBindingLists(Interval.EndMarker, Interval.EndMarker); - inactiveLists = new RegisterBindingLists(Interval.EndMarker, Interval.EndMarker); - currentPosition = -1; - current = null; - nextInterval(); - } - - void removeFromList(Interval interval) { - if (interval.state == State.Active) { - activeLists.remove(RegisterBinding.Any, interval); - } else { - assert interval.state == State.Inactive : "invalid state"; - inactiveLists.remove(RegisterBinding.Any, interval); - } - } - - void walkTo(State state, int from) { - assert state == State.Active || state == State.Inactive : "wrong state"; - for (RegisterBinding binding : RegisterBinding.VALUES) { - Interval prevprev = null; - Interval prev = (state == State.Active) ? activeLists.get(binding) : inactiveLists.get(binding); - Interval next = prev; - while (next.currentFrom() <= from) { - Interval cur = next; - next = cur.next; - - boolean rangeHasChanged = false; - while (cur.currentTo() <= from) { - cur.nextRange(); - rangeHasChanged = true; - } - - // also handle move from inactive list to active list - rangeHasChanged = rangeHasChanged || (state == State.Inactive && cur.currentFrom() <= from); - - if (rangeHasChanged) { - // remove cur from list - if (prevprev == null) { - if (state == State.Active) { - activeLists.set(binding, next); - } else { - inactiveLists.set(binding, next); - } - } else { - prevprev.next = next; - } - prev = next; - if (cur.currentAtEnd()) { - // move to handled state (not maintained as a list) - cur.state = State.Handled; - intervalMoved(cur, binding, state, State.Handled); - } else if (cur.currentFrom() <= from) { - // sort into active list - activeLists.addToListSortedByCurrentFromPositions(binding, cur); - cur.state = State.Active; - if (prev == cur) { - assert state == State.Active : "check"; - prevprev = prev; - prev = cur.next; - } - intervalMoved(cur, binding, state, State.Active); - } else { - // sort into inactive list - inactiveLists.addToListSortedByCurrentFromPositions(binding, cur); - cur.state = State.Inactive; - if (prev == cur) { - assert state == State.Inactive : "check"; - prevprev = prev; - prev = cur.next; - } - intervalMoved(cur, binding, state, State.Inactive); - } - } else { - prevprev = prev; - prev = cur.next; - } - } - } - } - - void nextInterval() { - RegisterBinding binding; - Interval any = unhandledLists.any; - Interval fixed = unhandledLists.fixed; - - if (any != Interval.EndMarker) { - // intervals may start at same position . prefer fixed interval - binding = fixed != Interval.EndMarker && fixed.from() <= any.from() ? RegisterBinding.Fixed : RegisterBinding.Any; - - assert binding == RegisterBinding.Fixed && fixed.from() <= any.from() || binding == RegisterBinding.Any && any.from() <= fixed.from() : "wrong interval!!!"; - assert any == Interval.EndMarker || fixed == Interval.EndMarker || any.from() != fixed.from() || binding == RegisterBinding.Fixed : "if fixed and any-Interval start at same position, fixed must be processed first"; - - } else if (fixed != Interval.EndMarker) { - binding = RegisterBinding.Fixed; - } else { - current = null; - return; - } - currentBinding = binding; - current = unhandledLists.get(binding); - unhandledLists.set(binding, current.next); - current.next = Interval.EndMarker; - current.rewindRange(); - } - - void walkTo(int toOpId) { - assert currentPosition <= toOpId : "can not walk backwards"; - while (current != null) { - boolean isActive = current.from() <= toOpId; - int opId = isActive ? current.from() : toOpId; - - if (GraalOptions.TraceLinearScanLevel >= 2 && !TTY.isSuppressed()) { - if (currentPosition < opId) { - TTY.println(); - TTY.println("walkTo(%d) *", opId); - } - } - - // set currentPosition prior to call of walkTo - currentPosition = opId; - - // call walkTo even if currentPosition == id - walkTo(State.Active, opId); - walkTo(State.Inactive, opId); - - if (isActive) { - current.state = State.Active; - if (activateCurrent()) { - activeLists.addToListSortedByCurrentFromPositions(currentBinding, current); - intervalMoved(current, currentBinding, State.Unhandled, State.Active); - } - - nextInterval(); - } else { - return; - } - } - } - - private void intervalMoved(Interval interval, RegisterBinding kind, State from, State to) { - // intervalMoved() is called whenever an interval moves from one interval list to another. - // In the implementation of this method it is prohibited to move the interval to any list. - if (GraalOptions.TraceLinearScanLevel >= 4 && !TTY.isSuppressed()) { - TTY.print(from.toString() + " to " + to.toString()); - TTY.fillTo(23); - TTY.out().println(interval.logString(allocator)); - } - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/alloc/LIRInsertionBuffer.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/alloc/LIRInsertionBuffer.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,136 +0,0 @@ -/* - * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.compiler.alloc; - -import java.util.*; - -import com.oracle.max.graal.compiler.lir.*; -import com.oracle.max.graal.compiler.util.*; -import com.sun.cri.ci.*; - -/** - * - * @author Thomas Wuerthinger - */ -public final class LIRInsertionBuffer { - - private LIRList lir; // the lir list where ops of this buffer should be inserted later (null when uninitialized) - - // list of insertion points. index and count are stored alternately: - // indexAndCount[i * 2]: the index into lir list where "count" ops should be inserted - // indexAndCount[i * 2 + 1]: the number of ops to be inserted at index - private final IntList indexAndCount; - - // the LIROps to be inserted - private final List ops; - - private void appendNew(int index, int count) { - indexAndCount.add(index); - indexAndCount.add(count); - } - - private void setCountAt(int i, int value) { - indexAndCount.set((i << 1) + 1, value); - } - - LIRInsertionBuffer() { - ops = new ArrayList(8); - indexAndCount = new IntList(8); - } - - // must be called before using the insertion buffer - void init(LIRList lir) { - assert !initialized() : "already initialized"; - this.lir = lir; - indexAndCount.clear(); - ops.clear(); - } - - boolean initialized() { - return lir != null; - } - - // called automatically when the buffer is appended to the LIRList - public void finish() { - lir = null; - } - - // accessors - public LIRList lirList() { - return lir; - } - - public int numberOfInsertionPoints() { - return indexAndCount.size() >> 1; - } - - public int indexAt(int i) { - return indexAndCount.get((i << 1)); - } - - public int countAt(int i) { - return indexAndCount.get((i << 1) + 1); - } - - public int numberOfOps() { - return ops.size(); - } - - public LIRInstruction opAt(int i) { - return ops.get(i); - } - - void move(int index, CiValue src, CiValue dst, LIRDebugInfo info) { - append(index, new LIROp1(LIROpcode.Move, src, dst, dst.kind, info)); - } - - // Implementation of LIRInsertionBuffer - - private void append(int index, LIRInstruction op) { - assert indexAndCount.size() % 2 == 0 : "must have a count for each index"; - - int i = numberOfInsertionPoints() - 1; - if (i < 0 || indexAt(i) < index) { - appendNew(index, 1); - } else { - assert indexAt(i) == index : "can append LIROps in ascending order only"; - assert countAt(i) > 0 : "check"; - setCountAt(i, countAt(i) + 1); - } - ops.add(op); - - assert verify(); - } - - private boolean verify() { - int sum = 0; - int prevIdx = -1; - - for (int i = 0; i < numberOfInsertionPoints(); i++) { - assert prevIdx < indexAt(i) : "index must be ordered ascending"; - sum += countAt(i); - } - assert sum == numberOfOps() : "wrong total sum"; - return true; - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/alloc/LinearScan.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/alloc/LinearScan.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,2421 +0,0 @@ -/* - * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.compiler.alloc; - -import static com.sun.cri.ci.CiUtil.*; -import static java.lang.reflect.Modifier.*; - -import java.util.*; -import java.util.Map.Entry; - -import com.oracle.max.graal.compiler.*; -import com.oracle.max.graal.compiler.alloc.Interval.RegisterBinding; -import com.oracle.max.graal.compiler.alloc.Interval.RegisterPriority; -import com.oracle.max.graal.compiler.alloc.Interval.SpillState; -import com.oracle.max.graal.compiler.debug.*; -import com.oracle.max.graal.compiler.gen.*; -import com.oracle.max.graal.compiler.graph.*; -import com.oracle.max.graal.compiler.lir.*; -import com.oracle.max.graal.compiler.lir.LIRInstruction.OperandMode; -import com.oracle.max.graal.compiler.observer.*; -import com.oracle.max.graal.compiler.util.*; -import com.oracle.max.graal.extensions.*; -import com.oracle.max.graal.graph.*; -import com.oracle.max.graal.nodes.*; -import com.oracle.max.graal.nodes.FrameState.ValueProcedure; -import com.oracle.max.graal.nodes.calc.*; -import com.oracle.max.graal.nodes.virtual.*; -import com.sun.cri.ci.*; -import com.sun.cri.ri.*; - -/** - * An implementation of the linear scan register allocator algorithm described - * in "Optimized Interval Splitting in a Linear Scan Register Allocator" - * by Christian Wimmer and Hanspeter Moessenboeck. - * - * @author Christian Wimmer (original HotSpot implementation) - * @author Thomas Wuerthinger - * @author Doug Simon - */ -public final class LinearScan { - - final GraalCompilation compilation; - final IR ir; - final LIRGenerator gen; - final FrameMap frameMap; - final RiRegisterAttributes[] registerAttributes; - final CiRegister[] registers; - - private static final int INITIAL_SPLIT_INTERVALS_CAPACITY = 32; - - /** - * List of blocks in linear-scan order. This is only correct as long as the CFG does not change. - */ - final LIRBlock[] sortedBlocks; - - final OperandPool operands; - - /** - * Number of stack slots used for intervals allocated to memory. - */ - int maxSpills; - - /** - * Unused spill slot for a single-word value because of alignment of a double-word value. - */ - CiStackSlot unusedSpillSlot; - - /** - * Map from {@linkplain #operandNumber(CiValue) operand numbers} to intervals. - */ - Interval[] intervals; - - /** - * The number of valid entries in {@link #intervals}. - */ - int intervalsSize; - - /** - * The index of the first entry in {@link #intervals} for a {@linkplain #createDerivedInterval(Interval) derived interval}. - */ - int firstDerivedIntervalIndex = -1; - - /** - * Intervals sorted by {@link Interval#from()}. - */ - Interval[] sortedIntervals; - - /** - * Map from an instruction {@linkplain LIRInstruction#id id} to the instruction. - * Entries should be retrieved with {@link #instructionForId(int)} as the id is - * not simply an index into this array. - */ - LIRInstruction[] opIdToInstructionMap; - - /** - * Map from an instruction {@linkplain LIRInstruction#id id} to the {@linkplain - * LIRBlock block} containing the instruction. Entries should be retrieved with - * {@link #blockForId(int)} as the id is not simply an index into this array. - */ - LIRBlock[] opIdToBlockMap; - - /** - * Bit set for each variable that is contained in each loop. - */ - BitMap2D intervalInLoop; - - public LinearScan(GraalCompilation compilation, IR ir, LIRGenerator gen, FrameMap frameMap) { - this.compilation = compilation; - this.ir = ir; - this.gen = gen; - this.frameMap = frameMap; - this.maxSpills = frameMap.initialSpillSlot(); - this.unusedSpillSlot = null; - this.sortedBlocks = ir.linearScanOrder().toArray(new LIRBlock[ir.linearScanOrder().size()]); - CiRegister[] allocatableRegisters = compilation.registerConfig.getAllocatableRegisters(); - this.registers = new CiRegister[CiRegister.maxRegisterNumber(allocatableRegisters) + 1]; - for (CiRegister reg : allocatableRegisters) { - registers[reg.number] = reg; - } - this.registerAttributes = compilation.registerConfig.getAttributesMap(); - this.operands = gen.operands; - } - - /** - * Converts an operand (variable or register) to an index in a flat address space covering all the - * {@linkplain CiVariable variables} and {@linkplain CiRegisterValue registers} being processed by this - * allocator. - */ - int operandNumber(CiValue operand) { - return operands.operandNumber(operand); - } - - static final IntervalPredicate IS_PRECOLORED_INTERVAL = new IntervalPredicate() { - @Override - public boolean apply(Interval i) { - return i.operand.isRegister(); - } - }; - - static final IntervalPredicate IS_VARIABLE_INTERVAL = new IntervalPredicate() { - @Override - public boolean apply(Interval i) { - return i.operand.isVariable(); - } - }; - - static final IntervalPredicate IS_OOP_INTERVAL = new IntervalPredicate() { - @Override - public boolean apply(Interval i) { - return !i.operand.isRegister() && i.kind() == CiKind.Object; - } - }; - - /** - * Gets an object describing the attributes of a given register according to this register configuration. - */ - RiRegisterAttributes attributes(CiRegister reg) { - return registerAttributes[reg.number]; - } - - /** - * Allocates the next available spill slot for a value of a given kind. - */ - CiStackSlot allocateSpillSlot(CiKind kind) { - CiStackSlot spillSlot; - if (numberOfSpillSlots(kind) == 2) { - if (isOdd(maxSpills)) { - // alignment of double-slot values - // the hole because of the alignment is filled with the next single-slot value - assert unusedSpillSlot == null : "wasting a spill slot"; - unusedSpillSlot = CiStackSlot.get(kind, maxSpills); - maxSpills++; - } - spillSlot = CiStackSlot.get(kind, maxSpills); - maxSpills += 2; - } else if (unusedSpillSlot != null) { - // re-use hole that was the result of a previous double-word alignment - spillSlot = unusedSpillSlot; - unusedSpillSlot = null; - } else { - spillSlot = CiStackSlot.get(kind, maxSpills); - maxSpills++; - } - - return spillSlot; - } - - void assignSpillSlot(Interval interval) { - // assign the canonical spill slot of the parent (if a part of the interval - // is already spilled) or allocate a new spill slot - if (interval.spillSlot() != null) { - interval.assignLocation(interval.spillSlot()); - } else { - CiStackSlot slot = allocateSpillSlot(interval.kind()); - interval.setSpillSlot(slot); - interval.assignLocation(slot); - } - } - - /** - * Creates a new interval. - * - * @param operand the operand for the interval - * @return the created interval - */ - Interval createInterval(CiValue operand) { - assert isProcessed(operand); - assert operand.isLegal(); - int operandNumber = operandNumber(operand); - Interval interval = new Interval(operand, operandNumber); - assert operandNumber < intervalsSize; - assert intervals[operandNumber] == null; - intervals[operandNumber] = interval; - return interval; - } - - /** - * Creates an interval as a result of splitting or spilling another interval. - * - * @param source an interval being split of spilled - * @return a new interval derived from {@code source} - */ - Interval createDerivedInterval(Interval source) { - if (firstDerivedIntervalIndex == -1) { - firstDerivedIntervalIndex = intervalsSize; - } - if (intervalsSize == intervals.length) { - intervals = Arrays.copyOf(intervals, intervals.length * 2); - } - intervalsSize++; - Interval interval = createInterval(operands.newVariable(source.kind())); - assert intervals[intervalsSize - 1] == interval; - return interval; - } - - // copy the variable flags if an interval is split - void copyRegisterFlags(Interval from, Interval to) { - if (operands.mustBeByteRegister(from.operand)) { - operands.setMustBeByteRegister((CiVariable) to.operand); - } - - // Note: do not copy the mustStartInMemory flag because it is not necessary for child - // intervals (only the very beginning of the interval must be in memory) - } - - // access to block list (sorted in linear scan order) - int blockCount() { - assert sortedBlocks.length == ir.linearScanOrder().size() : "invalid cached block list"; - return sortedBlocks.length; - } - - LIRBlock blockAt(int index) { - assert sortedBlocks[index] == ir.linearScanOrder().get(index) : "invalid cached block list"; - return sortedBlocks[index]; - } - - /** - * Gets the size of the {@link LIRBlock#liveIn} and {@link LIRBlock#liveOut} sets for a basic block. These sets do - * not include any operands allocated as a result of creating {@linkplain #createDerivedInterval(Interval) derived - * intervals}. - */ - int liveSetSize() { - return firstDerivedIntervalIndex == -1 ? operands.size() : firstDerivedIntervalIndex; - } - - int numLoops() { - return ir.numLoops(); - } - - boolean isIntervalInLoop(int interval, int loop) { - return intervalInLoop.at(interval, loop); - } - - Interval intervalFor(CiValue operand) { - int operandNumber = operandNumber(operand); - assert operandNumber < intervalsSize; - return intervals[operandNumber]; - } - - /** - * Gets the highest instruction id allocated by this object. - */ - int maxOpId() { - assert opIdToInstructionMap.length > 0 : "no operations"; - return (opIdToInstructionMap.length - 1) << 1; - } - - /** - * Converts an {@linkplain LIRInstruction#id instruction id} to an instruction index. - * All LIR instructions in a method have an index one greater than their linear-scan order predecesor - * with the first instruction having an index of 0. - */ - static int opIdToIndex(int opId) { - return opId >> 1; - } - - /** - * Retrieves the {@link LIRInstruction} based on its {@linkplain LIRInstruction#id id}. - * - * @param opId an instruction {@linkplain LIRInstruction#id id} - * @return the instruction whose {@linkplain LIRInstruction#id} {@code == id} - */ - LIRInstruction instructionForId(int opId) { - assert isEven(opId) : "opId not even"; - LIRInstruction instr = opIdToInstructionMap[opIdToIndex(opId)]; - assert instr.id() == opId; - return instr; - } - - /** - * Gets the block containing a given instruction. - * - * @param opId an instruction {@linkplain LIRInstruction#id id} - * @return the block containing the instruction denoted by {@code opId} - */ - LIRBlock blockForId(int opId) { - assert opIdToBlockMap.length > 0 && opId >= 0 && opId <= maxOpId() + 1 : "opId out of range"; - return opIdToBlockMap[opIdToIndex(opId)]; - } - - boolean isBlockBegin(int opId) { - return opId == 0 || blockForId(opId) != blockForId(opId - 1); - } - - boolean coversBlockBegin(int opId1, int opId2) { - return blockForId(opId1) != blockForId(opId2); - } - - /** - * Determines if an {@link LIRInstruction} destroys all caller saved registers. - * - * @param opId an instruction {@linkplain LIRInstruction#id id} - * @return {@code true} if the instruction denoted by {@code id} destroys all caller saved registers. - */ - boolean hasCall(int opId) { - assert isEven(opId) : "opId not even"; - return instructionForId(opId).hasCall; - } - - /** - * Eliminates moves from register to stack if the stack slot is known to be correct. - */ - void changeSpillDefinitionPos(Interval interval, int defPos) { - assert interval.isSplitParent() : "can only be called for split parents"; - - switch (interval.spillState()) { - case NoDefinitionFound: - assert interval.spillDefinitionPos() == -1 : "must no be set before"; - interval.setSpillDefinitionPos(defPos); - interval.setSpillState(SpillState.NoSpillStore); - break; - - case NoSpillStore: - assert defPos <= interval.spillDefinitionPos() : "positions are processed in reverse order when intervals are created"; - if (defPos < interval.spillDefinitionPos() - 2 || instructionForId(interval.spillDefinitionPos()).code == LIROpcode.Xir) { - // second definition found, so no spill optimization possible for this interval - interval.setSpillState(SpillState.NoOptimization); - } else { - // two consecutive definitions (because of two-operand LIR form) - assert blockForId(defPos) == blockForId(interval.spillDefinitionPos()) : "block must be equal"; - } - break; - - case NoOptimization: - // nothing to do - break; - - default: - throw new CiBailout("other states not allowed at this time"); - } - } - - // called during register allocation - void changeSpillState(Interval interval, int spillPos) { - switch (interval.spillState()) { - case NoSpillStore: { - int defLoopDepth = blockForId(interval.spillDefinitionPos()).loopDepth(); - int spillLoopDepth = blockForId(spillPos).loopDepth(); - - if (defLoopDepth < spillLoopDepth) { - // the loop depth of the spilling position is higher then the loop depth - // at the definition of the interval . move write to memory out of loop - // by storing at definitin of the interval - interval.setSpillState(SpillState.StoreAtDefinition); - } else { - // the interval is currently spilled only once, so for now there is no - // reason to store the interval at the definition - interval.setSpillState(SpillState.OneSpillStore); - } - break; - } - - case OneSpillStore: { - // the interval is spilled more then once, so it is better to store it to - // memory at the definition - interval.setSpillState(SpillState.StoreAtDefinition); - break; - } - - case StoreAtDefinition: - case StartInMemory: - case NoOptimization: - case NoDefinitionFound: - // nothing to do - break; - - default: - throw new CiBailout("other states not allowed at this time"); - } - } - - abstract static class IntervalPredicate { - abstract boolean apply(Interval i); - } - - private static final IntervalPredicate mustStoreAtDefinition = new IntervalPredicate() { - @Override - public boolean apply(Interval i) { - return i.isSplitParent() && i.spillState() == SpillState.StoreAtDefinition; - } - }; - - // called once before assignment of register numbers - void eliminateSpillMoves() { - if (GraalOptions.TraceLinearScanLevel >= 3) { - TTY.println(" Eliminating unnecessary spill moves"); - } - - // collect all intervals that must be stored after their definition. - // the list is sorted by Interval.spillDefinitionPos - Interval interval; - interval = createUnhandledLists(mustStoreAtDefinition, null).first; - if (GraalOptions.DetailedAsserts) { - checkIntervals(interval); - } - - LIRInsertionBuffer insertionBuffer = new LIRInsertionBuffer(); - int numBlocks = blockCount(); - for (int i = 0; i < numBlocks; i++) { - LIRBlock block = blockAt(i); - List instructions = block.lir().instructionsList(); - int numInst = instructions.size(); - boolean hasNew = false; - - // iterate all instructions of the block. skip the first because it is always a label - for (int j = 1; j < numInst; j++) { - LIRInstruction op = instructions.get(j); - int opId = op.id(); - - if (opId == -1) { - CiValue resultOperand = op.result(); - // remove move from register to stack if the stack slot is guaranteed to be correct. - // only moves that have been inserted by LinearScan can be removed. - assert op.code == LIROpcode.Move : "only moves can have a opId of -1"; - assert resultOperand.isVariable() : "LinearScan inserts only moves to variables"; - - LIROp1 op1 = (LIROp1) op; - Interval curInterval = intervalFor(resultOperand); - - if (!curInterval.location().isRegister() && curInterval.alwaysInMemory()) { - // move target is a stack slot that is always correct, so eliminate instruction - if (GraalOptions.TraceLinearScanLevel >= 4) { - TTY.println("eliminating move from interval %d to %d", operandNumber(op1.operand()), operandNumber(op1.result())); - } - instructions.set(j, null); // null-instructions are deleted by assignRegNum - } - - } else { - // insert move from register to stack just after the beginning of the interval - assert interval == Interval.EndMarker || interval.spillDefinitionPos() >= opId : "invalid order"; - assert interval == Interval.EndMarker || (interval.isSplitParent() && interval.spillState() == SpillState.StoreAtDefinition) : "invalid interval"; - - while (interval != Interval.EndMarker && interval.spillDefinitionPos() == opId) { - if (!hasNew) { - // prepare insertion buffer (appended when all instructions of the block are processed) - insertionBuffer.init(block.lir()); - hasNew = true; - } - - CiValue fromLocation = interval.location(); - CiValue toLocation = canonicalSpillOpr(interval); - - assert fromLocation.isRegister() : "from operand must be a register but is: " + fromLocation + " toLocation=" + toLocation + " spillState=" + interval.spillState(); - assert toLocation.isStackSlot() : "to operand must be a stack slot"; - - insertionBuffer.move(j, fromLocation, toLocation, null); - - if (GraalOptions.TraceLinearScanLevel >= 4) { - CiStackSlot slot = interval.spillSlot(); - TTY.println("inserting move after definition of interval %d to stack slot %d%s at opId %d", - interval.operandNumber, slot.index(), slot.inCallerFrame() ? " in caller frame" : "", opId); - } - - interval = interval.next; - } - } - } // end of instruction iteration - - if (hasNew) { - block.lir().append(insertionBuffer); - } - } // end of block iteration - - assert interval == Interval.EndMarker : "missed an interval"; - } - - private void checkIntervals(Interval interval) { - Interval prev = null; - Interval temp = interval; - while (temp != Interval.EndMarker) { - assert temp.spillDefinitionPos() > 0 : "invalid spill definition pos"; - if (prev != null) { - assert temp.from() >= prev.from() : "intervals not sorted"; - assert temp.spillDefinitionPos() >= prev.spillDefinitionPos() : "when intervals are sorted by from : then they must also be sorted by spillDefinitionPos"; - } - - assert temp.spillSlot() != null : "interval has no spill slot assigned"; - assert temp.spillDefinitionPos() >= temp.from() : "invalid order"; - assert temp.spillDefinitionPos() <= temp.from() + 2 : "only intervals defined once at their start-pos can be optimized"; - - if (GraalOptions.TraceLinearScanLevel >= 4) { - TTY.println("interval %d (from %d to %d) must be stored at %d", temp.operandNumber, temp.from(), temp.to(), temp.spillDefinitionPos()); - } - - prev = temp; - temp = temp.next; - } - } - - /** - * Numbers all instructions in all blocks. The numbering follows the {@linkplain ComputeLinearScanOrder linear scan order}. - */ - void numberInstructions() { - // Assign IDs to LIR nodes and build a mapping, lirOps, from ID to LIRInstruction node. - int numBlocks = blockCount(); - int numInstructions = 0; - for (int i = 0; i < numBlocks; i++) { - numInstructions += blockAt(i).lir().instructionsList().size(); - } - - // initialize with correct length - opIdToInstructionMap = new LIRInstruction[numInstructions]; - opIdToBlockMap = new LIRBlock[numInstructions]; - - int opId = 0; - int index = 0; - - for (int i = 0; i < numBlocks; i++) { - LIRBlock block = blockAt(i); - block.setFirstLirInstructionId(opId); - List instructions = block.lir().instructionsList(); - - int numInst = instructions.size(); - for (int j = 0; j < numInst; j++) { - LIRInstruction op = instructions.get(j); - op.setId(opId); - - opIdToInstructionMap[index] = op; - opIdToBlockMap[index] = block; - assert instructionForId(opId) == op : "must match"; - - index++; - opId += 2; // numbering of lirOps by two - } - block.setLastLirInstructionId((opId - 2)); - } - assert index == numInstructions : "must match"; - assert (index << 1) == opId : "must match: " + (index << 1); - } - - /** - * Computes local live sets (i.e. {@link LIRBlock#liveGen} and {@link LIRBlock#liveKill}) separately for each block. - */ - void computeLocalLiveSets() { - int numBlocks = blockCount(); - int liveSize = liveSetSize(); - - BitMap2D localIntervalInLoop = new BitMap2D(operands.size(), numLoops()); - - // iterate all blocks - for (int i = 0; i < numBlocks; i++) { - LIRBlock block = blockAt(i); - final BitMap liveGen = new BitMap(liveSize); - final BitMap liveKill = new BitMap(liveSize); - - List instructions = block.lir().instructionsList(); - int numInst = instructions.size(); - - // iterate all instructions of the block. skip the first because it is always a label - assert !instructions.get(0).hasOperands() : "first operation must always be a label"; - for (int j = 1; j < numInst; j++) { - final LIRInstruction op = instructions.get(j); - - // iterate input operands of instruction - int n = op.operandCount(LIRInstruction.OperandMode.Input); - for (int k = 0; k < n; k++) { - CiValue operand = op.operandAt(LIRInstruction.OperandMode.Input, k); - - if (operand.isVariable()) { - int operandNum = operandNumber(operand); - if (!liveKill.get(operandNum)) { - liveGen.set(operandNum); - if (GraalOptions.TraceLinearScanLevel >= 4) { - TTY.println(" Setting liveGen for operand %d at instruction %d", operandNum, op.id()); - } - } - if (block.loopIndex() >= 0) { - localIntervalInLoop.setBit(operandNum, block.loopIndex()); - } - } - - if (GraalOptions.DetailedAsserts) { - assert operand.isVariableOrRegister() : "visitor should only return register operands"; - verifyInput(block, liveKill, operand); - } - } - - // Add uses of live locals from interpreter's point of view for proper debug information generation - LIRDebugInfo info = op.info; - if (info != null) { - assert info.state != null; - info.state.forEachLiveStateValue(new ValueProcedure() { - public void doValue(ValueNode value) { - CiValue operand = value.operand(); - if (operand.isVariable()) { - int operandNum = operandNumber(operand); - if (!liveKill.get(operandNum)) { - liveGen.set(operandNum); - if (GraalOptions.TraceLinearScanLevel >= 4) { - TTY.println(" Setting liveGen for value %s, LIR opId %d, operand %d because of state for %s", ValueUtil.valueString(value), op.id(), operandNum, op); - } - } - } else if (operand.isRegister()) { - assert !isProcessed(operand) && !operand.kind.isObject(); - } else { - assert operand.isConstant() || operand.isIllegal() : "invalid operand for deoptimization value: " + value; - } - } - }); - } - - // iterate temp operands of instruction - n = op.operandCount(LIRInstruction.OperandMode.Temp); - for (int k = 0; k < n; k++) { - CiValue operand = op.operandAt(LIRInstruction.OperandMode.Temp, k); - - if (operand.isVariable()) { - int varNum = operandNumber(operand); - liveKill.set(varNum); - if (block.loopIndex() >= 0) { - localIntervalInLoop.setBit(varNum, block.loopIndex()); - } - } - - if (GraalOptions.DetailedAsserts) { - assert operand.isVariableOrRegister() : "visitor should only return register operands"; - verifyTemp(liveKill, operand); - } - } - - // iterate output operands of instruction - n = op.operandCount(LIRInstruction.OperandMode.Output); - for (int k = 0; k < n; k++) { - CiValue operand = op.operandAt(LIRInstruction.OperandMode.Output, k); - - if (operand.isVariable()) { - int varNum = operandNumber(operand); - liveKill.set(varNum); - if (block.loopIndex() >= 0) { - localIntervalInLoop.setBit(varNum, block.loopIndex()); - } - } - - if (GraalOptions.DetailedAsserts) { - assert operand.isVariableOrRegister() : "visitor should only return register operands"; - // fixed intervals are never live at block boundaries, so - // they need not be processed in live sets - // process them only in debug mode so that this can be checked - verifyTemp(liveKill, operand); - } - } - } // end of instruction iteration - - block.liveGen = liveGen; - block.liveKill = liveKill; - block.liveIn = new BitMap(liveSize); - block.liveOut = new BitMap(liveSize); - - if (GraalOptions.TraceLinearScanLevel >= 4) { - TTY.println("liveGen B%d %s", block.blockID(), block.liveGen); - TTY.println("liveKill B%d %s", block.blockID(), block.liveKill); - } - } // end of block iteration - - intervalInLoop = localIntervalInLoop; - } - - private void verifyTemp(BitMap liveKill, CiValue operand) { - // fixed intervals are never live at block boundaries, so - // they need not be processed in live sets - // process them only in debug mode so that this can be checked - if (!operand.isVariable()) { - if (isProcessed(operand)) { - liveKill.set(operandNumber(operand)); - } - } - } - - private void verifyInput(LIRBlock block, BitMap liveKill, CiValue operand) { - // fixed intervals are never live at block boundaries, so - // they need not be processed in live sets. - // this is checked by these assertions to be sure about it. - // the entry block may have incoming - // values in registers, which is ok. - if (!operand.isVariable() && block != ir.startBlock) { - if (isProcessed(operand)) { - assert liveKill.get(operandNumber(operand)) : "using fixed register that is not defined in this block"; - } - } - } - - /** - * Performs a backward dataflow analysis to compute global live sets (i.e. {@link LIRBlock#liveIn} and - * {@link LIRBlock#liveOut}) for each block. - */ - void computeGlobalLiveSets() { - int numBlocks = blockCount(); - boolean changeOccurred; - boolean changeOccurredInBlock; - int iterationCount = 0; - BitMap liveOut = new BitMap(liveSetSize()); // scratch set for calculations - - // Perform a backward dataflow analysis to compute liveOut and liveIn for each block. - // The loop is executed until a fixpoint is reached (no changes in an iteration) - do { - changeOccurred = false; - - // iterate all blocks in reverse order - for (int i = numBlocks - 1; i >= 0; i--) { - LIRBlock block = blockAt(i); - - changeOccurredInBlock = false; - - // liveOut(block) is the union of liveIn(sux), for successors sux of block - int n = block.numberOfSux(); - if (n > 0) { - // block has successors - if (n > 0) { - liveOut.setFrom(block.suxAt(0).liveIn); - for (int j = 1; j < n; j++) { - liveOut.setUnion(block.suxAt(j).liveIn); - } - } else { - liveOut.clearAll(); - } - - if (!block.liveOut.isSame(liveOut)) { - // A change occurred. Swap the old and new live out sets to avoid copying. - BitMap temp = block.liveOut; - block.liveOut = liveOut; - liveOut = temp; - - changeOccurred = true; - changeOccurredInBlock = true; - } - } - - if (iterationCount == 0 || changeOccurredInBlock) { - // liveIn(block) is the union of liveGen(block) with (liveOut(block) & !liveKill(block)) - // note: liveIn has to be computed only in first iteration or if liveOut has changed! - BitMap liveIn = block.liveIn; - liveIn.setFrom(block.liveOut); - liveIn.setDifference(block.liveKill); - liveIn.setUnion(block.liveGen); - } - - if (GraalOptions.TraceLinearScanLevel >= 4) { - traceLiveness(changeOccurredInBlock, iterationCount, block); - } - } - iterationCount++; - - if (changeOccurred && iterationCount > 50) { - throw new CiBailout("too many iterations in computeGlobalLiveSets"); - } - } while (changeOccurred); - - if (GraalOptions.DetailedAsserts) { - verifyLiveness(numBlocks); - } - - // check that the liveIn set of the first block is empty - LIRBlock startBlock = ir.startBlock; - BitMap liveInArgs = new BitMap(startBlock.liveIn.size()); - if (!startBlock.liveIn.isSame(liveInArgs)) { - if (GraalOptions.DetailedAsserts) { - reportFailure(numBlocks); - } - - TTY.println("preds=" + startBlock.blockPredecessors().size() + ", succs=" + startBlock.blockSuccessors().size()); - TTY.println("startBlock-ID: " + startBlock.blockID()); - - // bailout of if this occurs in product mode. - throw new CiBailout("liveIn set of first block must be empty"); - } - } - - private void reportFailure(int numBlocks) { - TTY.println(compilation.method.toString()); - TTY.println("Error: liveIn set of first block must be empty (when this fails, variables are used before they are defined)"); - TTY.print("affected registers:"); - TTY.println(ir.startBlock.liveIn.toString()); - - // print some additional information to simplify debugging - for (int operandNum = 0; operandNum < ir.startBlock.liveIn.size(); operandNum++) { - if (ir.startBlock.liveIn.get(operandNum)) { - CiValue operand = operands.operandFor(operandNum); - ValueNode instr = operand.isVariable() ? gen.operands.instructionForResult(((CiVariable) operand)) : null; - TTY.println(" var %d (HIR instruction %s)", operandNum, instr == null ? " " : instr.toString()); - - if (instr instanceof PhiNode) { - PhiNode phi = (PhiNode) instr; - TTY.println("phi block begin: " + phi.merge()); - TTY.println("pred count on blockbegin: " + phi.merge().phiPredecessorCount()); - TTY.println("phi values: " + phi.valueCount()); - TTY.println("phi block preds:"); - for (EndNode n : phi.merge().cfgPredecessors()) { - TTY.println(n.toString()); - } - } - - for (int j = 0; j < numBlocks; j++) { - LIRBlock block = blockAt(j); - if (block.liveGen.get(operandNum)) { - TTY.println(" used in block B%d", block.blockID()); - for (LIRInstruction ins : block.lir().instructionsList()) { - TTY.println(ins.id() + ": " + ins.result() + " " + ins.toString()); - } - } - if (block.liveKill.get(operandNum)) { - TTY.println(" defined in block B%d", block.blockID()); - for (LIRInstruction ins : block.lir().instructionsList()) { - TTY.println(ins.id() + ": " + ins.result() + " " + ins.toString()); - } - } - } - } - } - } - - private void verifyLiveness(int numBlocks) { - // check that fixed intervals are not live at block boundaries - // (live set must be empty at fixed intervals) - for (int i = 0; i < numBlocks; i++) { - LIRBlock block = blockAt(i); - for (int j = 0; j <= operands.maxRegisterNumber(); j++) { - assert !block.liveIn.get(j) : "liveIn set of fixed register must be empty"; - assert !block.liveOut.get(j) : "liveOut set of fixed register must be empty"; - assert !block.liveGen.get(j) : "liveGen set of fixed register must be empty"; - } - } - } - - private void traceLiveness(boolean changeOccurredInBlock, int iterationCount, LIRBlock block) { - char c = iterationCount == 0 || changeOccurredInBlock ? '*' : ' '; - TTY.print("(%d) liveIn%c B%d ", iterationCount, c, block.blockID()); - TTY.println(block.liveIn.toString()); - TTY.print("(%d) liveOut%c B%d ", iterationCount, c, block.blockID()); - TTY.println(block.liveOut.toString()); - } - - Interval addUse(CiValue operand, int from, int to, RegisterPriority registerPriority, CiKind kind) { - if (!isProcessed(operand)) { - return null; - } - if (GraalOptions.TraceLinearScanLevel >= 2 && kind == null) { - TTY.println(" use %s from %d to %d (%s)", operand, from, to, registerPriority.name()); - } - - if (kind == null) { - kind = operand.kind.stackKind(); - } - Interval interval = intervalFor(operand); - if (interval == null) { - interval = createInterval(operand); - } - - if (kind != CiKind.Illegal) { - interval.setKind(kind); - } - - if (operand.isVariable() && gen.operands.mustStayInMemory((CiVariable) operand)) { - interval.addRange(from, maxOpId()); - } else { - interval.addRange(from, to); - } - - interval.addUsePos(to, registerPriority); - return interval; - } - - void addTemp(CiValue operand, int tempPos, RegisterPriority registerPriority, CiKind kind) { - if (!isProcessed(operand)) { - return; - } - Interval interval = intervalFor(operand); - if (interval == null) { - interval = createInterval(operand); - } - - if (kind != CiKind.Illegal) { - interval.setKind(kind); - } - - interval.addRange(tempPos, tempPos + 1); - interval.addUsePos(tempPos, registerPriority); - } - - boolean isProcessed(CiValue operand) { - return !operand.isRegister() || attributes(operand.asRegister()).isAllocatable; - } - - void addDef(CiValue operand, int defPos, RegisterPriority registerPriority, CiKind kind) { - if (!isProcessed(operand)) { - return; - } - if (GraalOptions.TraceLinearScanLevel >= 2) { - TTY.println(" def %s defPos %d (%s)", operand, defPos, registerPriority.name()); - } - Interval interval = intervalFor(operand); - if (interval != null) { - - if (kind != CiKind.Illegal) { - interval.setKind(kind); - } - - Range r = interval.first(); - if (r.from <= defPos) { - // Update the starting point (when a range is first created for a use, its - // start is the beginning of the current block until a def is encountered.) - r.from = defPos; - interval.addUsePos(defPos, registerPriority); - - } else { - // Dead value - make vacuous interval - // also add register priority for dead intervals - interval.addRange(defPos, defPos + 1); - interval.addUsePos(defPos, registerPriority); - if (GraalOptions.TraceLinearScanLevel >= 2) { - TTY.println("Warning: def of operand %s at %d occurs without use", operand, defPos); - } - } - - } else { - // Dead value - make vacuous interval - // also add register priority for dead intervals - interval = createInterval(operand); - if (kind != CiKind.Illegal) { - interval.setKind(kind); - } - - interval.addRange(defPos, defPos + 1); - interval.addUsePos(defPos, registerPriority); - if (GraalOptions.TraceLinearScanLevel >= 2) { - TTY.println("Warning: dead value %s at %d in live intervals", operand, defPos); - } - } - - changeSpillDefinitionPos(interval, defPos); - if (registerPriority == RegisterPriority.None && interval.spillState().ordinal() <= SpillState.StartInMemory.ordinal()) { - // detection of method-parameters and roundfp-results - // TODO: move this directly to position where use-kind is computed - interval.setSpillState(SpillState.StartInMemory); - } - } - - /** - * Determines the register priority for an instruction's output/result operand. - */ - RegisterPriority registerPriorityOfOutputOperand(LIRInstruction op, CiValue operand) { - if (op.code == LIROpcode.Move) { - LIROp1 move = (LIROp1) op; - CiValue res = move.result(); - boolean resultInMemory = res.isVariable() && operands.mustStartInMemory((CiVariable) res); - - if (resultInMemory) { - // Begin of an interval with mustStartInMemory set. - // This interval will always get a stack slot first, so return noUse. - return RegisterPriority.None; - - } else if (move.operand().isStackSlot()) { - // method argument (condition must be equal to handleMethodArguments) - return RegisterPriority.None; - - } - } - - if (operand.isVariable() && operands.mustStartInMemory((CiVariable) operand)) { - // result is a stack-slot, so prevent immediate reloading - return RegisterPriority.None; - } - - // all other operands require a register - return RegisterPriority.MustHaveRegister; - } - - /** - * Determines the priority which with an instruction's input operand will be allocated a register. - */ - RegisterPriority registerPriorityOfInputOperand(LIRInstruction op, CiValue operand) { - if (op.code == LIROpcode.Move) { - LIROp1 move = (LIROp1) op; - CiValue res = move.result(); - boolean resultInMemory = res.isVariable() && operands.mustStartInMemory((CiVariable) res); - - if (resultInMemory) { - // Move to an interval with mustStartInMemory set. - // To avoid moves from stack to stack (not allowed) force the input operand to a register - return RegisterPriority.MustHaveRegister; - - } else if (move.operand().isVariableOrRegister() && move.result().isVariableOrRegister()) { - // The input operand is not forced to a register (moves from stack to register are allowed), - // but it is faster if the input operand is in a register - return RegisterPriority.ShouldHaveRegister; - } - } - - if (compilation.target.arch.isX86()) { - if (op.code == LIROpcode.Cmove) { - // conditional moves can handle stack operands - assert op.result().isVariableOrRegister(); - return RegisterPriority.ShouldHaveRegister; - } - - // optimizations for second input operand of arithmetic operations on Intel - // this operand is allowed to be on the stack in some cases - CiKind kind = operand.kind.stackKind(); - if (kind == CiKind.Float || kind == CiKind.Double) { - // SSE float instruction (CiKind.Double only supported with SSE2) - switch (op.code) { - case Cmp: - case Add: - case Sub: - case Mul: - case Div: { - LIROp2 op2 = (LIROp2) op; - if (op2.operand1() != op2.operand2() && op2.operand2() == operand) { - assert (op2.result().isVariableOrRegister() || op.code == LIROpcode.Cmp) && op2.operand1().isVariableOrRegister() : "cannot mark second operand as stack if others are not in register"; - return RegisterPriority.ShouldHaveRegister; - } - } - } - } else if (kind != CiKind.Long) { - // integer instruction (note: long operands must always be in register) - switch (op.code) { - case Cmp: - case Add: - case Sub: - case LogicAnd: - case LogicOr: - case LogicXor: { - LIROp2 op2 = (LIROp2) op; - if (op2.operand1() != op2.operand2() && op2.operand2() == operand) { - assert (op2.result().isVariableOrRegister() || op.code == LIROpcode.Cmp) && op2.operand1().isVariableOrRegister() : "cannot mark second operand as stack if others are not in register"; - return RegisterPriority.ShouldHaveRegister; - } - } - } - } - } // X86 - - // all other operands require a register - return RegisterPriority.MustHaveRegister; - } - - /** - * Optimizes moves related to incoming stack based arguments. - * The interval for the destination of such moves is assigned - * the stack slot (which is in the caller's frame) as its - * spill slot. - */ - void handleMethodArguments(LIRInstruction op) { - if (op.code == LIROpcode.Move) { - LIROp1 move = (LIROp1) op; - - if (move.operand().isStackSlot()) { - CiStackSlot slot = (CiStackSlot) move.operand(); - if (GraalOptions.DetailedAsserts) { - int argSlots = compilation.method.signature().argumentSlots(!isStatic(compilation.method.accessFlags())); - assert slot.index() >= 0 && slot.index() < argSlots; - assert move.id() > 0 : "invalid id"; - assert blockForId(move.id()).numberOfPreds() == 0 : "move from stack must be in first block"; - assert move.result().isVariable() : "result of move must be a variable"; - - if (GraalOptions.TraceLinearScanLevel >= 4) { - TTY.println("found move from stack slot %s to %s", slot, move.result()); - } - } - - Interval interval = intervalFor(move.result()); - CiStackSlot copySlot = slot; - if (GraalOptions.CopyPointerStackArguments && slot.kind == CiKind.Object) { - copySlot = allocateSpillSlot(slot.kind); - } - interval.setSpillSlot(copySlot); - interval.assignLocation(copySlot); - } - } - } - - void addRegisterHints(LIRInstruction op) { - switch (op.code) { - case Move: // fall through - case Convert: { - LIROp1 move = (LIROp1) op; - - CiValue moveFrom = move.operand(); - CiValue moveTo = move.result(); - - if (moveTo.isVariableOrRegister() && moveFrom.isVariableOrRegister()) { - Interval from = intervalFor(moveFrom); - Interval to = intervalFor(moveTo); - if (from != null && to != null) { - to.setLocationHint(from); - if (GraalOptions.TraceLinearScanLevel >= 4) { - TTY.println("operation at opId %d: added hint from interval %d to %d", move.id(), from.operandNumber, to.operandNumber); - } - } - } - break; - } - case Cmove: { - LIROp2 cmove = (LIROp2) op; - - CiValue moveFrom = cmove.operand1(); - CiValue moveTo = cmove.result(); - - if (moveTo.isVariableOrRegister() && moveFrom.isVariableOrRegister()) { - Interval from = intervalFor(moveFrom); - Interval to = intervalFor(moveTo); - if (from != null && to != null) { - to.setLocationHint(from); - if (GraalOptions.TraceLinearScanLevel >= 4) { - TTY.println("operation at opId %d: added hint from interval %d to %d", cmove.id(), from.operandNumber, to.operandNumber); - } - } - } - break; - } - } - } - - void buildIntervals() { - intervalsSize = operands.size(); - intervals = new Interval[intervalsSize + INITIAL_SPLIT_INTERVALS_CAPACITY]; - - // create a list with all caller-save registers (cpu, fpu, xmm) - RiRegisterConfig registerConfig = compilation.registerConfig; - CiRegister[] callerSaveRegs = registerConfig.getCallerSaveRegisters(); - - // iterate all blocks in reverse order - for (int i = blockCount() - 1; i >= 0; i--) { - LIRBlock block = blockAt(i); - List instructions = block.lir().instructionsList(); - final int blockFrom = block.firstLirInstructionId(); - int blockTo = block.lastLirInstructionId(); - - assert blockFrom == instructions.get(0).id(); - assert blockTo == instructions.get(instructions.size() - 1).id(); - - // Update intervals for operands live at the end of this block; - BitMap live = block.liveOut; - for (int operandNum = live.nextSetBit(0); operandNum >= 0; operandNum = live.nextSetBit(operandNum + 1)) { - assert live.get(operandNum) : "should not stop here otherwise"; - CiValue operand = operands.operandFor(operandNum); - if (GraalOptions.TraceLinearScanLevel >= 2) { - TTY.println("live in %s to %d", operand, blockTo + 2); - } - - addUse(operand, blockFrom, blockTo + 2, RegisterPriority.None, CiKind.Illegal); - - // add special use positions for loop-end blocks when the - // interval is used anywhere inside this loop. It's possible - // that the block was part of a non-natural loop, so it might - // have an invalid loop index. - if (block.isLinearScanLoopEnd() && block.loopIndex() != -1 && isIntervalInLoop(operandNum, block.loopIndex())) { - intervalFor(operand).addUsePos(blockTo + 1, RegisterPriority.LiveAtLoopEnd); - } - } - - // iterate all instructions of the block in reverse order. - // skip the first instruction because it is always a label - // definitions of intervals are processed before uses - assert !instructions.get(0).hasOperands() : "first operation must always be a label"; - for (int j = instructions.size() - 1; j >= 1; j--) { - LIRInstruction op = instructions.get(j); - final int opId = op.id(); - - // add a temp range for each register if operation destroys caller-save registers - if (op.hasCall) { - for (CiRegister r : callerSaveRegs) { - if (attributes(r).isAllocatable) { - addTemp(r.asValue(), opId, RegisterPriority.None, CiKind.Illegal); - } - } - if (GraalOptions.TraceLinearScanLevel >= 4) { - TTY.println("operation destroys all caller-save registers"); - } - } - - // Add any platform dependent temps - pdAddTemps(op); - - // visit definitions (output and temp operands) - int k; - int n; - n = op.operandCount(LIRInstruction.OperandMode.Output); - for (k = 0; k < n; k++) { - CiValue operand = op.operandAt(LIRInstruction.OperandMode.Output, k); - assert operand.isVariableOrRegister(); - addDef(operand, opId, registerPriorityOfOutputOperand(op, operand), operand.kind.stackKind()); - } - - n = op.operandCount(LIRInstruction.OperandMode.Temp); - for (k = 0; k < n; k++) { - CiValue operand = op.operandAt(LIRInstruction.OperandMode.Temp, k); - assert operand.isVariableOrRegister(); - if (GraalOptions.TraceLinearScanLevel >= 2) { - TTY.println(" temp %s tempPos %d (%s)", operand, opId, RegisterPriority.MustHaveRegister.name()); - } - addTemp(operand, opId, RegisterPriority.MustHaveRegister, operand.kind.stackKind()); - } - - // visit uses (input operands) - n = op.operandCount(LIRInstruction.OperandMode.Input); - for (k = 0; k < n; k++) { - CiValue operand = op.operandAt(LIRInstruction.OperandMode.Input, k); - assert operand.isVariableOrRegister(); - RegisterPriority p = registerPriorityOfInputOperand(op, operand); - Interval interval = addUse(operand, blockFrom, opId, p, null); - if (interval != null && op instanceof LIRXirInstruction) { - Range range = interval.first(); - // (tw) Increase range by 1 in order to overlap the input with the temp and the output operand. - if (range.to == opId) { - range.to++; - } - } - } - - // Add uses of live locals from interpreter's point of view for proper - // debug information generation - // Treat these operands as temp values (if the live range is extended - // to a call site, the value would be in a register at the call otherwise) - LIRDebugInfo info = op.info; - if (info != null) { - info.state.forEachLiveStateValue(new ValueProcedure() { - public void doValue(ValueNode value) { - CiValue operand = value.operand(); - if (operand.isVariableOrRegister()) { - addUse(operand, blockFrom, (opId + 1), RegisterPriority.None, null); - } - } - }); - } - - // special steps for some instructions (especially moves) - handleMethodArguments(op); - addRegisterHints(op); - - } // end of instruction iteration - } // end of block iteration - - // add the range [0, 1] to all fixed intervals. - // the register allocator need not handle unhandled fixed intervals - for (Interval interval : intervals) { - if (interval != null && interval.operand.isRegister()) { - interval.addRange(0, 1); - } - } - } - - // * Phase 5: actual register allocation - - private void pdAddTemps(LIRInstruction op) { - // TODO Platform dependent! - assert compilation.target.arch.isX86(); - - switch (op.code) { - case Tan: - case Sin: - case Cos: { - // The slow path for these functions may need to save and - // restore all live registers but we don't want to save and - // restore everything all the time, so mark the xmms as being - // killed. If the slow path were explicit or we could propagate - // live register masks down to the assembly we could do better - // but we don't have any easy way to do that right now. We - // could also consider not killing all xmm registers if we - // assume that slow paths are uncommon but it's not clear that - // would be a good idea. - if (GraalOptions.TraceLinearScanLevel >= 2) { - TTY.println("killing XMMs for trig"); - } - int opId = op.id(); - - for (CiRegister r : compilation.registerConfig.getCallerSaveRegisters()) { - if (r.isFpu()) { - addTemp(r.asValue(), opId, RegisterPriority.None, CiKind.Illegal); - } - } - break; - } - } - - } - - private boolean isSorted(Interval[] intervals) { - int from = -1; - for (Interval interval : intervals) { - assert interval != null; - assert from <= interval.from(); - from = interval.from(); - - // XXX: very slow! - assert Arrays.asList(this.intervals).contains(interval); - } - return true; - } - - Interval addToList(Interval first, Interval prev, Interval interval) { - Interval newFirst = first; - if (prev != null) { - prev.next = interval; - } else { - newFirst = interval; - } - return newFirst; - } - - Interval.Pair createUnhandledLists(IntervalPredicate isList1, IntervalPredicate isList2) { - assert isSorted(sortedIntervals) : "interval list is not sorted"; - - Interval list1 = Interval.EndMarker; - Interval list2 = Interval.EndMarker; - - Interval list1Prev = null; - Interval list2Prev = null; - Interval v; - - int n = sortedIntervals.length; - for (int i = 0; i < n; i++) { - v = sortedIntervals[i]; - if (v == null) { - continue; - } - - if (isList1.apply(v)) { - list1 = addToList(list1, list1Prev, v); - list1Prev = v; - } else if (isList2 == null || isList2.apply(v)) { - list2 = addToList(list2, list2Prev, v); - list2Prev = v; - } - } - - if (list1Prev != null) { - list1Prev.next = Interval.EndMarker; - } - if (list2Prev != null) { - list2Prev.next = Interval.EndMarker; - } - - assert list1Prev == null || list1Prev.next == Interval.EndMarker : "linear list ends not with sentinel"; - assert list2Prev == null || list2Prev.next == Interval.EndMarker : "linear list ends not with sentinel"; - - return new Interval.Pair(list1, list2); - } - - void sortIntervalsBeforeAllocation() { - int sortedLen = 0; - for (Interval interval : intervals) { - if (interval != null) { - sortedLen++; - } - } - - Interval[] sortedList = new Interval[sortedLen]; - int sortedIdx = 0; - int sortedFromMax = -1; - - // special sorting algorithm: the original interval-list is almost sorted, - // only some intervals are swapped. So this is much faster than a complete QuickSort - for (Interval interval : intervals) { - if (interval != null) { - int from = interval.from(); - - if (sortedFromMax <= from) { - sortedList[sortedIdx++] = interval; - sortedFromMax = interval.from(); - } else { - // the assumption that the intervals are already sorted failed, - // so this interval must be sorted in manually - int j; - for (j = sortedIdx - 1; j >= 0 && from < sortedList[j].from(); j--) { - sortedList[j + 1] = sortedList[j]; - } - sortedList[j + 1] = interval; - sortedIdx++; - } - } - } - sortedIntervals = sortedList; - } - - void sortIntervalsAfterAllocation() { - if (firstDerivedIntervalIndex == -1) { - // no intervals have been added during allocation, so sorted list is already up to date - return; - } - - Interval[] oldList = sortedIntervals; - Interval[] newList = Arrays.copyOfRange(intervals, firstDerivedIntervalIndex, intervalsSize); - int oldLen = oldList.length; - int newLen = newList.length; - - // conventional sort-algorithm for new intervals - Arrays.sort(newList, INTERVAL_COMPARATOR); - - // merge old and new list (both already sorted) into one combined list - Interval[] combinedList = new Interval[oldLen + newLen]; - int oldIdx = 0; - int newIdx = 0; - - while (oldIdx + newIdx < combinedList.length) { - if (newIdx >= newLen || (oldIdx < oldLen && oldList[oldIdx].from() <= newList[newIdx].from())) { - combinedList[oldIdx + newIdx] = oldList[oldIdx]; - oldIdx++; - } else { - combinedList[oldIdx + newIdx] = newList[newIdx]; - newIdx++; - } - } - - sortedIntervals = combinedList; - } - - private static final Comparator INTERVAL_COMPARATOR = new Comparator() { - - public int compare(Interval a, Interval b) { - if (a != null) { - if (b != null) { - return a.from() - b.from(); - } else { - return -1; - } - } else { - if (b != null) { - return 1; - } else { - return 0; - } - } - } - }; - - public void allocateRegisters() { - Interval precoloredIntervals; - Interval notPrecoloredIntervals; - - Interval.Pair result = createUnhandledLists(IS_PRECOLORED_INTERVAL, IS_VARIABLE_INTERVAL); - precoloredIntervals = result.first; - notPrecoloredIntervals = result.second; - - // allocate cpu registers - LinearScanWalker lsw = new LinearScanWalker(this, precoloredIntervals, notPrecoloredIntervals); - lsw.walk(); - lsw.finishAllocation(); - } - - // * Phase 6: resolve data flow - // (insert moves at edges between blocks if intervals have been split) - - // wrapper for Interval.splitChildAtOpId that performs a bailout in product mode - // instead of returning null - Interval splitChildAtOpId(Interval interval, int opId, LIRInstruction.OperandMode mode) { - Interval result = interval.getSplitChildAtOpId(opId, mode, this); - - if (result != null) { - if (GraalOptions.TraceLinearScanLevel >= 4) { - TTY.println("Split child at pos " + opId + " of interval " + interval.toString() + " is " + result.toString()); - } - return result; - } - - throw new CiBailout("LinearScan: interval is null"); - } - - Interval intervalAtBlockBegin(LIRBlock block, CiValue operand) { - assert operand.isVariable() : "register number out of bounds"; - assert intervalFor(operand) != null : "no interval found"; - - return splitChildAtOpId(intervalFor(operand), block.firstLirInstructionId(), LIRInstruction.OperandMode.Output); - } - - Interval intervalAtBlockEnd(LIRBlock block, CiValue operand) { - assert operand.isVariable() : "register number out of bounds"; - assert intervalFor(operand) != null : "no interval found"; - - return splitChildAtOpId(intervalFor(operand), block.lastLirInstructionId() + 1, LIRInstruction.OperandMode.Output); - } - - Interval intervalAtOpId(CiValue operand, int opId) { - assert operand.isVariable() : "register number out of bounds"; - assert intervalFor(operand) != null : "no interval found"; - - return splitChildAtOpId(intervalFor(operand), opId, LIRInstruction.OperandMode.Input); - } - - void resolveCollectMappings(LIRBlock fromBlock, LIRBlock toBlock, MoveResolver moveResolver) { - assert moveResolver.checkEmpty(); - - int numOperands = operands.size(); - BitMap liveAtEdge = toBlock.liveIn; - - // visit all variables for which the liveAtEdge bit is set - for (int operandNum = liveAtEdge.nextSetBit(0); operandNum >= 0; operandNum = liveAtEdge.nextSetBit(operandNum + 1)) { - assert operandNum < numOperands : "live information set for not exisiting interval"; - assert fromBlock.liveOut.get(operandNum) && toBlock.liveIn.get(operandNum) : "interval not live at this edge"; - - CiValue liveOperand = operands.operandFor(operandNum); - Interval fromInterval = intervalAtBlockEnd(fromBlock, liveOperand); - Interval toInterval = intervalAtBlockBegin(toBlock, liveOperand); - - if (fromInterval != toInterval && (fromInterval.location() != toInterval.location())) { - // need to insert move instruction - moveResolver.addMapping(fromInterval, toInterval); - } - } - } - - void resolveFindInsertPos(LIRBlock fromBlock, LIRBlock toBlock, MoveResolver moveResolver) { - if (fromBlock.numberOfSux() <= 1) { - if (GraalOptions.TraceLinearScanLevel >= 4) { - TTY.println("inserting moves at end of fromBlock B%d", fromBlock.blockID()); - } - - List instructions = fromBlock.lir().instructionsList(); - LIRInstruction instr = instructions.get(instructions.size() - 1); - if (instr instanceof LIRBranch) { - LIRBranch branch = (LIRBranch) instr; - // insert moves before branch - assert branch.cond() == Condition.TRUE : "block does not end with an unconditional jump"; - moveResolver.setInsertPosition(fromBlock.lir(), instructions.size() - 2); - } else { - moveResolver.setInsertPosition(fromBlock.lir(), instructions.size() - 1); - } - - } else { - if (GraalOptions.TraceLinearScanLevel >= 4) { - TTY.println("inserting moves at beginning of toBlock B%d", toBlock.blockID()); - } - - if (GraalOptions.DetailedAsserts) { - assert fromBlock.lir().instructionsList().get(0) instanceof LIRLabel : "block does not start with a label"; - - // because the number of predecessor edges matches the number of - // successor edges, blocks which are reached by switch statements - // may have be more than one predecessor but it will be guaranteed - // that all predecessors will be the same. - for (int i = 0; i < toBlock.numberOfPreds(); i++) { - assert fromBlock == toBlock.predAt(i) : "all critical edges must be broken"; - } - } - - moveResolver.setInsertPosition(toBlock.lir(), 0); - } - } - - /** - * Inserts necessary moves (spilling or reloading) at edges between blocks for intervals that - * have been split. - */ - void resolveDataFlow() { - int numBlocks = blockCount(); - MoveResolver moveResolver = new MoveResolver(this); - BitMap blockCompleted = new BitMap(numBlocks); - BitMap alreadyResolved = new BitMap(numBlocks); - - int i; - for (i = 0; i < numBlocks; i++) { - LIRBlock block = blockAt(i); - - // check if block has only one predecessor and only one successor - if (block.numberOfPreds() == 1 && block.numberOfSux() == 1) { - List instructions = block.lir().instructionsList(); - assert instructions.get(0).code == LIROpcode.Label : "block must start with label"; - assert instructions.get(instructions.size() - 1).code == LIROpcode.Branch : "block with successors must end with branch (" + block + "), " + instructions.get(instructions.size() - 1); - assert ((LIRBranch) instructions.get(instructions.size() - 1)).cond() == Condition.TRUE : "block with successor must end with unconditional branch"; - - // check if block is empty (only label and branch) - if (instructions.size() == 2) { - LIRBlock pred = block.predAt(0); - LIRBlock sux = block.suxAt(0); - - // prevent optimization of two consecutive blocks - if (!blockCompleted.get(pred.linearScanNumber()) && !blockCompleted.get(sux.linearScanNumber())) { - if (GraalOptions.TraceLinearScanLevel >= 3) { - TTY.println(" optimizing empty block B%d (pred: B%d, sux: B%d)", block.blockID(), pred.blockID(), sux.blockID()); - } - blockCompleted.set(block.linearScanNumber()); - - // directly resolve between pred and sux (without looking at the empty block between) - resolveCollectMappings(pred, sux, moveResolver); - if (moveResolver.hasMappings()) { - moveResolver.setInsertPosition(block.lir(), 0); - moveResolver.resolveAndAppendMoves(); - } - } - } - } - } - - for (i = 0; i < numBlocks; i++) { - if (!blockCompleted.get(i)) { - LIRBlock fromBlock = blockAt(i); - alreadyResolved.setFrom(blockCompleted); - - int numSux = fromBlock.numberOfSux(); - for (int s = 0; s < numSux; s++) { - LIRBlock toBlock = fromBlock.suxAt(s); - - // check for duplicate edges between the same blocks (can happen with switch blocks) - if (!alreadyResolved.get(toBlock.linearScanNumber())) { - if (GraalOptions.TraceLinearScanLevel >= 3) { - TTY.println(" processing edge between B%d and B%d", fromBlock.blockID(), toBlock.blockID()); - } - alreadyResolved.set(toBlock.linearScanNumber()); - - // collect all intervals that have been split between fromBlock and toBlock - resolveCollectMappings(fromBlock, toBlock, moveResolver); - if (moveResolver.hasMappings()) { - resolveFindInsertPos(fromBlock, toBlock, moveResolver); - moveResolver.resolveAndAppendMoves(); - } - } - } - } - } - } - - // * Phase 7: assign register numbers back to LIR - // (includes computation of debug information and oop maps) - - boolean verifyAssignedLocation(Interval interval, CiValue location) { - CiKind kind = interval.kind(); - - assert location.isRegister() || location.isStackSlot(); - - if (location.isRegister()) { - CiRegister reg = location.asRegister(); - - // register - switch (kind) { - case Byte: - case Char: - case Short: - case Jsr: - case Word: - case Object: - case Int: { - assert reg.isCpu() : "not cpu register"; - break; - } - - case Long: { - assert reg.isCpu() : "not cpu register"; - break; - } - - case Float: { - assert !compilation.target.arch.isX86() || reg.isFpu() : "not xmm register: " + reg; - break; - } - - case Double: { - assert !compilation.target.arch.isX86() || reg.isFpu() : "not xmm register: " + reg; - break; - } - - default: { - throw Util.shouldNotReachHere(); - } - } - } - return true; - } - - CiStackSlot canonicalSpillOpr(Interval interval) { - assert interval.spillSlot() != null : "canonical spill slot not set"; - return interval.spillSlot(); - } - - /** - * Assigns the allocated location for an LIR instruction operand back into the instruction. - * - * @param operand an LIR instruction operand - * @param opId the id of the LIR instruction using {@code operand} - * @param mode the usage mode for {@code operand} by the instruction - * @return the location assigned for the operand - */ - private CiValue colorLirOperand(CiVariable operand, int opId, OperandMode mode) { - Interval interval = intervalFor(operand); - assert interval != null : "interval must exist"; - - if (opId != -1) { - if (GraalOptions.DetailedAsserts) { - LIRBlock block = blockForId(opId); - if (block.numberOfSux() <= 1 && opId == block.lastLirInstructionId()) { - // check if spill moves could have been appended at the end of this block, but - // before the branch instruction. So the split child information for this branch would - // be incorrect. - LIRInstruction instr = block.lir().instructionsList().get(block.lir().instructionsList().size() - 1); - if (instr instanceof LIRBranch) { - LIRBranch branch = (LIRBranch) instr; - if (block.liveOut.get(operandNumber(operand))) { - assert branch.cond() == Condition.TRUE : "block does not end with an unconditional jump"; - throw new CiBailout("can't get split child for the last branch of a block because the information would be incorrect (moves are inserted before the branch in resolveDataFlow)"); - } - } - } - } - - // operands are not changed when an interval is split during allocation, - // so search the right interval here - interval = splitChildAtOpId(interval, opId, mode); - } - - return interval.location(); - } - - IntervalWalker initComputeOopMaps() { - // setup lists of potential oops for walking - Interval oopIntervals; - Interval nonOopIntervals; - - oopIntervals = createUnhandledLists(IS_OOP_INTERVAL, null).first; - - // intervals that have no oops inside need not to be processed. - // to ensure a walking until the last instruction id, add a dummy interval - // with a high operation id - nonOopIntervals = new Interval(CiValue.IllegalValue, -1); - nonOopIntervals.addRange(Integer.MAX_VALUE - 2, Integer.MAX_VALUE - 1); - - return new IntervalWalker(this, oopIntervals, nonOopIntervals); - } - - void computeOopMap(IntervalWalker iw, LIRInstruction op, LIRDebugInfo info, boolean isCallSite, BitMap frameRefMap, BitMap regRefMap) { - if (GraalOptions.TraceLinearScanLevel >= 3) { - TTY.println("creating oop map at opId %d", op.id()); - } - - // walk before the current operation . intervals that start at - // the operation (i.e. output operands of the operation) are not - // included in the oop map - iw.walkBefore(op.id()); - - // Iterate through active intervals - for (Interval interval = iw.activeLists.get(RegisterBinding.Fixed); interval != Interval.EndMarker; interval = interval.next) { - CiValue operand = interval.operand; - - assert interval.currentFrom() <= op.id() && op.id() <= interval.currentTo() : "interval should not be active otherwise"; - assert interval.operand.isVariable() : "fixed interval found"; - - // Check if this range covers the instruction. Intervals that - // start or end at the current operation are not included in the - // oop map, except in the case of patching moves. For patching - // moves, any intervals which end at this instruction are included - // in the oop map since we may safepoint while doing the patch - // before we've consumed the inputs. - if (op.id() < interval.currentTo()) { - // caller-save registers must not be included into oop-maps at calls - assert !isCallSite || !operand.isRegister() || !isCallerSave(operand) : "interval is in a caller-save register at a call . register will be overwritten"; - - CiValue location = interval.location(); - if (location.isStackSlot()) { - location = frameMap.toStackAddress((CiStackSlot) location); - } - info.setOop(location, compilation, frameRefMap, regRefMap); - - // Spill optimization: when the stack value is guaranteed to be always correct, - // then it must be added to the oop map even if the interval is currently in a register - if (interval.alwaysInMemory() && op.id() > interval.spillDefinitionPos() && !interval.location().equals(interval.spillSlot())) { - assert interval.spillDefinitionPos() > 0 : "position not set correctly"; - assert interval.spillSlot() != null : "no spill slot assigned"; - assert !interval.operand.isRegister() : "interval is on stack : so stack slot is registered twice"; - info.setOop(frameMap.toStackAddress(interval.spillSlot()), compilation, frameRefMap, regRefMap); - } - } - } - } - - private boolean isCallerSave(CiValue operand) { - return attributes(operand.asRegister()).isCallerSave; - } - - void computeOopMap(IntervalWalker iw, LIRInstruction op, LIRDebugInfo info, BitMap frameRefMap, BitMap regRefMap) { - computeOopMap(iw, op, info, op.hasCall, frameRefMap, regRefMap); - if (op instanceof LIRCall) { - List pointerSlots = ((LIRCall) op).pointerSlots; - if (pointerSlots != null) { - for (CiValue v : pointerSlots) { - info.setOop(v, compilation, frameRefMap, regRefMap); - } - } - } else if (op instanceof LIRXirInstruction) { - List pointerSlots = ((LIRXirInstruction) op).pointerSlots; - if (pointerSlots != null) { - for (CiValue v : pointerSlots) { - info.setOop(v, compilation, frameRefMap, regRefMap); - } - } - } - } - - public static ThreadLocal> frameModifierLoader = new ThreadLocal>(); - - private CiFrame overrideFrame(CiFrame frame) { - ServiceLoader serviceLoader = frameModifierLoader.get(); - if (serviceLoader == null) { - serviceLoader = ServiceLoader.load(FrameModifier.class); - frameModifierLoader.set(serviceLoader); - } - - CiFrame result = frame; - for (FrameModifier modifier : serviceLoader) { - result = modifier.getFrame(compilation.runtime, result); - } - return result; - } - - - private class DebugFrameBuilder { - - private final FrameState topState; - private final int opId; - private final BitMap frameRefMap; - - private HashMap virtualObjects; - - public DebugFrameBuilder(FrameState topState, int opId, BitMap frameRefMap) { - this.topState = topState; - this.opId = opId; - this.frameRefMap = frameRefMap; - } - - private CiValue toCiValue(ValueNode value) { - if (value instanceof VirtualObjectNode) { - if (virtualObjects == null) { - virtualObjects = new HashMap(); - } - VirtualObjectNode obj = (VirtualObjectNode) value; - CiVirtualObject ciObj = virtualObjects.get(value); - if (ciObj == null) { - ciObj = CiVirtualObject.get(obj.type(), null, value.id()); - virtualObjects.put(obj, ciObj); - } - return ciObj; - } else if (value != null && value.operand() != CiValue.IllegalValue) { - CiValue operand = value.operand(); - ConstantNode con = null; - if (value instanceof ConstantNode) { - con = (ConstantNode) value; - } - - assert con == null || operand.isVariable() || operand.isConstant() || operand.isIllegal() : "Constant instructions have only constant operands (or illegal if constant is optimized away)"; - - int tempOpId = this.opId; - if (operand.isVariable()) { - OperandMode mode = OperandMode.Input; - LIRBlock block = blockForId(tempOpId); - if (block.numberOfSux() == 1 && tempOpId == block.lastLirInstructionId()) { - // generating debug information for the last instruction of a block. - // if this instruction is a branch, spill moves are inserted before this branch - // and so the wrong operand would be returned (spill moves at block boundaries are not - // considered in the live ranges of intervals) - // Solution: use the first opId of the branch target block instead. - final LIRInstruction instr = block.lir().instructionsList().get(block.lir().instructionsList().size() - 1); - if (instr instanceof LIRBranch) { - if (block.liveOut.get(operandNumber(operand))) { - tempOpId = block.suxAt(0).firstLirInstructionId(); - mode = OperandMode.Output; - } - } - } - - // Get current location of operand - // The operand must be live because debug information is considered when building the intervals - // if the interval is not live, colorLirOperand will cause an assert on failure - operand = colorLirOperand((CiVariable) operand, tempOpId, mode); - assert !hasCall(tempOpId) || operand.isStackSlot() || !isCallerSave(operand) : "cannot have caller-save register operands at calls"; - return operand; - } else if (operand.isRegister()) { - assert false : "must not reach here"; - return operand; - } else { - assert value instanceof ConstantNode; - assert operand.isConstant() : "operand must be constant"; - return operand; - } - } else { - // return a dummy value because real value not needed - return CiValue.IllegalValue; - } - } - - private CiFrame computeFrameForState(FrameState state) { - CiValue[] values = new CiValue[state.valuesSize() + state.locksSize()]; - int valueIndex = 0; - - for (int i = 0; i < state.valuesSize(); i++) { - values[valueIndex++] = toCiValue(state.valueAt(i)); - } - - for (int i = 0; i < state.locksSize(); i++) { - if (compilation.runtime.sizeOfBasicObjectLock() != 0) { - CiStackSlot monitorAddress = frameMap.toMonitorBaseStackAddress(i); - values[valueIndex++] = monitorAddress; - CiStackSlot objectAddress = frameMap.toMonitorObjectStackAddress(i); - frameRefMap.set(objectAddress.index()); - } else { - ValueNode lock = state.lockAt(i); - if (lock.isConstant() && compilation.runtime.asJavaClass(lock.asConstant()) != null) { - // lock on class for synchronized static method - values[valueIndex++] = lock.asConstant(); - } else { - values[valueIndex++] = toCiValue(lock); - } - } - } - CiFrame caller = null; - if (state.outerFrameState() != null) { - caller = computeFrameForState(state.outerFrameState()); - } - CiFrame frame = new CiFrame(caller, state.method, state.bci, state.rethrowException(), values, state.localsSize(), state.stackSize(), state.locksSize()); - if (GraalOptions.Extend) { - frame = overrideFrame(frame); - } - return frame; - } - - public CiFrame build() { - CiFrame frame = computeFrameForState(topState); - - if (virtualObjects != null) { - // collect all VirtualObjectField instances: - HashMap objectStates = new HashMap(); - FrameState current = topState; - do { - for (Node n : current.virtualObjectMappings()) { - VirtualObjectFieldNode field = (VirtualObjectFieldNode) n; - // null states occur for objects with 0 fields - if (field != null && !objectStates.containsKey(field.object())) { - objectStates.put(field.object(), field); - } - } - current = current.outerFrameState(); - } while (current != null); - // fill in the CiVirtualObject values: - // during this process new CiVirtualObjects might be discovered, so repeat until no more changes occur. - boolean changed; - do { - changed = false; - HashMap virtualObjectsCopy = new HashMap(virtualObjects); - for (Entry entry : virtualObjectsCopy.entrySet()) { - if (entry.getValue().values() == null) { - VirtualObjectNode vobj = entry.getKey(); - CiValue[] values = new CiValue[vobj.fields().length]; - entry.getValue().setValues(values); - if (vobj.fields().length > 0) { - changed = true; - FloatingNode currentField = objectStates.get(vobj); - assert currentField != null; - do { - if (currentField instanceof VirtualObjectFieldNode) { - int index = ((VirtualObjectFieldNode) currentField).index(); - if (values[index] == null) { - values[index] = toCiValue(((VirtualObjectFieldNode) currentField).input()); - } - currentField = ((VirtualObjectFieldNode) currentField).lastState(); - } else { - assert currentField instanceof PhiNode : currentField; - currentField = (FloatingNode) ((PhiNode) currentField).valueAt(0); - } - } while (currentField != null); - } - } - } - } while (changed); - } - return frame; - } - } - - private void computeDebugInfo(IntervalWalker iw, LIRInstruction op) { - assert iw != null : "interval walker needed for debug information"; - computeDebugInfo(iw, op, op.info); - - if (op instanceof LIRXirInstruction) { - LIRXirInstruction xir = (LIRXirInstruction) op; - if (xir.infoAfter != null) { - computeDebugInfo(iw, op, xir.infoAfter); - } - } - } - - - private void computeDebugInfo(IntervalWalker iw, LIRInstruction op, LIRDebugInfo info) { - if (info != null) { - if (info.debugInfo == null) { - int frameSize = compilation.frameMap().frameSize(); - int frameWords = frameSize / compilation.target.spillSlotSize; - BitMap frameRefMap = new BitMap(frameWords); - BitMap regRefMap = !op.hasCall ? new BitMap(compilation.target.arch.registerReferenceMapBitCount) : null; - CiFrame frame = compilation.placeholderState != null ? null : computeFrame(info.state, op.id(), frameRefMap); - computeOopMap(iw, op, info, frameRefMap, regRefMap); - info.debugInfo = new CiDebugInfo(frame, regRefMap, frameRefMap); - } else if (GraalOptions.DetailedAsserts) { - assert info.debugInfo.frame().equals(computeFrame(info.state, op.id(), new BitMap(info.debugInfo.frameRefMap.size()))); - } - } - } - - CiFrame computeFrame(FrameState state, int opId, BitMap frameRefMap) { - if (GraalOptions.TraceLinearScanLevel >= 3) { - TTY.println("creating debug information at opId %d", opId); - } - return new DebugFrameBuilder(state, opId, frameRefMap).build(); - } - - private void assignLocations(List instructions, IntervalWalker iw) { - int numInst = instructions.size(); - boolean hasDead = false; - - for (int j = 0; j < numInst; j++) { - LIRInstruction op = instructions.get(j); - if (op == null) { // this can happen when spill-moves are removed in eliminateSpillMoves - hasDead = true; - continue; - } - - // iterate all modes of the visitor and process all virtual operands - for (LIRInstruction.OperandMode mode : LIRInstruction.OPERAND_MODES) { - int n = op.operandCount(mode); - for (int k = 0; k < n; k++) { - CiValue operand = op.operandAt(mode, k); - if (operand.isVariable()) { - op.setOperandAt(mode, k, colorLirOperand((CiVariable) operand, op.id(), mode)); - } - } - } - - if (op.info != null) { - // compute reference map and debug information - computeDebugInfo(iw, op); - } - - // make sure we haven't made the op invalid. - assert op.verify(); - - // remove useless moves - if (op.code == LIROpcode.Move) { - CiValue src = op.operand(0); - CiValue dst = op.result(); - if (dst == src || src.equals(dst)) { - // TODO: what about o.f = o.f and exceptions? - instructions.set(j, null); - hasDead = true; - } - } - } - - if (hasDead) { - // iterate all instructions of the block and remove all null-values. - int insertPoint = 0; - for (int j = 0; j < numInst; j++) { - LIRInstruction op = instructions.get(j); - if (op != null) { - if (insertPoint != j) { - instructions.set(insertPoint, op); - } - insertPoint++; - } - } - Util.truncate(instructions, insertPoint); - } - } - - private void assignLocations() { - IntervalWalker iw = initComputeOopMaps(); - for (LIRBlock block : sortedBlocks) { - assignLocations(block.lir().instructionsList(), iw); - } - } - - public void allocate() { - if (GraalOptions.Time) { - GraalTimers.LIFETIME_ANALYSIS.start(); - } - - numberInstructions(); - - printLir("Before register allocation", true); - - computeLocalLiveSets(); - computeGlobalLiveSets(); - - buildIntervals(); - sortIntervalsBeforeAllocation(); - - if (GraalOptions.Time) { - GraalTimers.LIFETIME_ANALYSIS.stop(); - GraalTimers.LINEAR_SCAN.start(); - } - - printIntervals("Before register allocation"); - - allocateRegisters(); - - if (GraalOptions.Time) { - GraalTimers.LINEAR_SCAN.stop(); - GraalTimers.RESOLUTION.start(); - } - - resolveDataFlow(); - - if (GraalOptions.Time) { - GraalTimers.RESOLUTION.stop(); - GraalTimers.DEBUG_INFO.start(); - } - - GraalMetrics.LSRASpills += (maxSpills - frameMap.initialSpillSlot()); - - // fill in number of spill slots into frameMap - frameMap.finalizeFrame(maxSpills); - - printIntervals("After register allocation"); - printLir("After register allocation", true); - - sortIntervalsAfterAllocation(); - - if (GraalOptions.DetailedAsserts) { - verify(); - } - - eliminateSpillMoves(); - assignLocations(); - - if (GraalOptions.DetailedAsserts) { - verifyIntervals(); - } - - if (GraalOptions.Time) { - GraalTimers.DEBUG_INFO.stop(); - GraalTimers.CODE_CREATE.start(); - } - - printLir("After register number assignment", true); - EdgeMoveOptimizer.optimize(ir.linearScanOrder()); - ControlFlowOptimizer.optimize(ir); - printLir("After control flow optimization", false); - } - - void printIntervals(String label) { - if (GraalOptions.TraceLinearScanLevel >= 1) { - int i; - TTY.println(); - TTY.println(label); - - for (Interval interval : intervals) { - if (interval != null) { - TTY.out().println(interval.logString(this)); - } - } - - TTY.println(); - TTY.println("--- Basic Blocks ---"); - for (i = 0; i < blockCount(); i++) { - LIRBlock block = blockAt(i); - TTY.print("B%d [%d, %d, %d, %d] ", block.blockID(), block.firstLirInstructionId(), block.lastLirInstructionId(), block.loopIndex(), block.loopDepth()); - } - TTY.println(); - TTY.println(); - } - - if (compilation.compiler.isObserved()) { - compilation.compiler.fireCompilationEvent(new CompilationEvent(compilation, label, this, intervals, intervalsSize)); - } - } - - void printLir(String label, boolean hirValid) { - if (GraalOptions.TraceLinearScanLevel >= 1 && !TTY.isSuppressed()) { - TTY.println(); - TTY.println(label); - LIRList.printLIR(ir.linearScanOrder()); - TTY.println(); - } - - if (compilation.compiler.isObserved()) { - compilation.compiler.fireCompilationEvent(new CompilationEvent(compilation, label, /*compilation.graph*/ null, hirValid, true)); - } - } - - boolean verify() { - // (check that all intervals have a correct register and that no registers are overwritten) - if (GraalOptions.TraceLinearScanLevel >= 2) { - TTY.println(" verifying intervals *"); - } - verifyIntervals(); - - if (GraalOptions.TraceLinearScanLevel >= 2) { - TTY.println(" verifying that no oops are in fixed intervals *"); - } - //verifyNoOopsInFixedIntervals(); - - if (GraalOptions.TraceLinearScanLevel >= 2) { - TTY.println(" verifying that unpinned constants are not alive across block boundaries"); - } - verifyConstants(); - - if (GraalOptions.TraceLinearScanLevel >= 2) { - TTY.println(" verifying register allocation *"); - } - verifyRegisters(); - - if (GraalOptions.TraceLinearScanLevel >= 2) { - TTY.println(" no errors found *"); - } - - return true; - } - - private void verifyRegisters() { - RegisterVerifier verifier = new RegisterVerifier(this); - verifier.verify(blockAt(0)); - } - - void verifyIntervals() { - int len = intervalsSize; - - for (int i = 0; i < len; i++) { - Interval i1 = intervals[i]; - if (i1 == null) { - continue; - } - - i1.checkSplitChildren(); - - if (i1.operandNumber != i) { - TTY.println("Interval %d is on position %d in list", i1.operandNumber, i); - TTY.println(i1.logString(this)); - throw new CiBailout(""); - } - - if (i1.operand.isVariable() && i1.kind() == CiKind.Illegal) { - TTY.println("Interval %d has no type assigned", i1.operandNumber); - TTY.println(i1.logString(this)); - throw new CiBailout(""); - } - - if (i1.location() == null) { - TTY.println("Interval %d has no register assigned", i1.operandNumber); - TTY.println(i1.logString(this)); - throw new CiBailout(""); - } - - if (!isProcessed(i1.location())) { - TTY.println("Can not have an Interval for an ignored register " + i1.location()); - TTY.println(i1.logString(this)); - throw new CiBailout(""); - } - - if (i1.first() == Range.EndMarker) { - TTY.println("Interval %d has no Range", i1.operandNumber); - TTY.println(i1.logString(this)); - throw new CiBailout(""); - } - - for (Range r = i1.first(); r != Range.EndMarker; r = r.next) { - if (r.from >= r.to) { - TTY.println("Interval %d has zero length range", i1.operandNumber); - TTY.println(i1.logString(this)); - throw new CiBailout(""); - } - } - - for (int j = i + 1; j < len; j++) { - Interval i2 = intervals[j]; - if (i2 == null) { - continue; - } - - // special intervals that are created in MoveResolver - // . ignore them because the range information has no meaning there - if (i1.from() == 1 && i1.to() == 2) { - continue; - } - if (i2.from() == 1 && i2.to() == 2) { - continue; - } - CiValue l1 = i1.location(); - CiValue l2 = i2.location(); - if (i1.intersects(i2) && (l1.equals(l2))) { - if (GraalOptions.DetailedAsserts) { - TTY.println("Intervals %d and %d overlap and have the same register assigned", i1.operandNumber, i2.operandNumber); - TTY.println(i1.logString(this)); - TTY.println(i2.logString(this)); - } - throw new CiBailout(""); - } - } - } - } - - void verifyNoOopsInFixedIntervals() { - Interval fixedIntervals; - Interval otherIntervals; - fixedIntervals = createUnhandledLists(IS_PRECOLORED_INTERVAL, null).first; - // to ensure a walking until the last instruction id, add a dummy interval - // with a high operation id - otherIntervals = new Interval(CiValue.IllegalValue, -1); - otherIntervals.addRange(Integer.MAX_VALUE - 2, Integer.MAX_VALUE - 1); - IntervalWalker iw = new IntervalWalker(this, fixedIntervals, otherIntervals); - - for (int i = 0; i < blockCount(); i++) { - LIRBlock block = blockAt(i); - - List instructions = block.lir().instructionsList(); - - for (int j = 0; j < instructions.size(); j++) { - LIRInstruction op = instructions.get(j); - - if (op.info != null) { - iw.walkBefore(op.id()); - boolean checkLive = true; - - // Make sure none of the fixed registers is live across an - // oopmap since we can't handle that correctly. - if (checkLive) { - for (Interval interval = iw.activeLists.get(RegisterBinding.Fixed); interval != Interval.EndMarker; interval = interval.next) { - if (interval.currentTo() > op.id() + 1) { - // This interval is live out of this op so make sure - // that this interval represents some value that's - // referenced by this op either as an input or output. - boolean ok = false; - for (LIRInstruction.OperandMode mode : LIRInstruction.OPERAND_MODES) { - int n = op.operandCount(mode); - for (int k = 0; k < n; k++) { - CiValue operand = op.operandAt(mode, k); - if (operand.isRegister()) { - if (intervalFor(operand) == interval) { - ok = true; - break; - } - } - } - } - assert ok : "fixed intervals should never be live across an oopmap point"; - } - } - } - } - } - } - } - - void verifyConstants() { - int numBlocks = blockCount(); - - for (int i = 0; i < numBlocks; i++) { - LIRBlock block = blockAt(i); - BitMap liveAtEdge = block.liveIn; - - // visit all operands where the liveAtEdge bit is set - for (int operandNum = liveAtEdge.nextSetBit(0); operandNum >= 0; operandNum = liveAtEdge.nextSetBit(operandNum + 1)) { - if (GraalOptions.TraceLinearScanLevel >= 4) { - TTY.println("checking interval %d of block B%d", operandNum, block.blockID()); - } - CiValue operand = operands.operandFor(operandNum); - assert operand.isVariable() : "value must have variable operand"; - ValueNode value = gen.operands.instructionForResult(((CiVariable) operand)); - assert value != null : "all intervals live across block boundaries must have Value"; - // TKR assert value.asConstant() == null || value.isPinned() : - // "only pinned constants can be alive accross block boundaries"; - } - } - } - - public int numberOfSpillSlots(CiKind kind) { - return compilation.target.spillSlots(kind); - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/alloc/LinearScanWalker.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/alloc/LinearScanWalker.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,983 +0,0 @@ -/* - * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.compiler.alloc; - -import static com.sun.cri.ci.CiUtil.*; - -import java.util.*; - -import com.oracle.max.graal.compiler.*; -import com.oracle.max.graal.compiler.alloc.Interval.RegisterBinding; -import com.oracle.max.graal.compiler.alloc.Interval.RegisterPriority; -import com.oracle.max.graal.compiler.alloc.Interval.SpillState; -import com.oracle.max.graal.compiler.alloc.Interval.State; -import com.oracle.max.graal.compiler.debug.*; -import com.oracle.max.graal.compiler.lir.*; -import com.oracle.max.graal.compiler.util.*; -import com.sun.cri.ci.*; -import com.sun.cri.ci.CiRegister.RegisterFlag; - -/** - * - * @author Thomas Wuerthinger - */ -final class LinearScanWalker extends IntervalWalker { - - private CiRegister[] availableRegs; - - private final int[] usePos; - private final int[] blockPos; - - private List[] spillIntervals; - - private MoveResolver moveResolver; // for ordering spill moves - - // accessors mapped to same functions in class LinearScan - int blockCount() { - return allocator.blockCount(); - } - - LIRBlock blockAt(int idx) { - return allocator.blockAt(idx); - } - - LIRBlock blockOfOpWithId(int opId) { - return allocator.blockForId(opId); - } - - LinearScanWalker(LinearScan allocator, Interval unhandledFixedFirst, Interval unhandledAnyFirst) { - super(allocator, unhandledFixedFirst, unhandledAnyFirst); - moveResolver = new MoveResolver(allocator); - spillIntervals = Util.uncheckedCast(new List[allocator.registers.length]); - for (int i = 0; i < allocator.registers.length; i++) { - spillIntervals[i] = new ArrayList(2); - } - usePos = new int[allocator.registers.length]; - blockPos = new int[allocator.registers.length]; - } - - void initUseLists(boolean onlyProcessUsePos) { - for (CiRegister register : availableRegs) { - int i = register.number; - usePos[i] = Integer.MAX_VALUE; - - if (!onlyProcessUsePos) { - blockPos[i] = Integer.MAX_VALUE; - spillIntervals[i].clear(); - } - } - } - - void excludeFromUse(Interval i) { - CiValue location = i.location(); - int i1 = location.asRegister().number; - if (i1 >= availableRegs[0].number && i1 <= availableRegs[availableRegs.length - 1].number) { - usePos[i1] = 0; - } - } - - void setUsePos(Interval interval, int usePos, boolean onlyProcessUsePos) { - if (usePos != -1) { - assert usePos != 0 : "must use excludeFromUse to set usePos to 0"; - int i = interval.location().asRegister().number; - if (i >= availableRegs[0].number && i <= availableRegs[availableRegs.length - 1].number) { - if (this.usePos[i] > usePos) { - this.usePos[i] = usePos; - } - if (!onlyProcessUsePos) { - spillIntervals[i].add(interval); - } - } - } - } - - void setBlockPos(Interval i, int blockPos) { - if (blockPos != -1) { - int reg = i.location().asRegister().number; - if (reg >= availableRegs[0].number && reg <= availableRegs[availableRegs.length - 1].number) { - if (this.blockPos[reg] > blockPos) { - this.blockPos[reg] = blockPos; - } - if (usePos[reg] > blockPos) { - usePos[reg] = blockPos; - } - } - } - } - - void freeExcludeActiveFixed() { - Interval interval = activeLists.get(RegisterBinding.Fixed); - while (interval != Interval.EndMarker) { - assert interval.location().isRegister() : "active interval must have a register assigned"; - excludeFromUse(interval); - interval = interval.next; - } - } - - void freeExcludeActiveAny() { - Interval interval = activeLists.get(RegisterBinding.Any); - while (interval != Interval.EndMarker) { - assert interval.location().isRegister() : "active interval must have a register assigned"; - excludeFromUse(interval); - interval = interval.next; - } - } - - void freeCollectInactiveFixed(Interval current) { - Interval interval = inactiveLists.get(RegisterBinding.Fixed); - while (interval != Interval.EndMarker) { - if (current.to() <= interval.currentFrom()) { - assert interval.currentIntersectsAt(current) == -1 : "must not intersect"; - setUsePos(interval, interval.currentFrom(), true); - } else { - setUsePos(interval, interval.currentIntersectsAt(current), true); - } - interval = interval.next; - } - } - - void freeCollectInactiveAny(Interval current) { - Interval interval = inactiveLists.get(RegisterBinding.Any); - while (interval != Interval.EndMarker) { - setUsePos(interval, interval.currentIntersectsAt(current), true); - interval = interval.next; - } - } - - void freeCollectUnhandled(RegisterBinding kind, Interval current) { - Interval interval = unhandledLists.get(kind); - while (interval != Interval.EndMarker) { - setUsePos(interval, interval.intersectsAt(current), true); - if (kind == RegisterBinding.Fixed && current.to() <= interval.from()) { - setUsePos(interval, interval.from(), true); - } - interval = interval.next; - } - } - - void spillExcludeActiveFixed() { - Interval interval = activeLists.get(RegisterBinding.Fixed); - while (interval != Interval.EndMarker) { - excludeFromUse(interval); - interval = interval.next; - } - } - - void spillBlockUnhandledFixed(Interval current) { - Interval interval = unhandledLists.get(RegisterBinding.Fixed); - while (interval != Interval.EndMarker) { - setBlockPos(interval, interval.intersectsAt(current)); - interval = interval.next; - } - } - - void spillBlockInactiveFixed(Interval current) { - Interval interval = inactiveLists.get(RegisterBinding.Fixed); - while (interval != Interval.EndMarker) { - if (current.to() > interval.currentFrom()) { - setBlockPos(interval, interval.currentIntersectsAt(current)); - } else { - assert interval.currentIntersectsAt(current) == -1 : "invalid optimization: intervals intersect"; - } - - interval = interval.next; - } - } - - void spillCollectActiveAny() { - Interval interval = activeLists.get(RegisterBinding.Any); - while (interval != Interval.EndMarker) { - setUsePos(interval, Math.min(interval.nextUsage(RegisterPriority.LiveAtLoopEnd, currentPosition), interval.to()), false); - interval = interval.next; - } - } - - void spillCollectInactiveAny(Interval current) { - Interval interval = inactiveLists.get(RegisterBinding.Any); - while (interval != Interval.EndMarker) { - if (interval.currentIntersects(current)) { - setUsePos(interval, Math.min(interval.nextUsage(RegisterPriority.LiveAtLoopEnd, currentPosition), interval.to()), false); - } - interval = interval.next; - } - } - - void insertMove(int opId, Interval srcIt, Interval dstIt) { - // output all moves here. When source and target are equal, the move is - // optimized away later in assignRegNums - - opId = (opId + 1) & ~1; - LIRBlock opBlock = allocator.blockForId(opId); - assert opId > 0 && allocator.blockForId(opId - 2) == opBlock : "cannot insert move at block boundary"; - - // calculate index of instruction inside instruction list of current block - // the minimal index (for a block with no spill moves) can be calculated because the - // numbering of instructions is known. - // When the block already contains spill moves, the index must be increased until the - // correct index is reached. - List list = opBlock.lir().instructionsList(); - int index = (opId - list.get(0).id()) >> 1; - assert list.get(index).id() <= opId : "error in calculation"; - - while (list.get(index).id() != opId) { - index++; - assert 0 <= index && index < list.size() : "index out of bounds"; - } - assert 1 <= index && index < list.size() : "index out of bounds"; - assert list.get(index).id() == opId : "error in calculation"; - - // insert new instruction before instruction at position index - moveResolver.moveInsertPosition(opBlock.lir(), index - 1); - moveResolver.addMapping(srcIt, dstIt); - } - - int findOptimalSplitPos(LIRBlock minBlock, LIRBlock maxBlock, int maxSplitPos) { - int fromBlockNr = minBlock.linearScanNumber(); - int toBlockNr = maxBlock.linearScanNumber(); - - assert 0 <= fromBlockNr && fromBlockNr < blockCount() : "out of range"; - assert 0 <= toBlockNr && toBlockNr < blockCount() : "out of range"; - assert fromBlockNr < toBlockNr : "must cross block boundary"; - - // Try to split at end of maxBlock. If this would be after - // maxSplitPos, then use the begin of maxBlock - int optimalSplitPos = maxBlock.lastLirInstructionId() + 2; - if (optimalSplitPos > maxSplitPos) { - optimalSplitPos = maxBlock.firstLirInstructionId(); - } - - int minLoopDepth = maxBlock.loopDepth(); - for (int i = toBlockNr - 1; i >= fromBlockNr; i--) { - LIRBlock cur = blockAt(i); - - if (cur.loopDepth() < minLoopDepth) { - // block with lower loop-depth found . split at the end of this block - minLoopDepth = cur.loopDepth(); - optimalSplitPos = cur.lastLirInstructionId() + 2; - } - } - assert optimalSplitPos > allocator.maxOpId() || allocator.isBlockBegin(optimalSplitPos) : "algorithm must move split pos to block boundary"; - - return optimalSplitPos; - } - - int findOptimalSplitPos(Interval interval, int minSplitPos, int maxSplitPos, boolean doLoopOptimization) { - int optimalSplitPos = -1; - if (minSplitPos == maxSplitPos) { - // trivial case, no optimization of split position possible - if (GraalOptions.TraceLinearScanLevel >= 4) { - TTY.println(" min-pos and max-pos are equal, no optimization possible"); - } - optimalSplitPos = minSplitPos; - - } else { - assert minSplitPos < maxSplitPos : "must be true then"; - assert minSplitPos > 0 : "cannot access minSplitPos - 1 otherwise"; - - // reason for using minSplitPos - 1: when the minimal split pos is exactly at the - // beginning of a block, then minSplitPos is also a possible split position. - // Use the block before as minBlock, because then minBlock.lastLirInstructionId() + 2 == minSplitPos - LIRBlock minBlock = allocator.blockForId(minSplitPos - 1); - - // reason for using maxSplitPos - 1: otherwise there would be an assert on failure - // when an interval ends at the end of the last block of the method - // (in this case, maxSplitPos == allocator().maxLirOpId() + 2, and there is no - // block at this opId) - LIRBlock maxBlock = allocator.blockForId(maxSplitPos - 1); - - assert minBlock.linearScanNumber() <= maxBlock.linearScanNumber() : "invalid order"; - if (minBlock == maxBlock) { - // split position cannot be moved to block boundary : so split as late as possible - if (GraalOptions.TraceLinearScanLevel >= 4) { - TTY.println(" cannot move split pos to block boundary because minPos and maxPos are in same block"); - } - optimalSplitPos = maxSplitPos; - - } else { - if (interval.hasHoleBetween(maxSplitPos - 1, maxSplitPos) && !allocator.isBlockBegin(maxSplitPos)) { - // Do not move split position if the interval has a hole before maxSplitPos. - // Intervals resulting from Phi-Functions have more than one definition (marked - // as mustHaveRegister) with a hole before each definition. When the register is needed - // for the second definition : an earlier reloading is unnecessary. - if (GraalOptions.TraceLinearScanLevel >= 4) { - TTY.println(" interval has hole just before maxSplitPos, so splitting at maxSplitPos"); - } - optimalSplitPos = maxSplitPos; - - } else { - // seach optimal block boundary between minSplitPos and maxSplitPos - if (GraalOptions.TraceLinearScanLevel >= 4) { - TTY.println(" moving split pos to optimal block boundary between block B%d and B%d", minBlock.blockID(), maxBlock.blockID()); - } - - if (doLoopOptimization) { - // Loop optimization: if a loop-end marker is found between min- and max-position : - // then split before this loop - int loopEndPos = interval.nextUsageExact(RegisterPriority.LiveAtLoopEnd, minBlock.lastLirInstructionId() + 2); - if (GraalOptions.TraceLinearScanLevel >= 4) { - TTY.println(" loop optimization: loop end found at pos %d", loopEndPos); - } - - assert loopEndPos > minSplitPos : "invalid order"; - if (loopEndPos < maxSplitPos) { - // loop-end marker found between min- and max-position - // if it is not the end marker for the same loop as the min-position : then move - // the max-position to this loop block. - // Desired result: uses tagged as shouldHaveRegister inside a loop cause a reloading - // of the interval (normally, only mustHaveRegister causes a reloading) - LIRBlock loopBlock = allocator.blockForId(loopEndPos); - - if (GraalOptions.TraceLinearScanLevel >= 4) { - TTY.println(" interval is used in loop that ends in block B%d, so trying to move maxBlock back from B%d to B%d", loopBlock.blockID(), maxBlock.blockID(), loopBlock.blockID()); - } - assert loopBlock != minBlock : "loopBlock and minBlock must be different because block boundary is needed between"; - - optimalSplitPos = findOptimalSplitPos(minBlock, loopBlock, loopBlock.lastLirInstructionId() + 2); - if (optimalSplitPos == loopBlock.lastLirInstructionId() + 2) { - optimalSplitPos = -1; - if (GraalOptions.TraceLinearScanLevel >= 4) { - TTY.println(" loop optimization not necessary"); - } - } else { - if (GraalOptions.TraceLinearScanLevel >= 4) { - TTY.println(" loop optimization successful"); - } - } - } - } - - if (optimalSplitPos == -1) { - // not calculated by loop optimization - optimalSplitPos = findOptimalSplitPos(minBlock, maxBlock, maxSplitPos); - } - } - } - } - if (GraalOptions.TraceLinearScanLevel >= 4) { - TTY.println(" optimal split position: %d", optimalSplitPos); - } - - return optimalSplitPos; - } - - // split an interval at the optimal position between minSplitPos and - // maxSplitPos in two parts: - // 1) the left part has already a location assigned - // 2) the right part is sorted into to the unhandled-list - void splitBeforeUsage(Interval interval, int minSplitPos, int maxSplitPos) { - if (GraalOptions.TraceLinearScanLevel >= 2) { - TTY.println("----- splitting interval: "); - } - if (GraalOptions.TraceLinearScanLevel >= 4) { - TTY.println(interval.logString(allocator)); - } - if (GraalOptions.TraceLinearScanLevel >= 2) { - TTY.println(" between %d and %d", minSplitPos, maxSplitPos); - } - - assert interval.from() < minSplitPos : "cannot split at start of interval"; - assert currentPosition < minSplitPos : "cannot split before current position"; - assert minSplitPos <= maxSplitPos : "invalid order"; - assert maxSplitPos <= interval.to() : "cannot split after end of interval"; - - int optimalSplitPos = findOptimalSplitPos(interval, minSplitPos, maxSplitPos, true); - - assert minSplitPos <= optimalSplitPos && optimalSplitPos <= maxSplitPos : "out of range"; - assert optimalSplitPos <= interval.to() : "cannot split after end of interval"; - assert optimalSplitPos > interval.from() : "cannot split at start of interval"; - - if (optimalSplitPos == interval.to() && interval.nextUsage(RegisterPriority.MustHaveRegister, minSplitPos) == Integer.MAX_VALUE) { - // the split position would be just before the end of the interval - // . no split at all necessary - if (GraalOptions.TraceLinearScanLevel >= 4) { - TTY.println(" no split necessary because optimal split position is at end of interval"); - } - return; - } - - // must calculate this before the actual split is performed and before split position is moved to odd opId - boolean moveNecessary = !allocator.isBlockBegin(optimalSplitPos) && !interval.hasHoleBetween(optimalSplitPos - 1, optimalSplitPos); - - if (!allocator.isBlockBegin(optimalSplitPos)) { - // move position before actual instruction (odd opId) - optimalSplitPos = (optimalSplitPos - 1) | 1; - } - - if (GraalOptions.TraceLinearScanLevel >= 4) { - TTY.println(" splitting at position %d", optimalSplitPos); - } - assert allocator.isBlockBegin(optimalSplitPos) || (optimalSplitPos % 2 == 1) : "split pos must be odd when not on block boundary"; - assert !allocator.isBlockBegin(optimalSplitPos) || (optimalSplitPos % 2 == 0) : "split pos must be even on block boundary"; - - Interval splitPart = interval.split(optimalSplitPos, allocator); - - allocator.copyRegisterFlags(interval, splitPart); - splitPart.setInsertMoveWhenActivated(moveNecessary); - - assert splitPart.from() >= current.currentFrom() : "cannot append new interval before current walk position"; - unhandledLists.addToListSortedByStartAndUsePositions(RegisterBinding.Any, splitPart); - - if (GraalOptions.TraceLinearScanLevel >= 2) { - TTY.println(" split interval in two parts (insertMoveWhenActivated: %b)", moveNecessary); - } - if (GraalOptions.TraceLinearScanLevel >= 2) { - TTY.print(" "); - TTY.println(interval.logString(allocator)); - TTY.print(" "); - TTY.println(splitPart.logString(allocator)); - } - } - -// split an interval at the optimal position between minSplitPos and -// maxSplitPos in two parts: -// 1) the left part has already a location assigned -// 2) the right part is always on the stack and therefore ignored in further processing - - void splitForSpilling(Interval interval) { - // calculate allowed range of splitting position - int maxSplitPos = currentPosition; - int minSplitPos = Math.max(interval.previousUsage(RegisterPriority.ShouldHaveRegister, maxSplitPos) + 1, interval.from()); - - if (GraalOptions.TraceLinearScanLevel >= 2) { - TTY.print("----- splitting and spilling interval: "); - TTY.println(interval.logString(allocator)); - TTY.println(" between %d and %d", minSplitPos, maxSplitPos); - } - - assert interval.state == State.Active : "why spill interval that is not active?"; - assert interval.from() <= minSplitPos : "cannot split before start of interval"; - assert minSplitPos <= maxSplitPos : "invalid order"; - assert maxSplitPos < interval.to() : "cannot split at end end of interval"; - assert currentPosition < interval.to() : "interval must not end before current position"; - - if (minSplitPos == interval.from()) { - // the whole interval is never used, so spill it entirely to memory - if (GraalOptions.TraceLinearScanLevel >= 2) { - TTY.println(" spilling entire interval because split pos is at beginning of interval"); - TTY.println(" use positions: " + interval.usePosList().size()); - } - assert interval.firstUsage(RegisterPriority.ShouldHaveRegister) > currentPosition : "interval must not have use position before currentPosition"; - - allocator.assignSpillSlot(interval); - allocator.changeSpillState(interval, minSplitPos); - - // Also kick parent intervals out of register to memory when they have no use - // position. This avoids short interval in register surrounded by intervals in - // memory . avoid useless moves from memory to register and back - Interval parent = interval; - while (parent != null && parent.isSplitChild()) { - parent = parent.getSplitChildBeforeOpId(parent.from()); - - if (parent.location().isRegister()) { - if (parent.firstUsage(RegisterPriority.ShouldHaveRegister) == Integer.MAX_VALUE) { - // parent is never used, so kick it out of its assigned register - if (GraalOptions.TraceLinearScanLevel >= 4) { - TTY.println(" kicking out interval %d out of its register because it is never used", parent.operandNumber); - } - allocator.assignSpillSlot(parent); - } else { - // do not go further back because the register is actually used by the interval - parent = null; - } - } - } - - } else { - // search optimal split pos, split interval and spill only the right hand part - int optimalSplitPos = findOptimalSplitPos(interval, minSplitPos, maxSplitPos, false); - - assert minSplitPos <= optimalSplitPos && optimalSplitPos <= maxSplitPos : "out of range"; - assert optimalSplitPos < interval.to() : "cannot split at end of interval"; - assert optimalSplitPos >= interval.from() : "cannot split before start of interval"; - - if (!allocator.isBlockBegin(optimalSplitPos)) { - // move position before actual instruction (odd opId) - optimalSplitPos = (optimalSplitPos - 1) | 1; - } - - if (GraalOptions.TraceLinearScanLevel >= 4) { - TTY.println(" splitting at position %d", optimalSplitPos); - } - assert allocator.isBlockBegin(optimalSplitPos) || (optimalSplitPos % 2 == 1) : "split pos must be odd when not on block boundary"; - assert !allocator.isBlockBegin(optimalSplitPos) || (optimalSplitPos % 2 == 0) : "split pos must be even on block boundary"; - - Interval spilledPart = interval.split(optimalSplitPos, allocator); - allocator.assignSpillSlot(spilledPart); - allocator.changeSpillState(spilledPart, optimalSplitPos); - - if (!allocator.isBlockBegin(optimalSplitPos)) { - if (GraalOptions.TraceLinearScanLevel >= 4) { - TTY.println(" inserting move from interval %d to %d", interval.operandNumber, spilledPart.operandNumber); - } - insertMove(optimalSplitPos, interval, spilledPart); - } - - // the currentSplitChild is needed later when moves are inserted for reloading - assert spilledPart.currentSplitChild() == interval : "overwriting wrong currentSplitChild"; - spilledPart.makeCurrentSplitChild(); - - if (GraalOptions.TraceLinearScanLevel >= 2) { - TTY.println(" split interval in two parts"); - TTY.print(" "); - TTY.println(interval.logString(allocator)); - TTY.print(" "); - TTY.println(spilledPart.logString(allocator)); - } - } - } - - void splitStackInterval(Interval interval) { - int minSplitPos = currentPosition + 1; - int maxSplitPos = Math.min(interval.firstUsage(RegisterPriority.ShouldHaveRegister), interval.to()); - - splitBeforeUsage(interval, minSplitPos, maxSplitPos); - } - - void splitWhenPartialRegisterAvailable(Interval interval, int registerAvailableUntil) { - int minSplitPos = Math.max(interval.previousUsage(RegisterPriority.ShouldHaveRegister, registerAvailableUntil), interval.from() + 1); - splitBeforeUsage(interval, minSplitPos, registerAvailableUntil); - } - - void splitAndSpillInterval(Interval interval) { - assert interval.state == State.Active || interval.state == State.Inactive : "other states not allowed"; - - int currentPos = currentPosition; - if (interval.state == State.Inactive) { - // the interval is currently inactive, so no spill slot is needed for now. - // when the split part is activated, the interval has a new chance to get a register, - // so in the best case no stack slot is necessary - assert interval.hasHoleBetween(currentPos - 1, currentPos + 1) : "interval can not be inactive otherwise"; - splitBeforeUsage(interval, currentPos + 1, currentPos + 1); - - } else { - // search the position where the interval must have a register and split - // at the optimal position before. - // The new created part is added to the unhandled list and will get a register - // when it is activated - int minSplitPos = currentPos + 1; - int maxSplitPos = Math.min(interval.nextUsage(RegisterPriority.MustHaveRegister, minSplitPos), interval.to()); - - splitBeforeUsage(interval, minSplitPos, maxSplitPos); - - assert interval.nextUsage(RegisterPriority.MustHaveRegister, currentPos) == Integer.MAX_VALUE : "the remaining part is spilled to stack and therefore has no register"; - splitForSpilling(interval); - } - } - - boolean allocFreeRegister(Interval interval) { - if (GraalOptions.TraceLinearScanLevel >= 2) { - TTY.println("trying to find free register for " + interval.logString(allocator)); - } - - initUseLists(true); - freeExcludeActiveFixed(); - freeExcludeActiveAny(); - freeCollectInactiveFixed(interval); - freeCollectInactiveAny(interval); - // freeCollectUnhandled(fixedKind, cur); - assert unhandledLists.get(RegisterBinding.Fixed) == Interval.EndMarker : "must not have unhandled fixed intervals because all fixed intervals have a use at position 0"; - - // usePos contains the start of the next interval that has this register assigned - // (either as a fixed register or a normal allocated register in the past) - // only intervals overlapping with cur are processed, non-overlapping invervals can be ignored safely - if (GraalOptions.TraceLinearScanLevel >= 4) { - TTY.println(" state of registers:"); - for (CiRegister register : availableRegs) { - int i = register.number; - TTY.println(" reg %d: usePos: %d", register.number, usePos[i]); - } - } - - CiRegister hint = null; - Interval locationHint = interval.locationHint(true, allocator); - if (locationHint != null && locationHint.location() != null && locationHint.location().isRegister()) { - hint = locationHint.location().asRegister(); - if (GraalOptions.TraceLinearScanLevel >= 4) { - TTY.println(" hint register %d from interval %s", hint.number, locationHint.logString(allocator)); - } - } - assert interval.location() == null : "register already assigned to interval"; - - // the register must be free at least until this position - int regNeededUntil = interval.from() + 1; - int intervalTo = interval.to(); - - boolean needSplit = false; - int splitPos = -1; - - CiRegister reg = null; - CiRegister minFullReg = null; - CiRegister maxPartialReg = null; - - for (int i = 0; i < availableRegs.length; ++i) { - CiRegister availableReg = availableRegs[i]; - int number = availableReg.number; - if (usePos[number] >= intervalTo) { - // this register is free for the full interval - if (minFullReg == null || availableReg == hint || (usePos[number] < usePos[minFullReg.number] && minFullReg != hint)) { - minFullReg = availableReg; - } - } else if (usePos[number] > regNeededUntil) { - // this register is at least free until regNeededUntil - if (maxPartialReg == null || availableReg == hint || (usePos[number] > usePos[maxPartialReg.number] && maxPartialReg != hint)) { - maxPartialReg = availableReg; - } - } - } - - if (minFullReg != null) { - reg = minFullReg; - } else if (maxPartialReg != null) { - needSplit = true; - reg = maxPartialReg; - } else { - return false; - } - - splitPos = usePos[reg.number]; - interval.assignLocation(reg.asValue(interval.kind())); - if (GraalOptions.TraceLinearScanLevel >= 2) { - TTY.println("selected register %d", reg.number); - } - - assert splitPos > 0 : "invalid splitPos"; - if (needSplit) { - // register not available for full interval, so split it - splitWhenPartialRegisterAvailable(interval, splitPos); - } - - // only return true if interval is completely assigned - return true; - } - - CiRegister findLockedRegister(int regNeededUntil, int intervalTo, CiValue ignoreReg, boolean[] needSplit) { - int maxReg = -1; - CiRegister ignore = ignoreReg.isRegister() ? ignoreReg.asRegister() : null; - - for (CiRegister reg : availableRegs) { - int i = reg.number; - if (reg == ignore) { - // this register must be ignored - - } else if (usePos[i] > regNeededUntil) { - if (maxReg == -1 || (usePos[i] > usePos[maxReg])) { - maxReg = i; - } - } - } - - if (maxReg != -1) { - if (blockPos[maxReg] <= intervalTo) { - needSplit[0] = true; - } - return availableRegs[maxReg]; - } - - return null; - } - - void splitAndSpillIntersectingIntervals(CiRegister reg) { - assert reg != null : "no register assigned"; - - for (int i = 0; i < spillIntervals[reg.number].size(); i++) { - Interval interval = spillIntervals[reg.number].get(i); - removeFromList(interval); - splitAndSpillInterval(interval); - } - } - - // Split an Interval and spill it to memory so that cur can be placed in a register - void allocLockedRegister(Interval interval) { - if (GraalOptions.TraceLinearScanLevel >= 2) { - TTY.println("need to split and spill to get register for " + interval.logString(allocator)); - } - - // collect current usage of registers - initUseLists(false); - spillExcludeActiveFixed(); - // spillBlockUnhandledFixed(cur); - assert unhandledLists.get(RegisterBinding.Fixed) == Interval.EndMarker : "must not have unhandled fixed intervals because all fixed intervals have a use at position 0"; - spillBlockInactiveFixed(interval); - spillCollectActiveAny(); - spillCollectInactiveAny(interval); - - if (GraalOptions.TraceLinearScanLevel >= 4) { - TTY.println(" state of registers:"); - for (CiRegister reg : availableRegs) { - int i = reg.number; - TTY.print(" reg %d: usePos: %d, blockPos: %d, intervals: ", i, usePos[i], blockPos[i]); - for (int j = 0; j < spillIntervals[i].size(); j++) { - TTY.print("%d ", spillIntervals[i].get(j).operandNumber); - } - TTY.println(); - } - } - - // the register must be free at least until this position - int firstUsage = interval.firstUsage(RegisterPriority.MustHaveRegister); - int regNeededUntil = Math.min(firstUsage, interval.from() + 1); - int intervalTo = interval.to(); - assert regNeededUntil > 0 && regNeededUntil < Integer.MAX_VALUE : "interval has no use"; - - CiRegister reg = null; - CiRegister ignore = interval.location() != null && interval.location().isRegister() ? interval.location().asRegister() : null; - for (CiRegister availableReg : availableRegs) { - int number = availableReg.number; - if (availableReg == ignore) { - // this register must be ignored - } else if (usePos[number] > regNeededUntil) { - if (reg == null || (usePos[number] > usePos[reg.number])) { - reg = availableReg; - } - } - } - - if (reg == null || usePos[reg.number] <= firstUsage) { - // the first use of cur is later than the spilling position -> spill cur - if (GraalOptions.TraceLinearScanLevel >= 4) { - TTY.println("able to spill current interval. firstUsage(register): %d, usePos: %d", firstUsage, reg == null ? 0 : usePos[reg.number]); - } - - if (firstUsage <= interval.from() + 1) { - assert false : "cannot spill interval that is used in first instruction (possible reason: no register found) firstUsage=" + firstUsage + ", interval.from()=" + interval.from(); - // assign a reasonable register and do a bailout in product mode to avoid errors - allocator.assignSpillSlot(interval); - throw new CiBailout("LinearScan: no register found"); - } - - splitAndSpillInterval(interval); - return; - } - - boolean needSplit = blockPos[reg.number] <= intervalTo; - - int splitPos = blockPos[reg.number]; - - if (GraalOptions.TraceLinearScanLevel >= 4) { - TTY.println("decided to use register %d", reg.number); - } - assert splitPos > 0 : "invalid splitPos"; - assert needSplit || splitPos > interval.from() : "splitting interval at from"; - - interval.assignLocation(reg.asValue(interval.kind())); - if (needSplit) { - // register not available for full interval : so split it - splitWhenPartialRegisterAvailable(interval, splitPos); - } - - // perform splitting and spilling for all affected intervals - splitAndSpillIntersectingIntervals(reg); - } - - boolean noAllocationPossible(Interval interval) { - - if (compilation.target.arch.isX86()) { - // fast calculation of intervals that can never get a register because the - // the next instruction is a call that blocks all registers - // Note: this does not work if callee-saved registers are available (e.g. on Sparc) - - // check if this interval is the result of a split operation - // (an interval got a register until this position) - int pos = interval.from(); - if (isOdd(pos)) { - // the current instruction is a call that blocks all registers - if (pos < allocator.maxOpId() && allocator.hasCall(pos + 1) && interval.to() > pos + 1) { - if (GraalOptions.TraceLinearScanLevel >= 4) { - TTY.println(" free register cannot be available because all registers blocked by following call"); - } - - // safety check that there is really no register available - assert !allocFreeRegister(interval) : "found a register for this interval"; - return true; - } - - } - } - return false; - } - - void initVarsForAlloc(Interval interval) { - EnumMap categorizedRegs = allocator.compilation.registerConfig.getCategorizedAllocatableRegisters(); - if (allocator.operands.mustBeByteRegister(interval.operand)) { - assert interval.kind() != CiKind.Float && interval.kind() != CiKind.Double : "cpu regs only"; - availableRegs = categorizedRegs.get(RegisterFlag.Byte); - } else if (interval.kind() == CiKind.Float || interval.kind() == CiKind.Double) { - availableRegs = categorizedRegs.get(RegisterFlag.FPU); - } else { - availableRegs = categorizedRegs.get(RegisterFlag.CPU); - } - } - - boolean isMove(LIRInstruction op, Interval from, Interval to) { - if (op.code != LIROpcode.Move) { - return false; - } - assert op instanceof LIROp1 : "move must be LIROp1"; - - CiValue input = ((LIROp1) op).operand(); - CiValue result = ((LIROp1) op).result(); - return input.isVariable() && result.isVariable() && input == from.operand && result == to.operand; - } - - // optimization (especially for phi functions of nested loops): - // assign same spill slot to non-intersecting intervals - void combineSpilledIntervals(Interval interval) { - if (interval.isSplitChild()) { - // optimization is only suitable for split parents - return; - } - - Interval registerHint = interval.locationHint(false, allocator); - if (registerHint == null) { - // cur is not the target of a move : otherwise registerHint would be set - return; - } - assert registerHint.isSplitParent() : "register hint must be split parent"; - - if (interval.spillState() != SpillState.NoOptimization || registerHint.spillState() != SpillState.NoOptimization) { - // combining the stack slots for intervals where spill move optimization is applied - // is not benefitial and would cause problems - return; - } - - int beginPos = interval.from(); - int endPos = interval.to(); - if (endPos > allocator.maxOpId() || isOdd(beginPos) || isOdd(endPos)) { - // safety check that lirOpWithId is allowed - return; - } - - if (!isMove(allocator.instructionForId(beginPos), registerHint, interval) || !isMove(allocator.instructionForId(endPos), interval, registerHint)) { - // cur and registerHint are not connected with two moves - return; - } - - Interval beginHint = registerHint.getSplitChildAtOpId(beginPos, LIRInstruction.OperandMode.Input, allocator); - Interval endHint = registerHint.getSplitChildAtOpId(endPos, LIRInstruction.OperandMode.Output, allocator); - if (beginHint == endHint || beginHint.to() != beginPos || endHint.from() != endPos) { - // registerHint must be split : otherwise the re-writing of use positions does not work - return; - } - - assert beginHint.location() != null : "must have register assigned"; - assert endHint.location() == null : "must not have register assigned"; - assert interval.firstUsage(RegisterPriority.MustHaveRegister) == beginPos : "must have use position at begin of interval because of move"; - assert endHint.firstUsage(RegisterPriority.MustHaveRegister) == endPos : "must have use position at begin of interval because of move"; - - if (beginHint.location().isRegister()) { - // registerHint is not spilled at beginPos : so it would not be benefitial to immediately spill cur - return; - } - assert registerHint.spillSlot() != null : "must be set when part of interval was spilled"; - - // modify intervals such that cur gets the same stack slot as registerHint - // delete use positions to prevent the intervals to get a register at beginning - interval.setSpillSlot(registerHint.spillSlot()); - interval.removeFirstUsePos(); - endHint.removeFirstUsePos(); - } - - // allocate a physical register or memory location to an interval - @Override - boolean activateCurrent() { - Interval interval = current; - boolean result = true; - - if (GraalOptions.TraceLinearScanLevel >= 2) { - TTY.println("+++++ activating interval " + interval.logString(allocator)); - } - - if (GraalOptions.TraceLinearScanLevel >= 4) { - TTY.println(" splitParent: %s, insertMoveWhenActivated: %b", interval.splitParent().operandNumber, interval.insertMoveWhenActivated()); - } - - final CiValue operand = interval.operand; - if (interval.location() != null && interval.location().isStackSlot()) { - // activating an interval that has a stack slot assigned . split it at first use position - // used for method parameters - if (GraalOptions.TraceLinearScanLevel >= 4) { - TTY.println(" interval has spill slot assigned (method parameter) . split it before first use"); - } - splitStackInterval(interval); - result = false; - - } else { - if (operand.isVariable() && allocator.operands.mustStartInMemory((CiVariable) operand)) { - assert interval.location() == null : "register already assigned"; - allocator.assignSpillSlot(interval); - - if (!allocator.operands.mustStayInMemory((CiVariable) operand)) { - // activating an interval that must start in a stack slot but may get a register later - // used for lirRoundfp: rounding is done by store to stack and reload later - if (GraalOptions.TraceLinearScanLevel >= 4) { - TTY.println(" interval must start in stack slot . split it before first use"); - } - splitStackInterval(interval); - } - - result = false; - } else if (interval.location() == null) { - // interval has not assigned register . normal allocation - // (this is the normal case for most intervals) - if (GraalOptions.TraceLinearScanLevel >= 4) { - TTY.println(" normal allocation of register"); - } - - // assign same spill slot to non-intersecting intervals - combineSpilledIntervals(interval); - - initVarsForAlloc(interval); - if (noAllocationPossible(interval) || !allocFreeRegister(interval)) { - // no empty register available. - // split and spill another interval so that this interval gets a register - allocLockedRegister(interval); - } - - // spilled intervals need not be move to active-list - if (!interval.location().isRegister()) { - result = false; - } - } - } - - // load spilled values that become active from stack slot to register - if (interval.insertMoveWhenActivated()) { - assert interval.isSplitChild(); - assert interval.currentSplitChild() != null; - assert interval.currentSplitChild().operand != operand : "cannot insert move between same interval"; - if (GraalOptions.TraceLinearScanLevel >= 4) { - TTY.println("Inserting move from interval %d to %d because insertMoveWhenActivated is set", interval.currentSplitChild().operandNumber, interval.operandNumber); - } - - insertMove(interval.from(), interval.currentSplitChild(), interval); - } - interval.makeCurrentSplitChild(); - - return result; // true = interval is moved to active list - } - - public void finishAllocation() { - // must be called when all intervals are allocated - moveResolver.resolveAndAppendMoves(); - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/alloc/MoveResolver.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/alloc/MoveResolver.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,363 +0,0 @@ -/* - * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.compiler.alloc; - -import java.util.*; - -import com.oracle.max.graal.compiler.*; -import com.oracle.max.graal.compiler.debug.*; -import com.oracle.max.graal.compiler.lir.*; -import com.oracle.max.graal.compiler.util.*; -import com.sun.cri.ci.*; - -/** - * - * @author Thomas Wuerthinger - */ -final class MoveResolver { - - private final LinearScan allocator; - - private LIRList insertList; - private int insertIdx; - private LIRInsertionBuffer insertionBuffer; // buffer where moves are inserted - - private final List mappingFrom; - private final List mappingFromOpr; - private final List mappingTo; - private boolean multipleReadsAllowed; - private final int[] registerBlocked; - - private int registerBlocked(int reg) { - return registerBlocked[reg]; - } - - private void setRegisterBlocked(int reg, int direction) { - assert direction == 1 || direction == -1 : "out of bounds"; - registerBlocked[reg] += direction; - } - - void setMultipleReadsAllowed() { - multipleReadsAllowed = true; - } - - boolean hasMappings() { - return mappingFrom.size() > 0; - } - - MoveResolver(LinearScan allocator) { - - this.allocator = allocator; - this.multipleReadsAllowed = false; - this.mappingFrom = new ArrayList(8); - this.mappingFromOpr = new ArrayList(8); - this.mappingTo = new ArrayList(8); - this.insertIdx = -1; - this.insertionBuffer = new LIRInsertionBuffer(); - this.registerBlocked = new int[allocator.registers.length]; - assert checkEmpty(); - } - - boolean checkEmpty() { - assert mappingFrom.size() == 0 && mappingFromOpr.size() == 0 && mappingTo.size() == 0 : "list must be empty before and after processing"; - for (int i = 0; i < allocator.registers.length; i++) { - assert registerBlocked(i) == 0 : "register map must be empty before and after processing"; - } - assert !multipleReadsAllowed : "must have default value"; - return true; - } - - private boolean verifyBeforeResolve() { - assert mappingFrom.size() == mappingFromOpr.size() : "length must be equal"; - assert mappingFrom.size() == mappingTo.size() : "length must be equal"; - assert insertList != null && insertIdx != -1 : "insert position not set"; - - int i; - int j; - if (!multipleReadsAllowed) { - for (i = 0; i < mappingFrom.size(); i++) { - for (j = i + 1; j < mappingFrom.size(); j++) { - assert mappingFrom.get(i) == null || mappingFrom.get(i) != mappingFrom.get(j) : "cannot read from same interval twice"; - } - } - } - - for (i = 0; i < mappingTo.size(); i++) { - for (j = i + 1; j < mappingTo.size(); j++) { - assert mappingTo.get(i) != mappingTo.get(j) : "cannot write to same interval twice"; - } - } - - HashSet usedRegs = new HashSet(); - if (!multipleReadsAllowed) { - for (i = 0; i < mappingFrom.size(); i++) { - Interval interval = mappingFrom.get(i); - if (interval != null) { - boolean unique = usedRegs.add(interval.location()); - assert unique : "cannot read from same register twice"; - } - } - } - - usedRegs.clear(); - for (i = 0; i < mappingTo.size(); i++) { - Interval interval = mappingTo.get(i); - boolean unique = usedRegs.add(interval.location()); - assert unique : "cannot write to same register twice"; - } - - usedRegs.clear(); - for (i = 0; i < mappingFrom.size(); i++) { - Interval interval = mappingFrom.get(i); - if (interval != null && !interval.location().isRegister()) { - usedRegs.add(interval.location()); - } - } - for (i = 0; i < mappingTo.size(); i++) { - Interval interval = mappingTo.get(i); - assert !usedRegs.contains(interval.location()) || interval.location() == mappingFrom.get(i).location() : "stack slots used in mappingFrom must be disjoint to mappingTo"; - } - - return true; - } - - // mark assignedReg and assignedRegHi of the interval as blocked - private void blockRegisters(Interval interval) { - CiValue location = interval.location(); - if (location.isRegister()) { - int reg = location.asRegister().number; - assert multipleReadsAllowed || registerBlocked(reg) == 0 : "register already marked as used"; - setRegisterBlocked(reg, 1); - } - } - - // mark assignedReg and assignedRegHi of the interval as unblocked - private void unblockRegisters(Interval interval) { - CiValue location = interval.location(); - if (location.isRegister()) { - int reg = location.asRegister().number; - assert registerBlocked(reg) > 0 : "register already marked as unused"; - setRegisterBlocked(reg, -1); - } - } - - /** - * Checks if the {@linkplain Interval#location() location} of {@code to} is not blocked - * or is only blocked by {@code from}. - */ - private boolean safeToProcessMove(Interval from, Interval to) { - CiValue fromReg = from != null ? from.location() : null; - - CiValue reg = to.location(); - if (reg.isRegister()) { - if (registerBlocked(reg.asRegister().number) > 1 || (registerBlocked(reg.asRegister().number) == 1 && reg != fromReg)) { - return false; - } - } - - return true; - } - - private void createInsertionBuffer(LIRList list) { - assert !insertionBuffer.initialized() : "overwriting existing buffer"; - insertionBuffer.init(list); - } - - private void appendInsertionBuffer() { - if (insertionBuffer.initialized()) { - insertionBuffer.lirList().append(insertionBuffer); - } - assert !insertionBuffer.initialized() : "must be uninitialized now"; - - insertList = null; - insertIdx = -1; - } - - private void insertMove(Interval fromInterval, Interval toInterval) { - assert fromInterval.operand != toInterval.operand : "from and to interval equal: " + fromInterval; - assert Util.archKindsEqual(fromInterval.kind(), toInterval.kind()) : "move between different types"; - assert insertList != null && insertIdx != -1 : "must setup insert position first"; - assert insertionBuffer.lirList() == insertList : "wrong insertion buffer"; - - CiValue fromOpr = fromInterval.operand; - CiValue toOpr = toInterval.operand; - - insertionBuffer.move(insertIdx, fromOpr, toOpr, null); - - if (GraalOptions.TraceLinearScanLevel >= 4) { - TTY.println("MoveResolver: inserted move from %d (%s) to %d (%s)", fromInterval.operandNumber, fromInterval.location(), toInterval.operandNumber, toInterval.location()); - } - } - - private void insertMove(CiValue fromOpr, Interval toInterval) { - assert Util.archKindsEqual(fromOpr.kind, toInterval.kind()) : "move between different types"; - assert insertList != null && insertIdx != -1 : "must setup insert position first"; - assert insertionBuffer.lirList() == insertList : "wrong insertion buffer"; - - CiValue toOpr = toInterval.operand; - insertionBuffer.move(insertIdx, fromOpr, toOpr, null); - - if (GraalOptions.TraceLinearScanLevel >= 4) { - TTY.print("MoveResolver: inserted move from constant %s to %d (%s)", fromOpr, toInterval.operandNumber, toInterval.location()); - } - } - - private void resolveMappings() { - assert verifyBeforeResolve(); - - // Block all registers that are used as input operands of a move. - // When a register is blocked, no move to this register is emitted. - // This is necessary for detecting cycles in moves. - int i; - for (i = mappingFrom.size() - 1; i >= 0; i--) { - Interval fromInterval = mappingFrom.get(i); - if (fromInterval != null) { - blockRegisters(fromInterval); - } - } - - int spillCandidate = -1; - while (mappingFrom.size() > 0) { - boolean processedInterval = false; - - for (i = mappingFrom.size() - 1; i >= 0; i--) { - Interval fromInterval = mappingFrom.get(i); - Interval toInterval = mappingTo.get(i); - - if (safeToProcessMove(fromInterval, toInterval)) { - // this interval can be processed because target is free - if (fromInterval != null) { - insertMove(fromInterval, toInterval); - unblockRegisters(fromInterval); - } else { - insertMove(mappingFromOpr.get(i), toInterval); - } - mappingFrom.remove(i); - mappingFromOpr.remove(i); - mappingTo.remove(i); - - processedInterval = true; - } else if (fromInterval != null && fromInterval.location().isRegister()) { - // this interval cannot be processed now because target is not free - // it starts in a register, so it is a possible candidate for spilling - spillCandidate = i; - } - } - - if (!processedInterval) { - // no move could be processed because there is a cycle in the move list - // (e.g. r1 . r2, r2 . r1), so one interval must be spilled to memory - assert spillCandidate != -1 : "no interval in register for spilling found"; - - // create a new spill interval and assign a stack slot to it - Interval fromInterval = mappingFrom.get(spillCandidate); - Interval spillInterval = allocator.createDerivedInterval(fromInterval); - spillInterval.setKind(fromInterval.kind()); - - // add a dummy range because real position is difficult to calculate - // Note: this range is a special case when the integrity of the allocation is checked - spillInterval.addRange(1, 2); - - // do not allocate a new spill slot for temporary interval, but - // use spill slot assigned to fromInterval. Otherwise moves from - // one stack slot to another can happen (not allowed by LIRAssembler - CiStackSlot spillSlot = fromInterval.spillSlot(); - if (spillSlot == null) { - spillSlot = allocator.allocateSpillSlot(spillInterval.kind()); - fromInterval.setSpillSlot(spillSlot); - } - spillInterval.assignLocation(spillSlot); - - if (GraalOptions.TraceLinearScanLevel >= 4) { - TTY.println("created new Interval %s for spilling", spillInterval.operand); - } - - // insert a move from register to stack and update the mapping - insertMove(fromInterval, spillInterval); - mappingFrom.set(spillCandidate, spillInterval); - unblockRegisters(fromInterval); - } - } - - // reset to default value - multipleReadsAllowed = false; - - // check that all intervals have been processed - assert checkEmpty(); - } - - void setInsertPosition(LIRList insertList, int insertIdx) { - assert this.insertList == null && this.insertIdx == -1 : "use moveInsertPosition instead of setInsertPosition when data already set"; - - createInsertionBuffer(insertList); - this.insertList = insertList; - this.insertIdx = insertIdx; - } - - void moveInsertPosition(LIRList insertList, int insertIdx) { - if (this.insertList != null && (this.insertList != insertList || this.insertIdx != insertIdx)) { - // insert position changed . resolve current mappings - resolveMappings(); - } - - if (this.insertList != insertList) { - // block changed . append insertionBuffer because it is - // bound to a specific block and create a new insertionBuffer - appendInsertionBuffer(); - createInsertionBuffer(insertList); - } - - this.insertList = insertList; - this.insertIdx = insertIdx; - } - - void addMapping(Interval fromInterval, Interval toInterval) { - if (GraalOptions.TraceLinearScanLevel >= 4) { - TTY.println("MoveResolver: adding mapping from interval %d (%s) to interval %d (%s)", fromInterval.operandNumber, fromInterval.location(), toInterval.operandNumber, toInterval.location()); - } - - assert fromInterval.operand != toInterval.operand : "from and to interval equal: " + fromInterval; - assert Util.archKindsEqual(fromInterval.kind(), toInterval.kind()); - mappingFrom.add(fromInterval); - mappingFromOpr.add(CiValue.IllegalValue); - mappingTo.add(toInterval); - } - - void addMapping(CiValue fromOpr, Interval toInterval) { - if (GraalOptions.TraceLinearScanLevel >= 4) { - TTY.println("MoveResolver: adding mapping from %s to %d (%s)", fromOpr, toInterval.operandNumber, toInterval.location()); - } - assert fromOpr.isConstant() : "only for constants"; - - mappingFrom.add(null); - mappingFromOpr.add(fromOpr); - mappingTo.add(toInterval); - } - - void resolveAndAppendMoves() { - if (hasMappings()) { - resolveMappings(); - } - appendInsertionBuffer(); - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/alloc/OperandPool.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/alloc/OperandPool.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,269 +0,0 @@ -/* - * Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.compiler.alloc; - -import java.util.*; - -import com.oracle.max.graal.compiler.*; -import com.oracle.max.graal.graph.*; -import com.oracle.max.graal.nodes.*; -import com.sun.cri.ci.*; - -/** - * An ordered, 0-based indexable pool of instruction operands for a method being compiled. - * The physical {@linkplain CiRegister registers} of the platform occupy the front of the - * pool (starting at index 0) followed by {@linkplain CiVariable variable} operands. - * The index of an operand in the pool is its {@linkplain #operandNumber(CiValue) operand number}. - * - * In the original HotSpot C1 source code, this pool corresponds to the - * "flat register file" mentioned in c1_LinearScan.cpp. - * - * @author Doug Simon - */ -public final class OperandPool { - - public static final int INITIAL_VARIABLE_CAPACITY = 20; - - /** - * The physical registers occupying the head of the operand pool. This is the complete - * {@linkplain CiArchitecture#registers register set} of the target architecture, not - * just the allocatable registers. - */ - private final CiRegister[] registers; - - /** - * The variable operands allocated from this pool. The {@linkplain #operandNumber(CiValue) number} - * of the first variable operand in this pool is one greater than the number of the last - * register operand in the pool. - */ - private final ArrayList variables; - - /** - * Map from a {@linkplain CiVariable#index variable index} to the instruction whose result is stored in the denoted variable. - * This map is only populated and used if {@link GraalOptions#DetailedAsserts} is {@code true}. - */ - private final ArrayList variableDefs; - - /** - * The {@linkplain #operandNumber(CiValue) number} of the first variable operand - * {@linkplain #newVariable(CiKind) allocated} from this pool. - */ - private final int firstVariableNumber; - - /** - * Records which variable operands have the {@link VariableFlag#MustBeByteRegister} flag set. - */ - private BitMap mustBeByteRegister; - - /** - * Records which variable operands have the {@link VariableFlag#MustStartInMemory} flag set. - */ - private BitMap mustStartInMemory; - - /** - * Records which variable operands have the {@link VariableFlag#MustStayInMemory} flag set. - */ - private BitMap mustStayInMemory; - - /** - * Flags that can be set for {@linkplain CiValue#isVariable() variable} operands. - */ - public enum VariableFlag { - /** - * Denotes a variable that needs to be assigned a memory location - * at the beginning, but may then be loaded in a register. - */ - MustStartInMemory, - - /** - * Denotes a variable that needs to be assigned a memory location - * at the beginning and never subsequently loaded in a register. - */ - MustStayInMemory, - - /** - * Denotes a variable that must be assigned to a byte-sized register. - */ - MustBeByteRegister; - - public static final VariableFlag[] VALUES = values(); - } - - private static BitMap set(BitMap map, CiVariable variable) { - if (map == null) { - int length = BitMap.roundUpLength(variable.index + 1); - map = new BitMap(length); - } else if (map.size() <= variable.index) { - int length = BitMap.roundUpLength(variable.index + 1); - map.grow(length); - } - map.set(variable.index); - return map; - } - - private static boolean get(BitMap map, CiVariable variable) { - if (map == null || map.size() <= variable.index) { - return false; - } - return map.get(variable.index); - } - - /** - * Creates a new operand pool. - * - * @param target description of the target architecture for a compilation - */ - public OperandPool(CiTarget target) { - CiRegister[] registers = target.arch.registers; - this.firstVariableNumber = registers.length; - this.registers = registers; - variables = new ArrayList(INITIAL_VARIABLE_CAPACITY); - variableDefs = GraalOptions.DetailedAsserts ? new ArrayList(INITIAL_VARIABLE_CAPACITY) : null; - } - - /** - * Creates a new {@linkplain CiVariable variable} operand. - * - * @param kind the kind of the variable - * @return a new variable - */ - public CiVariable newVariable(CiKind kind) { - return newVariable(kind, kind == CiKind.Boolean || kind == CiKind.Byte ? VariableFlag.MustBeByteRegister : null); - } - - /** - * Creates a new {@linkplain CiVariable variable} operand. - * - * @param kind the kind of the variable - * @param flag a flag that is set for the new variable operand (ignored if {@code null}) - * @return a new variable operand - */ - public CiVariable newVariable(CiKind kind, VariableFlag flag) { - assert kind != CiKind.Void; - int varIndex = variables.size(); - CiVariable var = CiVariable.get(kind, varIndex); - if (flag == VariableFlag.MustBeByteRegister) { - mustBeByteRegister = set(mustBeByteRegister, var); - } else if (flag == VariableFlag.MustStartInMemory) { - mustStartInMemory = set(mustStartInMemory, var); - } else if (flag == VariableFlag.MustStayInMemory) { - mustStayInMemory = set(mustStayInMemory, var); - } else { - assert flag == null; - } - variables.add(var); - return var; - } - - /** - * Gets the unique number for an operand contained in this pool. - * - * - * @param operand an operand - * @return the unique number for {@code operand} in the range {@code [0 .. size())} - */ - public int operandNumber(CiValue operand) { - if (operand.isRegister()) { - int number = operand.asRegister().number; - assert number < firstVariableNumber; - return number; - } - assert operand.isVariable(); - return firstVariableNumber + ((CiVariable) operand).index; - } - - /** - * Gets the operand in this pool denoted by a given operand number. - * - * @param operandNumber a value that must be in the range {@code [0 .. size())} - * @return the operand in this pool denoted by {@code operandNumber} - */ - public CiValue operandFor(int operandNumber) { - if (operandNumber < firstVariableNumber) { - assert operandNumber >= 0; - return registers[operandNumber].asValue(); - } - int index = operandNumber - firstVariableNumber; - CiVariable variable = variables.get(index); - assert variable.index == index; - return variable; - } - - /** - * Records that the result of {@code instruction} is stored in {@code result}. - * - * @param result the variable storing the result of {@code instruction} - * @param instruction an instruction that produces a result (i.e. pushes a value to the stack) - */ - public void recordResult(CiVariable result, ValueNode instruction) { - while (variableDefs.size() <= result.index) { - variableDefs.add(null); - } - variableDefs.set(result.index, instruction); - } - - /** - * Gets the instruction whose result is recorded in a given variable. - * - * @param result the variable storing the result of an instruction - * @return the instruction that stores its result in {@code result} - */ - public ValueNode instructionForResult(CiVariable result) { - if (variableDefs.size() > result.index) { - return variableDefs.get(result.index); - } - return null; - } - - public boolean mustStartInMemory(CiVariable operand) { - return get(mustStartInMemory, operand) || get(mustStayInMemory, operand); - } - - public boolean mustStayInMemory(CiVariable operand) { - return get(mustStayInMemory, operand); - } - - public boolean mustBeByteRegister(CiValue operand) { - return get(mustBeByteRegister, (CiVariable) operand); - } - - public void setMustBeByteRegister(CiVariable operand) { - mustBeByteRegister = set(mustBeByteRegister, operand); - } - - /** - * Gets the number of operands in this pool. This value will increase by 1 for - * each new variable operand {@linkplain #newVariable(CiKind) allocated} from this pool. - */ - public int size() { - return firstVariableNumber + variables.size(); - } - - /** - * Gets the highest operand number for a register operand in this pool. This value will - * never change for the lifetime of this pool. - */ - public int maxRegisterNumber() { - return firstVariableNumber - 1; - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/alloc/Range.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/alloc/Range.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,119 +0,0 @@ -/* - * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.compiler.alloc; - - -/** - * Represents a range of integers from a start (inclusive) to an end (exclusive. - * - * @author Thomas Wuerthinger - */ -public final class Range { - - public static final Range EndMarker = new Range(Integer.MAX_VALUE, Integer.MAX_VALUE, null); - - /** - * The start of the range, inclusive. - */ - public int from; - - /** - * The end of the range, exclusive. - */ - public int to; - - /** - * A link to allow the range to be put into a singly linked list. - */ - public Range next; - - boolean intersects(Range r) { - return intersectsAt(r) != -1; - } - - - /** - * Creates a new range. - * - * @param from the start of the range, inclusive - * @param to the end of the range, exclusive - * @param next link to the next range in a linked list - */ - Range(int from, int to, Range next) { - this.from = from; - this.to = to; - this.next = next; - } - - int intersectsAt(Range r2) { - Range r1 = this; - - assert r2 != null : "null ranges not allowed"; - assert r1 != EndMarker && r2 != EndMarker : "empty ranges not allowed"; - - do { - if (r1.from < r2.from) { - if (r1.to <= r2.from) { - r1 = r1.next; - if (r1 == EndMarker) { - return -1; - } - } else { - return r2.from; - } - } else { - if (r2.from < r1.from) { - if (r2.to <= r1.from) { - r2 = r2.next; - if (r2 == EndMarker) { - return -1; - } - } else { - return r1.from; - } - } else { // r1.from() == r2.from() - if (r1.from == r1.to) { - r1 = r1.next; - if (r1 == EndMarker) { - return -1; - } - } else { - if (r2.from == r2.to) { - r2 = r2.next; - if (r2 == EndMarker) { - return -1; - } - } else { - return r1.from; - } - } - } - } - } while (true); - } - - @Override - public String toString() { - return "[" + from + ", " + to + "]"; - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/alloc/RegisterVerifier.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/alloc/RegisterVerifier.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,277 +0,0 @@ -/* - * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.compiler.alloc; - -import java.util.*; - -import com.oracle.max.graal.compiler.*; -import com.oracle.max.graal.compiler.debug.*; -import com.oracle.max.graal.compiler.lir.*; -import com.oracle.max.graal.compiler.util.*; -import com.sun.cri.ci.*; - -/** - * - * @author Thomas Wuerthinger - */ -final class RegisterVerifier { - - LinearScan allocator; - List workList; // all blocks that must be processed - ArrayMap savedStates; // saved information of previous check - - // simplified access to methods of LinearScan - GraalCompilation compilation() { - return allocator.compilation; - } - - Interval intervalAt(CiValue operand) { - return allocator.intervalFor(operand); - } - - // currently, only registers are processed - int stateSize() { - return allocator.operands.maxRegisterNumber() + 1; - } - - // accessors - Interval[] stateForBlock(LIRBlock block) { - return savedStates.get(block.blockID()); - } - - void setStateForBlock(LIRBlock block, Interval[] savedState) { - savedStates.put(block.blockID(), savedState); - } - - void addToWorkList(LIRBlock block) { - if (!workList.contains(block)) { - workList.add(block); - } - } - - RegisterVerifier(LinearScan allocator) { - this.allocator = allocator; - workList = new ArrayList(16); - this.savedStates = new ArrayMap(); - - } - - void verify(LIRBlock start) { - // setup input registers (method arguments) for first block - Interval[] inputState = new Interval[stateSize()]; - CiCallingConvention args = compilation().frameMap().incomingArguments(); - for (int n = 0; n < args.locations.length; n++) { - CiValue operand = args.locations[n]; - if (operand.isRegister()) { - CiValue reg = operand; - Interval interval = intervalAt(reg); - inputState[reg.asRegister().number] = interval; - } - } - - setStateForBlock(start, inputState); - addToWorkList(start); - - // main loop for verification - do { - LIRBlock block = workList.get(0); - workList.remove(0); - - processBlock(block); - } while (!workList.isEmpty()); - } - - private void processBlock(LIRBlock block) { - if (GraalOptions.TraceLinearScanLevel >= 2) { - TTY.println(); - TTY.println("processBlock B%d", block.blockID()); - } - - // must copy state because it is modified - Interval[] inputState = copy(stateForBlock(block)); - - if (GraalOptions.TraceLinearScanLevel >= 4) { - TTY.println("Input-State of intervals:"); - TTY.print(" "); - for (int i = 0; i < stateSize(); i++) { - if (inputState[i] != null) { - TTY.print(" %4d", inputState[i].operandNumber); - } else { - TTY.print(" __"); - } - } - TTY.println(); - TTY.println(); - } - - // process all operations of the block - processOperations(block.lir(), inputState); - - // iterate all successors - for (LIRBlock succ : block.blockSuccessors()) { - processSuccessor(succ, inputState); - } - } - - private void processSuccessor(LIRBlock block, Interval[] inputState) { - Interval[] savedState = stateForBlock(block); - - if (savedState != null) { - // this block was already processed before. - // check if new inputState is consistent with savedState - - boolean savedStateCorrect = true; - for (int i = 0; i < stateSize(); i++) { - if (inputState[i] != savedState[i]) { - // current inputState and previous savedState assume a different - // interval in this register . assume that this register is invalid - if (savedState[i] != null) { - // invalidate old calculation only if it assumed that - // register was valid. when the register was already invalid, - // then the old calculation was correct. - savedStateCorrect = false; - savedState[i] = null; - - if (GraalOptions.TraceLinearScanLevel >= 4) { - TTY.println("processSuccessor B%d: invalidating slot %d", block.blockID(), i); - } - } - } - } - - if (savedStateCorrect) { - // already processed block with correct inputState - if (GraalOptions.TraceLinearScanLevel >= 2) { - TTY.println("processSuccessor B%d: previous visit already correct", block.blockID()); - } - } else { - // must re-visit this block - if (GraalOptions.TraceLinearScanLevel >= 2) { - TTY.println("processSuccessor B%d: must re-visit because input state changed", block.blockID()); - } - addToWorkList(block); - } - - } else { - // block was not processed before, so set initial inputState - if (GraalOptions.TraceLinearScanLevel >= 2) { - TTY.println("processSuccessor B%d: initial visit", block.blockID()); - } - - setStateForBlock(block, copy(inputState)); - addToWorkList(block); - } - } - - Interval[] copy(Interval[] inputState) { - return inputState.clone(); - } - - void statePut(Interval[] inputState, CiValue location, Interval interval) { - if (location != null && location.isRegister()) { - CiRegister reg = location.asRegister(); - int regNum = reg.number; - if (interval != null) { - if (GraalOptions.TraceLinearScanLevel >= 4) { - TTY.println(" %s = %s", reg, interval.operand); - } - } else if (inputState[regNum] != null) { - if (GraalOptions.TraceLinearScanLevel >= 4) { - TTY.println(" %s = null", reg); - } - } - - inputState[regNum] = interval; - } - } - - boolean checkState(Interval[] inputState, CiValue reg, Interval interval) { - if (reg != null && reg.isRegister()) { - if (inputState[reg.asRegister().number] != interval) { - throw new CiBailout("!! Error in register allocation: register " + reg + " does not contain interval " + interval.operand + " but interval " + inputState[reg.asRegister().number]); - } - } - return true; - } - - void processOperations(LIRList ops, Interval[] inputState) { - // visit all instructions of the block - for (int i = 0; i < ops.length(); i++) { - LIRInstruction op = ops.at(i); - - if (GraalOptions.TraceLinearScanLevel >= 4) { - TTY.println(op.toStringWithIdPrefix()); - } - - // check if input operands are correct - int n = op.operandCount(LIRInstruction.OperandMode.Input); - for (int j = 0; j < n; j++) { - CiValue operand = op.operandAt(LIRInstruction.OperandMode.Input, j); - if (allocator.isProcessed(operand)) { - Interval interval = intervalAt(operand); - if (op.id() != -1) { - interval = interval.getSplitChildAtOpId(op.id(), LIRInstruction.OperandMode.Input, allocator); - } - - assert checkState(inputState, interval.location(), interval.splitParent()); - } - } - - // invalidate all caller save registers at calls - if (op.hasCall) { - for (CiRegister r : allocator.compilation.registerConfig.getCallerSaveRegisters()) { - statePut(inputState, r.asValue(), null); - } - } - - // set temp operands (some operations use temp operands also as output operands, so can't set them null) - n = op.operandCount(LIRInstruction.OperandMode.Temp); - for (int j = 0; j < n; j++) { - CiValue operand = op.operandAt(LIRInstruction.OperandMode.Temp, j); - if (allocator.isProcessed(operand)) { - Interval interval = intervalAt(operand); - assert interval != null : "Could not find interval for operand " + operand; - if (op.id() != -1) { - interval = interval.getSplitChildAtOpId(op.id(), LIRInstruction.OperandMode.Temp, allocator); - } - - statePut(inputState, interval.location(), interval.splitParent()); - } - } - - // set output operands - n = op.operandCount(LIRInstruction.OperandMode.Output); - for (int j = 0; j < n; j++) { - CiValue operand = op.operandAt(LIRInstruction.OperandMode.Output, j); - if (allocator.isProcessed(operand)) { - Interval interval = intervalAt(operand); - if (op.id() != -1) { - interval = interval.getSplitChildAtOpId(op.id(), LIRInstruction.OperandMode.Output, allocator); - } - - statePut(inputState, interval.location(), interval.splitParent()); - } - } - } - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/asm/ExceptionInfo.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/asm/ExceptionInfo.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,38 +0,0 @@ -/* - * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.compiler.asm; - -import com.oracle.max.graal.compiler.lir.*; - -public class ExceptionInfo { - - public final int codeOffset; - public final LIRBlock exceptionEdge; - public final int bci; - - public ExceptionInfo(int pcOffset, LIRBlock exceptionEdge, int bci) { - this.codeOffset = pcOffset; - this.exceptionEdge = exceptionEdge; - this.bci = bci; - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/asm/TargetMethodAssembler.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/asm/TargetMethodAssembler.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,200 +0,0 @@ -/* - * Copyright (c) 2011, 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.compiler.asm; - -import java.util.*; - -import com.oracle.max.asm.*; -import com.oracle.max.graal.compiler.*; -import com.oracle.max.graal.compiler.debug.*; -import com.oracle.max.graal.compiler.lir.*; -import com.oracle.max.graal.compiler.util.*; -import com.sun.cri.ci.*; -import com.sun.cri.ri.*; - -public class TargetMethodAssembler { - public final AbstractAssembler asm; - public final CiTargetMethod targetMethod; - public List exceptionInfoList; - protected int lastSafepointPos; - - public TargetMethodAssembler(AbstractAssembler asm) { - this.asm = asm; - this.targetMethod = new CiTargetMethod(); - } - - public void setFrameSize(int frameSize) { - targetMethod.setFrameSize(frameSize); - } - - public CiTargetMethod.Mark recordMark(Object id, CiTargetMethod.Mark[] references) { - return targetMethod.recordMark(asm.codeBuffer.position(), id, references); - } - - public void blockComment(String s) { - targetMethod.addAnnotation(new CiTargetMethod.CodeComment(asm.codeBuffer.position(), s)); - } - - public CiTargetMethod finishTargetMethod(Object name, RiRuntime runtime, int registerRestoreEpilogueOffset, boolean isStub) { - // Install code, data and frame size - targetMethod.setTargetCode(asm.codeBuffer.close(false), asm.codeBuffer.position()); - targetMethod.setRegisterRestoreEpilogueOffset(registerRestoreEpilogueOffset); - - // Record exception handlers if they exist - if (exceptionInfoList != null) { - for (ExceptionInfo ei : exceptionInfoList) { - int codeOffset = ei.codeOffset; - targetMethod.recordExceptionHandler(codeOffset, -1, 0, ei.exceptionEdge.blockEntryPco, -1, null); - } - } - - if (GraalOptions.Meter) { - GraalMetrics.TargetMethods++; - GraalMetrics.CodeBytesEmitted += targetMethod.targetCodeSize(); - GraalMetrics.SafepointsEmitted += targetMethod.safepoints.size(); - GraalMetrics.DirectCallSitesEmitted += targetMethod.directCalls.size(); - GraalMetrics.IndirectCallSitesEmitted += targetMethod.indirectCalls.size(); - GraalMetrics.DataPatches += targetMethod.dataReferences.size(); - GraalMetrics.ExceptionHandlersEmitted += targetMethod.exceptionHandlers.size(); - } - - if (GraalOptions.PrintAssembly && !TTY.isSuppressed() && !isStub) { - Util.printSection("Target Method", Util.SECTION_CHARACTER); - TTY.println("Name: " + name); - TTY.println("Frame size: " + targetMethod.frameSize()); - TTY.println("Register size: " + asm.target.arch.registerReferenceMapBitCount); - - if (GraalOptions.PrintCodeBytes) { - Util.printSection("Code", Util.SUB_SECTION_CHARACTER); - TTY.println("Code: %d bytes", targetMethod.targetCodeSize()); - Util.printBytes(0L, targetMethod.targetCode(), 0, targetMethod.targetCodeSize(), GraalOptions.PrintAssemblyBytesPerLine); - } - - Util.printSection("Disassembly", Util.SUB_SECTION_CHARACTER); - String disassembly = runtime.disassemble(targetMethod); - TTY.println(disassembly); - boolean noDis = disassembly == null || disassembly.length() == 0; - - Util.printSection("Safepoints", Util.SUB_SECTION_CHARACTER); - for (CiTargetMethod.Safepoint x : targetMethod.safepoints) { - TTY.println(x.toString()); - if (noDis && x.debugInfo != null) { - TTY.println(CiUtil.indent(x.debugInfo.toString(), " ")); - } - } - - Util.printSection("Direct Call Sites", Util.SUB_SECTION_CHARACTER); - for (CiTargetMethod.Call x : targetMethod.directCalls) { - TTY.println(x.toString()); - if (noDis && x.debugInfo != null) { - TTY.println(CiUtil.indent(x.debugInfo.toString(), " ")); - } - } - - Util.printSection("Indirect Call Sites", Util.SUB_SECTION_CHARACTER); - for (CiTargetMethod.Call x : targetMethod.indirectCalls) { - TTY.println(x.toString()); - if (noDis && x.debugInfo != null) { - TTY.println(CiUtil.indent(x.debugInfo.toString(), " ")); - } - } - - Util.printSection("Data Patches", Util.SUB_SECTION_CHARACTER); - for (CiTargetMethod.DataPatch x : targetMethod.dataReferences) { - TTY.println(x.toString()); - } - - Util.printSection("Marks", Util.SUB_SECTION_CHARACTER); - for (CiTargetMethod.Mark x : targetMethod.marks) { - TTY.println(x.toString()); - } - - Util.printSection("Exception Handlers", Util.SUB_SECTION_CHARACTER); - for (CiTargetMethod.ExceptionHandler x : targetMethod.exceptionHandlers) { - TTY.println(x.toString()); - } - } - - return targetMethod; - } - - public void recordExceptionHandlers(int pcOffset, LIRDebugInfo info) { - if (info != null) { - if (info.exceptionEdge() != null) { - if (exceptionInfoList == null) { - exceptionInfoList = new ArrayList(4); - } - exceptionInfoList.add(new ExceptionInfo(pcOffset, info.exceptionEdge(), info.state.bci)); - } - } - } - - public void recordImplicitException(int pcOffset, LIRDebugInfo info) { - // record an implicit exception point - if (info != null) { - assert lastSafepointPos < pcOffset; - lastSafepointPos = pcOffset; - targetMethod.recordSafepoint(pcOffset, info.debugInfo()); - assert info.exceptionEdge() == null; - } - } - - public void recordDirectCall(int posBefore, int posAfter, Object target, LIRDebugInfo info) { - CiDebugInfo debugInfo = info != null ? info.debugInfo() : null; - assert lastSafepointPos < posAfter; - lastSafepointPos = posAfter; - targetMethod.recordCall(posBefore, posAfter - posBefore, target, debugInfo, true); - } - - public void recordIndirectCall(int posBefore, int posAfter, Object target, LIRDebugInfo info) { - CiDebugInfo debugInfo = info != null ? info.debugInfo() : null; - assert lastSafepointPos < posAfter; - lastSafepointPos = posAfter; - targetMethod.recordCall(posBefore, posAfter - posBefore, target, debugInfo, false); - } - - public void recordSafepoint(int pos, LIRDebugInfo info) { - // safepoints always need debug info - CiDebugInfo debugInfo = info.debugInfo(); - assert lastSafepointPos < pos; - lastSafepointPos = pos; - targetMethod.recordSafepoint(pos, debugInfo); - } - - public CiAddress recordDataReferenceInCode(CiConstant data) { - assert data != null; - - int pos = asm.codeBuffer.position(); - - if (GraalOptions.TraceRelocation) { - TTY.print("Data reference in code: pos = %d, data = %s", pos, data.toString()); - } - - targetMethod.recordDataReference(pos, data); - return CiAddress.Placeholder; - } - - public int lastSafepointPos() { - return lastSafepointPos; - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/debug/BlockPrinter.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/debug/BlockPrinter.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,121 +0,0 @@ -/* - * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.compiler.debug; - -import com.oracle.max.graal.compiler.graph.*; -import com.oracle.max.graal.compiler.schedule.*; -import com.oracle.max.graal.graph.*; -import com.oracle.max.graal.nodes.*; - -/** - * Prints a listing for a {@linkplain MergeNode block}. - */ -public class BlockPrinter implements BlockClosure { - - private final InstructionPrinter ip; - private final boolean cfgOnly; - - public BlockPrinter(IR ir, InstructionPrinter ip, boolean cfgOnly) { - this.ip = ip; - this.cfgOnly = cfgOnly; - } - - public void apply(Block block) { - if (cfgOnly) { - if (block.getInstructions().size() > 0) { - ip.printInstruction((FixedWithNextNode) block.getInstructions().get(0)); - } else { - ip.out().println("Empty block"); - } - ip.out().println(); - } else { - printBlock(block); - } - } - - public void printBlock(Block block) { - LogStream out = ip.out(); - out.println(); - - ip.printInstructionListingHeader(); - - for (Node i : block.getInstructions()) { - if (i instanceof FixedWithNextNode) { - ip.printInstructionListing((FixedWithNextNode) i); - } - } - out.println(); - - } - - private static void printFrameState(FrameState newFrameState, LogStream out) { - int startPosition = out.position(); - if (newFrameState.stackSize() == 0) { - out.print("empty stack"); - } else { - out.print("stack ["); - int i = 0; - while (i < newFrameState.stackSize()) { - if (i > 0) { - out.print(", "); - } - ValueNode value = newFrameState.stackAt(i); - out.print(i + ":" + ValueUtil.valueString(value)); - if (value == null) { - i++; - } else { - i += value.kind.sizeInSlots(); - if (value instanceof PhiNode) { - PhiNode phi = (PhiNode) value; - if (phi.operand() != null) { - out.print(" "); - out.print(phi.operand().toString()); - } - } - } - } - out.print(']'); - } - if (newFrameState.locksSize() != 0) { - // print out the lines on the line below this - // one at the same indentation level. - out.println(); - out.fillTo(startPosition, ' '); - out.print("locks ["); - for (int i = 0; i < newFrameState.locksSize(); i++) { - ValueNode value = newFrameState.lockAt(i); - if (i > 0) { - out.print(", "); - } - out.print(i + ":"); - if (value == null) { - // synchronized methods push null on the lock stack - out.print("this"); - } else { - out.print(ValueUtil.valueString(value)); - } - } - out.print("]"); - } - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/debug/CFGPrinter.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/debug/CFGPrinter.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,637 +0,0 @@ -/* - * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.compiler.debug; - -import java.io.*; -import java.util.*; - -import com.oracle.max.graal.compiler.*; -import com.oracle.max.graal.compiler.alloc.*; -import com.oracle.max.graal.compiler.alloc.Interval.UsePosList; -import com.oracle.max.graal.compiler.graph.*; -import com.oracle.max.graal.compiler.lir.*; -import com.oracle.max.graal.compiler.lir.LIRInstruction.OperandFormatter; -import com.oracle.max.graal.compiler.schedule.*; -import com.oracle.max.graal.graph.*; -import com.oracle.max.graal.nodes.*; -import com.sun.cri.ci.*; -import com.sun.cri.ci.CiAddress.Scale; -import com.sun.cri.ri.*; - -/** - * Utility for printing the control flow graph of a method being compiled by Graal at various compilation phases. - * The output format matches that produced by HotSpot so that it can then be fed to the - * C1 Visualizer. - */ -public class CFGPrinter { - private static final String COLUMN_END = " <|@"; - private static final String HOVER_START = "<@"; - private static final String HOVER_SEP = "|@"; - private static final String HOVER_END = ">@"; - - private static OutputStream cfgFileStream; - - /** - * Gets the output stream on the file "output.cfg" in the current working directory. - * This stream is first opened if necessary. - * - * @return the output stream to "output.cfg" or {@code null} if there was an error opening this file for writing - */ - public static synchronized OutputStream cfgFileStream() { - if (cfgFileStream == null) { - File cfgFile = new File("output.cfg"); - try { - cfgFileStream = new FileOutputStream(cfgFile); - } catch (FileNotFoundException e) { - TTY.println("WARNING: Could not open " + cfgFile.getAbsolutePath()); - } - } - return cfgFileStream; - } - - private final LogStream out; - private final CiTarget target; - - /** - * Creates a control flow graph printer. - * - * @param os where the output generated via this printer shown be written - * @param target the target architecture description - */ - public CFGPrinter(OutputStream os, CiTarget target) { - out = new LogStream(os); - this.target = target; - } - - /** - * Flushes all buffered output to the stream passed to {@link #CFGPrinter(OutputStream, CiTarget)}. - */ - public void flush() { - out.flush(); - } - - private void begin(String string) { - out.println("begin_" + string); - out.adjustIndentation(2); - } - - private void end(String string) { - out.adjustIndentation(-2); - out.println("end_" + string); - } - - /** - * Prints a compilation timestamp for a given method. - * - * @param method the method for which a timestamp will be printed - */ - public void printCompilation(RiMethod method) { - begin("compilation"); - out.print("name \" ").print(CiUtil.format("%H::%n", method, true)).println('"'); - out.print("method \"").print(CiUtil.format("%f %r %H.%n(%p)", method, true)).println('"'); - out.print("date ").println(System.currentTimeMillis()); - end("compilation"); - } - - /** - * Print the details of a given control flow graph block. - * - * @param block the block to print - * @param successors the successor blocks of {@code block} - * @param handlers the exception handler blocks of {@code block} - * @param printHIR if {@code true} the HIR for each instruction in the block will be printed - * @param printLIR if {@code true} the LIR for each instruction in the block will be printed - */ - void printBlock(Block block, List successors, Block handler, boolean printHIR, boolean printLIR) { - begin("block"); - - out.print("name \"B").print(block.blockID()).println('"'); - out.print("from_bci -1"); - out.print("to_bci -1"); - - out.print("predecessors "); - for (Block pred : block.getPredecessors()) { - out.print("\"B").print(pred.blockID()).print("\" "); - } - out.println(); - - out.print("successors "); - for (Block succ : successors) { - out.print("\"B").print(succ.blockID()).print("\" "); - } - out.println(); - - out.print("xhandlers"); - if (handler != null) { - out.print("\"B").print(handler.blockID()).print("\" "); - } - out.println(); - - out.print("flags "); - out.println(); - - out.print("loop_index ").println(-1); - out.print("loop_depth ").println(-1); - - if (printHIR) { - printHIR(block); - } - - // TODO(tw): Add possibility to print LIR. - //if (printLIR) { - // printLIR(block.lirBlock()); - //} - - end("block"); - } - - /** - * Prints the JVM frame state upon entry to a given block. - * - * @param block the block for which the frame state is to be printed - */ - /*private void printState(Block block) { - begin("states"); - - FrameState state = block.stateBefore(); - if (state == null) { - return; - } - int stackSize = state.stackSize(); - if (stackSize > 0) { - begin("stack"); - out.print("size ").println(stackSize); - out.print("method \"").print(CiUtil.toLocation(GraalCompilation.compilation().method, state.bci)).println('"'); - - int i = 0; - while (i < stackSize) { - Value value = state.stackAt(i); - out.disableIndentation(); - out.print(block.stateString(i, value)); - printOperand(value); - out.println(); - out.enableIndentation(); - if (value == null) { - i++; - } else { - i += value.kind.sizeInSlots(); - } - } - end("stack"); - } - - if (state.locksSize() > 0) { - begin("locks"); - out.print("size ").println(state.locksSize()); - out.print("method \"").print(CiUtil.toLocation(GraalCompilation.compilation().method, state.bci)).println('"'); - - for (int i = 0; i < state.locksSize(); ++i) { - Value value = state.lockAt(i); - out.disableIndentation(); - out.print(block.stateString(i, value)); - printOperand(value); - out.println(); - out.enableIndentation(); - } - end("locks"); - } - - begin("locals"); - out.print("size ").println(state.localsSize()); - out.print("method \"").print(CiUtil.toLocation(GraalCompilation.compilation().method, state.bci)).println('"'); - int i = 0; - while (i < state.localsSize()) { - Value value = state.localAt(i); - if (value != null) { - out.disableIndentation(); - out.print(block.stateString(i, value)); - printOperand(value); - out.println(); - out.enableIndentation(); - // also ignore illegal HiWords - i += value.isIllegal() ? 1 : value.kind.sizeInSlots(); - } else { - i++; - } - } - end("locals"); - end("states"); - }*/ - - /** - * Formats a given {@linkplain FrameState JVM frame state} as a multi line string. - */ - private String stateToString(FrameState state, CFGOperandFormatter operandFmt) { - if (state == null) { - return null; - } - - StringBuilder buf = new StringBuilder(); - buf.append(CiUtil.toLocation(GraalCompilation.compilation().method, state.bci)); - buf.append('\n'); - if (state.stackSize() > 0) { - int i = 0; - buf.append("stack: "); - while (i < state.stackSize()) { - if (i == 0) { - buf.append(' '); - } - ValueNode value = state.stackAt(i); - buf.append(stateValueToString(value, operandFmt)).append(' '); - i++; - } - buf.append("\n"); - } - - if (state.locksSize() > 0) { - buf.append("locks: "); - for (int i = 0; i < state.locksSize(); ++i) { - if (i == 0) { - buf.append(' '); - } - ValueNode value = state.lockAt(i); - buf.append(stateValueToString(value, operandFmt)).append(' '); - } - buf.append("\n"); - } - - buf.append("locals: "); - int i = 0; - while (i < state.localsSize()) { - if (i == 0) { - buf.append(' '); - } - ValueNode value = state.localAt(i); - buf.append(stateValueToString(value, operandFmt)).append(' '); - i++; - } - buf.append("\n"); - return buf.toString(); - } - - private String stateValueToString(ValueNode value, OperandFormatter operandFmt) { - if (operandFmt == null) { - return ValueUtil.valueString(value); - } - if (value == null) { - return "-"; - } - return operandFmt.format(value.operand()); - } - - private String stateValueToString(CiValue value, OperandFormatter operandFmt) { - if (value == null) { - return "-"; - } - return operandFmt.format(value); - } - - /** - * Formats a given {@linkplain FrameState JVM frame state} as a multi line string. - */ - private String debugInfoToString(CiDebugInfo info, CFGOperandFormatter operandFmt) { - if (info == null) { - return null; - } - StringBuilder sb = new StringBuilder(); - - - if (info.hasRegisterRefMap()) { - sb.append("reg-ref-map:"); - GraalCompilation compilation = GraalCompilation.compilation(); - CiArchitecture arch = compilation == null ? null : compilation.target.arch; - for (int reg = info.registerRefMap.nextSetBit(0); reg >= 0; reg = info.registerRefMap.nextSetBit(reg + 1)) { - sb.append(' ').append(arch == null ? "reg" + reg : arch.registers[reg]); - } - sb.append("\n"); - } - if (info.hasStackRefMap()) { - sb.append("frame-ref-map:"); - BitMap bm = info.frameRefMap; - for (int i = bm.nextSetBit(0); i >= 0; i = bm.nextSetBit(i + 1)) { - sb.append(' ').append(CiStackSlot.get(CiKind.Object, i)); - } - sb.append("\n"); - } - if (info.codePos != null) { - sb.append(stateToString(info.codePos, operandFmt)); - } - return sb.toString(); - } - - /** - * Formats a given {@linkplain FrameState JVM frame state} as a multi line string. - */ - private String stateToString(CiCodePos codePos, CFGOperandFormatter operandFmt) { - if (codePos == null) { - return null; - } - - StringBuilder buf = new StringBuilder(); - - do { - buf.append(CiUtil.toLocation(codePos.method, codePos.bci)); - buf.append('\n'); - if (codePos instanceof CiFrame) { - CiFrame frame = (CiFrame) codePos; - if (frame.numStack > 0) { - int i = 0; - buf.append("stack: "); - while (i < frame.numStack) { - if (i == 0) { - buf.append(' '); - } - CiValue value = frame.getStackValue(i); - buf.append(stateValueToString(value, operandFmt)).append(' '); - i++; - } - buf.append("\n"); - } - - if (frame.numLocks > 0) { - buf.append("locks: "); - for (int i = 0; i < frame.numLocks; ++i) { - if (i == 0) { - buf.append(' '); - } - CiValue value = frame.getLockValue(i); - buf.append(stateValueToString(value, operandFmt)).append(' '); - } - buf.append("\n"); - } - - buf.append("locals: "); - int i = 0; - while (i < frame.numLocals) { - if (i == 0) { - buf.append(' '); - } - CiValue value = frame.getLocalValue(i); - buf.append(stateValueToString(value, operandFmt)).append(' '); - i++; - } - buf.append("\n"); - } - codePos = codePos.caller; - } while (codePos != null); - return buf.toString(); - } - - /** - * Prints the HIR for each instruction in a given block. - * - * @param block - */ - private void printHIR(Block block) { - begin("IR"); - out.println("HIR"); - out.disableIndentation(); - for (Node i : block.getInstructions()) { - if (i instanceof FixedWithNextNode) { - printInstructionHIR((FixedWithNextNode) i); - } - } - out.enableIndentation(); - end("IR"); - } - - /** - * Formats LIR operands as expected by the C1 Visualizer. - */ - public static class CFGOperandFormatter extends OperandFormatter { - /** - * The textual delimiters used for an operand depend on the context in which it is being - * printed. When printed as part of a frame state or as the result operand in a HIR node listing, - * it is enclosed in double-quotes (i.e. {@code "}'s). - */ - public final boolean asStateOrHIROperandResult; - - public CFGOperandFormatter(boolean asStateOrHIROperandResult) { - this.asStateOrHIROperandResult = asStateOrHIROperandResult; - } - - @Override - public String format(CiValue operand) { - if (operand.isLegal()) { - String op; - if (operand.isVariableOrRegister() || operand.isStackSlot()) { - op = operand.name(); - } else if (operand.isConstant()) { - CiConstant constant = (CiConstant) operand; - op = operand.kind.javaName + ":" + operand.kind.format(constant.boxedValue()); - } else if (operand.isAddress()) { - CiAddress address = (CiAddress) operand; - op = "Base:" + format(address.base); - if (!address.index.isIllegal()) { - op += " Index:" + format(address.index); - } - if (address.scale != Scale.Times1) { - op += " * " + address.scale.value; - } - op += " Disp:" + address.displacement; - } else { - assert operand.isIllegal(); - op = "-"; - } - if (operand.kind != CiKind.Illegal) { - op += "|" + operand.kind.typeChar; - } - if (asStateOrHIROperandResult) { - op = " \"" + op.replace('"', '\'') + "\" "; - } - return op; - } - return ""; - } - } - - /** - * Prints the LIR for each instruction in a given block. - * - * @param block the block to print - */ - private void printLIR(LIRBlock block) { - LIRList lir = block.lir(); - if (lir != null) { - begin("IR"); - out.println("LIR"); - for (int i = 0; i < lir.length(); i++) { - LIRInstruction inst = lir.at(i); - out.printf("nr %4d ", inst.id()).print(COLUMN_END); - - if (inst.info != null) { - int level = out.indentationLevel(); - out.adjustIndentation(-level); - String state; - if (inst.info.debugInfo != null) { - // Use register-allocator output if available - state = debugInfoToString(inst.info.debugInfo, new CFGOperandFormatter(false)); - } else { - state = stateToString(inst.info.state, new CFGOperandFormatter(false)); - } - if (state != null) { - out.print(" st ").print(HOVER_START).print("st").print(HOVER_SEP).print(state).print(HOVER_END).print(COLUMN_END); - } - out.adjustIndentation(level); - } - - out.print(" instruction ").print(inst.toString(new CFGOperandFormatter(false))).print(COLUMN_END); - out.println(COLUMN_END); - } - end("IR"); - } - } - - private void printOperand(ValueNode i) { - if (i != null && i.operand().isLegal()) { - out.print(new CFGOperandFormatter(true).format(i.operand())); - } - } - - /** - * Prints the HIR for a given instruction. - * - * @param i the instruction for which HIR will be printed - */ - private void printInstructionHIR(FixedWithNextNode i) { - out.print("bci ").print(-1).println(COLUMN_END); - if (i.operand().isLegal()) { - out.print("result ").print(new CFGOperandFormatter(false).format(i.operand())).println(COLUMN_END); - } - out.print("tid ").print(i).println(COLUMN_END); - - if (i instanceof StateSplit) { - StateSplit stateSplit = (StateSplit) i; - String state = stateToString(stateSplit.stateAfter(), null); - if (state != null) { - out.print("st ").print(HOVER_START).print("st").print(HOVER_SEP).print(state).print(HOVER_END).println(COLUMN_END); - } - } - - out.print("instruction "); - out.print(i.toString()); - out.print(COLUMN_END).print(' ').println(COLUMN_END); - } - - /** - * Prints the control flow graph denoted by a given block map. - * - * @param blockMap a data structure describing the blocks in a method and how they are connected - * @param codeSize the bytecode size of the method from which {@code blockMap} was produced - * @param label a label describing the compilation phase that produced the control flow graph - * @param printHIR if {@code true} the HIR for each instruction in the block will be printed - * @param printLIR if {@code true} the LIR for each instruction in the block will be printed - */ - public void printCFG(RiMethod method, BlockMap blockMap, int codeSize, String label, boolean printHIR, boolean printLIR) { - begin("cfg"); - out.print("name \"").print(label).println('"'); - for (BlockMap.Block block : blockMap.blocks) { - begin("block"); - blockMap.printBlock(block, out); - end("block"); - } - end("cfg"); - } - - /** - * Prints the control flow graph rooted at a given block. - * - * @param startBlock the entry block of the control flow graph to be printed - * @param label a label describing the compilation phase that produced the control flow graph - * @param printHIR if {@code true} the HIR for each instruction in the block will be printed - * @param printLIR if {@code true} the LIR for each instruction in the block will be printed - */ - public void printCFG(Block startBlock, String label, final boolean printHIR, final boolean printLIR) { - begin("cfg"); - out.print("name \"").print(label).println('"'); - startBlock.iteratePreOrder(new BlockClosure() { - public void apply(Block block) { - List successors = block.getSuccessors(); - printBlock(block, successors, null, printHIR, printLIR); - } - }); - end("cfg"); - } - - public void printIntervals(LinearScan allocator, Interval[] intervals, String name) { - begin("intervals"); - out.println(String.format("name \"%s\"", name)); - - for (Interval interval : intervals) { - if (interval != null) { - printInterval(allocator, interval); - } - } - - end("intervals"); - } - - private void printInterval(LinearScan allocator, Interval interval) { - out.printf("%d %s ", interval.operandNumber, (interval.operand.isRegister() ? "fixed" : interval.kind().name())); - if (interval.operand.isRegister()) { - out.printf("\"[%s|%c]\"", interval.operand.name(), interval.operand.kind.typeChar); - } else { - if (interval.location() != null) { - out.printf("\"[%s|%c]\"", interval.location().name(), interval.location().kind.typeChar); - } - } - - Interval hint = interval.locationHint(false, allocator); - out.printf("%d %d ", interval.splitParent().operandNumber, hint != null ? hint.operandNumber : -1); - - // print ranges - Range cur = interval.first(); - while (cur != Range.EndMarker) { - out.printf("[%d, %d[", cur.from, cur.to); - cur = cur.next; - assert cur != null : "range list not closed with range sentinel"; - } - - // print use positions - int prev = 0; - UsePosList usePosList = interval.usePosList(); - for (int i = usePosList.size() - 1; i >= 0; --i) { - assert prev < usePosList.usePos(i) : "use positions not sorted"; - out.printf("%d %s ", usePosList.usePos(i), usePosList.registerPriority(i)); - prev = usePosList.usePos(i); - } - - out.printf(" \"%s\"", interval.spillState()); - out.println(); - } - - public void printMachineCode(String code, String label) { - if (code.length() == 0) { - return; - } - if (label != null) { - begin("cfg"); - out.print("name \"").print(label).println('"'); - end("cfg"); - } - begin("nmethod"); - out.print(code); - out.println(" <|@"); - end("nmethod"); - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/debug/CFGPrinterObserver.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/debug/CFGPrinterObserver.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,120 +0,0 @@ -/* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.compiler.debug; - -import java.io.*; - -import com.oracle.max.graal.compiler.*; -import com.oracle.max.graal.compiler.observer.*; -import com.sun.cri.ri.*; - -/** - * Observes compilation events and uses {@link CFGPrinter} to produce a control flow graph for the C1 Visualizer. - * - * @author Peter Hofer - */ -public class CFGPrinterObserver implements CompilationObserver { - - private GraalCompilation currentCompilation; - private CFGPrinter cfgPrinter; - private ByteArrayOutputStream buffer = null; - private final OutputStream stream; - - public CFGPrinterObserver() { - this(CFGPrinter.cfgFileStream()); - } - - public CFGPrinterObserver(OutputStream stream) { - this.stream = stream; - } - - @Override - public void compilationStarted(CompilationEvent event) { - // Supports only one compilation at the same time - assert currentCompilation == null; - - currentCompilation = event.getCompilation(); - if (buffer == null) { - buffer = new ByteArrayOutputStream(); - } - cfgPrinter = new CFGPrinter(buffer, currentCompilation.target); - cfgPrinter.printCompilation(currentCompilation.method); - } - - @Override - public void compilationEvent(CompilationEvent event) { - assert currentCompilation == event.getCompilation(); - - String label = event.getLabel(); - - if (event.getAllocator() != null && event.getIntervals() != null) { - cfgPrinter.printIntervals(event.getAllocator(), event.getIntervals(), label); - } - - boolean cfgprinted = false; - - if (event.getBlockMap() != null && event.getCodeSize() >= 0) { - cfgPrinter.printCFG(event.getMethod(), event.getBlockMap(), event.getCodeSize(), label, event.isHIRValid(), event.isLIRValid()); - cfgprinted = true; - } - - // TODO fix that when schedule is here (startBlock : Instruction->Block) - /*if (event.getStartBlock() != null) { - cfgPrinter.printCFG((BlockBegin) event.getStartBlock(), label, event.isHIRValid(), event.isLIRValid()); - cfgprinted = true; - }*/ - - if (event.getTargetMethod() != null) { - if (cfgprinted) { - // Avoid duplicate "cfg" section - label = null; - } - - RiRuntime runtime = event.getCompilation().runtime; - cfgPrinter.printMachineCode(runtime.disassemble(event.getTargetMethod()), label); - } - } - - @Override - public void compilationFinished(CompilationEvent event) { - assert currentCompilation == event.getCompilation(); - - cfgPrinter.flush(); - - if (stream != null) { - synchronized (stream) { - try { - stream.write(buffer.toByteArray()); - stream.flush(); - } catch (IOException e) { - TTY.println("WARNING: Error writing CFGPrinter output for %s: %s", event.getMethod(), e); - } - } - } - - buffer.reset(); - cfgPrinter = null; - currentCompilation = null; - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/debug/GraphvizPrinterObserver.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/debug/GraphvizPrinterObserver.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,109 +0,0 @@ -/* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.compiler.debug; - -import java.io.*; -import java.util.regex.*; - -import com.oracle.max.graal.compiler.*; -import com.oracle.max.graal.compiler.observer.*; -import com.oracle.max.graal.graph.*; -import com.oracle.max.graal.graphviz.*; -import com.oracle.max.graal.nodes.*; - -/** - * Observes compilation events and uses {@link GraphvizPrinter} to produce a control flow graph in the DOT language - * which can be visualized with Graphviz. - * - * @author Peter Hofer - */ -public class GraphvizPrinterObserver implements CompilationObserver { - - private static final Pattern INVALID_CHAR = Pattern.compile("[^A-Za-z0-9_.-]"); - - private final boolean pdf; - private int n; - - public GraphvizPrinterObserver(boolean pdf) { - this.pdf = pdf; - } - - public void compilationStarted(CompilationEvent event) { - n = 0; - } - - public void compilationFinished(CompilationEvent event) { - } - - public void compilationEvent(CompilationEvent event) { - if (event.getGraph() != null && !TTY.isSuppressed()) { - Graph graph = event.getGraph(); - - String name = event.getMethod().holder().name(); - name = name.substring(1, name.length() - 1).replace('/', '.'); - name = name + "." + event.getMethod().name(); - - String filename = name + "_" + (n++) + "_" + event.getLabel(); - filename = INVALID_CHAR.matcher(filename).replaceAll("_"); - - OutputStream out = null; - try { - if (pdf) { - ByteArrayOutputStream buffer = new ByteArrayOutputStream(); - printGraph(graph, name, buffer); - - out = new FileOutputStream(filename + ".pdf"); - GraphvizRunner.process(GraphvizRunner.DOT_LAYOUT, new ByteArrayInputStream(buffer.toByteArray()), out, "pdf"); - } else { - out = new FileOutputStream(filename + ".gv"); - - printGraph(graph, name, out); - } - } catch (IOException e) { - e.printStackTrace(); - } finally { - if (out != null) { - try { - out.close(); - } catch (IOException e) { - } - } - } - } - } - - private static void printGraph(Graph graph, String name, OutputStream buffer) { - GraphvizPrinter printer = new GraphvizPrinter(buffer); - if (GraalOptions.OmitDOTFrameStates) { - printer.addOmittedClass(FrameState.class); - } - printer.addClassColor(StartNode.class, "snow3"); - printer.addClassColor(LoopBeginNode.class, "skyblue"); - printer.addClassColor(LoopEndNode.class, "skyblue3"); - printer.addClassColor(UnwindNode.class, "red"); - printer.addClassColor(ReturnNode.class, "indianred1"); - printer.begin(name); - printer.print(graph, true); - printer.end(); - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/debug/IdealGraphPrinter.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/debug/IdealGraphPrinter.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,478 +0,0 @@ -/* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.compiler.debug; - -import java.io.*; -import java.util.AbstractMap.SimpleImmutableEntry; -import java.util.*; -import java.util.Map.Entry; - -import com.oracle.max.graal.compiler.*; -import com.oracle.max.graal.compiler.schedule.*; -import com.oracle.max.graal.compiler.util.*; -import com.oracle.max.graal.compiler.util.LoopUtil.Loop; -import com.oracle.max.graal.graph.*; -import com.oracle.max.graal.graph.collections.*; -import com.oracle.max.graal.nodes.*; -import com.oracle.max.graal.nodes.loop.*; -import com.sun.cri.bytecode.*; -import com.sun.cri.ri.*; - -/** - * Generates a representation of {@link Graph Graphs} that can be visualized and inspected with the Ideal Graph Visualizer. - */ -public class IdealGraphPrinter { - - private static class Edge { - final int from; - final int to; - final int fromIndex; - final int toIndex; - - Edge(int from, int fromIndex, int to, int toIndex) { - this.from = from; - this.fromIndex = fromIndex; - this.to = to; - this.toIndex = toIndex; - } - } - - private final HashSet> omittedClasses = new HashSet>(); - private final PrintStream stream; - private final Set noBlockNodes = new HashSet(); - - /** - * Creates a new {@link IdealGraphPrinter} that writes to the specified output stream. - */ - public IdealGraphPrinter(OutputStream stream) { - this.stream = new PrintStream(stream); - } - - /** - * Adds a node class that is omitted in the output. - */ - public void addOmittedClass(Class clazz) { - omittedClasses.add(clazz); - } - - /** - * Flushes any buffered output. - */ - public void flush() { - stream.flush(); - } - - /** - * Starts a new graph document. - */ - public void begin() { - stream.println(""); - } - - /** - * Starts a new group of graphs with the given name, short name and method byte code index (BCI) as properties. - */ - public void beginGroup(String name, String shortName, RiMethod method, int bci) { - stream.println(""); - stream.printf("

%s

Graal

%n", escape(name)); - stream.printf(" %n", escape(name), escape(shortName), bci); - if (GraalOptions.PrintIdealGraphBytecodes) { - StringBuilder sb = new StringBuilder(40); - stream.println("\n<![CDATA["); - BytecodeStream bytecodes = new BytecodeStream(method.code()); - while (bytecodes.currentBC() != Bytecodes.END) { - sb.setLength(0); - sb.append(bytecodes.currentBCI()).append(' '); - sb.append(Bytecodes.nameOf(bytecodes.currentBC())); - for (int i = bytecodes.currentBCI() + 1; i < bytecodes.nextBCI(); ++i) { - sb.append(' ').append(bytecodes.readUByte(i)); - } - stream.println(sb.toString()); - bytecodes.next(); - } - stream.println("]]>"); - } - stream.println(""); - } - - /** - * Ends the current group. - */ - public void endGroup() { - stream.println(""); - } - - /** - * Finishes the graph document and flushes the output stream. - */ - public void end() { - stream.println(""); - flush(); - } - - public void print(Graph graph, String title, boolean shortNames) { - print(graph, title, shortNames, Collections.emptyMap()); - } - - /** - * Prints an entire {@link Graph} with the specified title, optionally using short names for nodes. - */ - public void print(Graph graph, String title, boolean shortNames, Map debugObjects) { - stream.printf(" %n", escape(title)); - noBlockNodes.clear(); - IdentifyBlocksPhase schedule = null; - if (debugObjects != null) { - for (Object obj : debugObjects.values()) { - if (obj instanceof IdentifyBlocksPhase) { - schedule = (IdentifyBlocksPhase) obj; - } - } - } - if (schedule == null) { - try { - schedule = new IdentifyBlocksPhase(true, false); - schedule.apply(graph, false, false); - } catch (Throwable t) { - // nothing to do here... - //t.printStackTrace(); - } - } - List loops = null; - try { - loops = LoopUtil.computeLoops(graph); - // loop.nodes() does some more calculations which may fail, so execute this here as well - if (loops != null) { - for (Loop loop : loops) { - loop.nodes(); - } - } - } catch (Throwable t) { - t.printStackTrace(); - loops = null; - } - - stream.println(" "); - List edges = printNodes(graph, shortNames, schedule == null ? null : schedule.getNodeToBlock(), loops, debugObjects); - stream.println(" "); - - stream.println(" "); - for (Edge edge : edges) { - printEdge(edge); - } - stream.println(" "); - - if (schedule != null) { - stream.println(" "); - for (Block block : schedule.getBlocks()) { - printBlock(graph, block, schedule.getNodeToBlock()); - } - printNoBlock(); - stream.println(" "); - } - - stream.println(" "); - flush(); - } - - private List printNodes(Graph graph, boolean shortNames, NodeMap nodeToBlock, List loops, Map debugObjects) { - ArrayList edges = new ArrayList(); - NodeBitMap loopExits = graph.createNodeBitMap(); - if (loops != null) { - for (Loop loop : loops) { - loopExits.setUnion(loop.exits()); - } - } - - Map>> colors = new HashMap>>(); - Map>> colorsToString = new HashMap>>(); - Map> bits = new HashMap>(); - if (debugObjects != null) { - for (Entry entry : debugObjects.entrySet()) { - String name = entry.getKey(); - Object obj = entry.getValue(); - if (obj instanceof NodeMap) { - Map colorNumbers = new HashMap(); - int nextColor = 0; - NodeMap map = (NodeMap) obj; - for (Entry mapEntry : map.entries()) { - Node node = mapEntry.getKey(); - Object color = mapEntry.getValue(); - Integer colorNumber = colorNumbers.get(color); - if (colorNumber == null) { - colorNumber = nextColor++; - colorNumbers.put(color, colorNumber); - } - Set> nodeColors = colors.get(node); - if (nodeColors == null) { - nodeColors = new HashSet>(); - colors.put(node, nodeColors); - } - nodeColors.add(new SimpleImmutableEntry(name + "Color", colorNumber)); - Set> nodeColorStrings = colorsToString.get(node); - if (nodeColorStrings == null) { - nodeColorStrings = new HashSet>(); - colorsToString.put(node, nodeColorStrings); - } - nodeColorStrings.add(new SimpleImmutableEntry(name, color.toString())); - } - } else if (obj instanceof NodeBitMap) { - NodeBitMap bitmap = (NodeBitMap) obj; - for (Node node : bitmap) { - Set nodeBits = bits.get(node); - if (nodeBits == null) { - nodeBits = new HashSet(); - bits.put(node, nodeBits); - } - nodeBits.add(name); - } - } - } - } - - for (Node node : graph.getNodes()) { - if (omittedClasses.contains(node.getClass())) { - continue; - } - - stream.printf(" %n", node.id()); - stream.printf("

%d

%n", node.id()); - - Map props = node.getDebugProperties(); - if (!props.containsKey("name") || props.get("name").toString().trim().length() == 0) { - String name; - if (shortNames) { - name = node.shortName(); - } else { - name = node.toString(); - } - stream.printf("

%s

%n", escape(name)); - } - stream.printf("

%s

%n", escape(node.getClass().getSimpleName())); - Block block = nodeToBlock == null ? null : nodeToBlock.get(node); - if (block != null) { - stream.printf("

%d

%n", block.blockID()); - if (!(node instanceof PhiNode || node instanceof FrameState || node instanceof LocalNode || node instanceof LoopCounterNode) && !block.getInstructions().contains(node)) { - stream.println("

true

"); - } - } else { - stream.println("

noBlock

"); - noBlockNodes.add(node); - } - if (loopExits.isMarked(node)) { - stream.println("

true

"); - } - StringBuilder sb = new StringBuilder(); - if (loops != null) { - for (Loop loop : loops) { - if (loop.nodes().isMarked(node)) { - if (sb.length() > 0) { - sb.append(", "); - } - sb.append(loop.loopBegin().id()); - } - } - } - if (sb.length() > 0) { - stream.printf("

%s

%n", sb); - } - - Set> nodeColors = colors.get(node); - if (nodeColors != null) { - for (Entry color : nodeColors) { - String name = color.getKey(); - Integer value = color.getValue(); - stream.printf("

%d

%n", name, value); - } - } - Set> nodeColorStrings = colorsToString.get(node); - if (nodeColorStrings != null) { - for (Entry color : nodeColorStrings) { - String name = color.getKey(); - String value = color.getValue(); - stream.printf("

%s

%n", name, value); - } - } - Set nodeBits = bits.get(node); - if (nodeBits != null) { - for (String bit : nodeBits) { - stream.print("

true

"); - } - } - - for (Entry entry : props.entrySet()) { - String key = entry.getKey().toString(); - String value = entry.getValue() == null ? "null" : entry.getValue().toString(); - stream.print("

"); - stream.print(escape(value)); - stream.println("

"); - } - - stream.println("
"); - - // successors - int fromIndex = 0; - for (Node successor : node.successors()) { - if (successor != Node.Null && !omittedClasses.contains(successor.getClass())) { - edges.add(new Edge(node.id(), fromIndex, successor.id(), 0)); - } - fromIndex++; - } - - // inputs - int toIndex = 1; - for (Node input : node.inputs()) { - if (input != Node.Null && !omittedClasses.contains(input.getClass())) { - edges.add(new Edge(input.id(), input.successors().explicitCount(), node.id(), toIndex)); - } - toIndex++; - } - } - - return edges; - } - - private void printEdge(Edge edge) { - stream.printf(" %n", edge.from, edge.fromIndex, edge.to, edge.toIndex); - } - - private void printBlock(Graph graph, Block block, NodeMap nodeToBlock) { - stream.printf(" %n", block.blockID()); - stream.println(" "); - for (Block sux : block.getSuccessors()) { - if (sux != null) { - stream.printf(" %n", sux.blockID()); - } - } - stream.println(" "); - stream.println(" "); - - Set nodes = new HashSet(block.getInstructions()); - - if (nodeToBlock != null) { - for (Node n : graph.getNodes()) { - Block blk = nodeToBlock.get(n); - if (blk == block) { - nodes.add(n); - } - } - } - - if (nodes.size() > 0) { - // if this is the first block: add all locals to this block - if (block.getInstructions().size() > 0 && block.getInstructions().get(0) == graph.start()) { - for (Node node : graph.getNodes()) { - if (node instanceof LocalNode) { - nodes.add(node); - } - } - } - - // add all framestates and phis to their blocks - for (Node node : block.getInstructions()) { - if (node instanceof StateSplit && ((StateSplit) node).stateAfter() != null) { - nodes.add(((StateSplit) node).stateAfter()); - } - if (node instanceof MergeNode) { - for (Node usage : node.usages()) { - if (usage instanceof PhiNode || usage instanceof LoopCounterNode) { - nodes.add(usage); - } - } - } - } - - for (Node node : nodes) { - if (!omittedClasses.contains(node.getClass())) { - stream.printf(" %n", node.id()); - } - } - } - stream.println(" "); - stream.printf(" %n", block.blockID()); - } - - private void printNoBlock() { - if (!noBlockNodes.isEmpty()) { - stream.printf(" %n"); - stream.printf(" %n"); - for (Node node : noBlockNodes) { - stream.printf(" %n", node.id()); - } - stream.printf(" %n"); - stream.printf(" %n"); - } - } - - private String escape(String s) { - StringBuilder str = null; - for (int i = 0; i < s.length(); i++) { - char c = s.charAt(i); - switch (c) { - case '&': - case '<': - case '>': - case '"': - case '\'': - if (str == null) { - str = new StringBuilder(); - str.append(s, 0, i); - } - switch(c) { - case '&': - str.append("&"); - break; - case '<': - str.append("<"); - break; - case '>': - str.append(">"); - break; - case '"': - str.append("""); - break; - case '\'': - str.append("'"); - break; - default: - assert false; - } - break; - default: - if (str != null) { - str.append(c); - } - break; - } - } - if (str == null) { - return s; - } else { - return str.toString(); - } - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/debug/IdealGraphPrinterObserver.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/debug/IdealGraphPrinterObserver.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,180 +0,0 @@ -/* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.compiler.debug; - -import java.io.*; -import java.net.*; -import java.util.regex.*; - -import com.oracle.max.graal.compiler.*; -import com.oracle.max.graal.compiler.observer.*; -import com.oracle.max.graal.graph.*; -import com.oracle.max.graal.nodes.*; -import com.sun.cri.ri.*; - -/** - * Observes compilation events and uses {@link IdealGraphPrinter} to generate a graph representation that can be - * inspected with the Ideal Graph Visualizer. - * - * @author Peter Hofer - */ -public class IdealGraphPrinterObserver implements CompilationObserver { - - private static final Pattern INVALID_CHAR = Pattern.compile("[^A-Za-z0-9_.-]"); - - private final String host; - private final int port; - - private IdealGraphPrinter printer; - private OutputStream stream; - private Socket socket; - - /** - * Creates a new {@link IdealGraphPrinterObserver} that writes output to a file named after the compiled method. - */ - public IdealGraphPrinterObserver() { - this(null, -1); - } - - /** - * Creates a new {@link IdealGraphPrinterObserver} that sends output to a remove IdealGraphVisualizer instance. - */ - public IdealGraphPrinterObserver(String host, int port) { - this.host = host; - this.port = port; - } - - @Override - public void compilationStarted(CompilationEvent event) { - assert (stream == null && printer == null); - - if ((!TTY.isSuppressed() && GraalOptions.Plot) || (GraalOptions.PlotOnError && event.isErrorEvent())) { - String name = event.getMethod().holder().name(); - name = name.substring(1, name.length() - 1).replace('/', '.'); - name = name + "." + event.getMethod().name(); - - if (host != null) { - openNetworkPrinter(name, event.getMethod()); - } else { - openFilePrinter(name, event.getMethod()); - } - } - } - - private void openFilePrinter(String name, RiMethod method) { - String filename = name + ".igv.xml"; - filename = INVALID_CHAR.matcher(filename).replaceAll("_"); - - try { - stream = new FileOutputStream(filename); - printer = new IdealGraphPrinter(stream); - if (GraalOptions.OmitDOTFrameStates) { - printer.addOmittedClass(FrameState.class); - } - printer.begin(); - printer.beginGroup(name, name, method, -1); - } catch (IOException e) { - e.printStackTrace(); - } - } - - private void openNetworkPrinter(String name, RiMethod method) { - try { - socket = new Socket(host, port); - if (socket.getInputStream().read() == 'y') { - stream = new BufferedOutputStream(socket.getOutputStream(), 0x4000); - } else { - // server currently does not accept any input - socket.close(); - socket = null; - return; - } - - printer = new IdealGraphPrinter(new BufferedOutputStream(stream)); - if (GraalOptions.OmitDOTFrameStates) { - printer.addOmittedClass(FrameState.class); - } - printer.begin(); - printer.beginGroup(name, name, method, -1); - printer.flush(); - if (socket.getInputStream().read() != 'y') { - // server declines input for this method - socket.close(); - socket = null; - stream = null; - printer = null; - } - } catch (IOException e) { - e.printStackTrace(); - - if (socket != null) { - try { - socket.close(); - } catch (IOException ioe) { - } - socket = null; - } - stream = null; - printer = null; - } - } - - @Override - public void compilationEvent(CompilationEvent event) { - boolean lazyStart = false; - if (printer == null && event.isErrorEvent()) { - this.compilationStarted(event); - lazyStart = true; - } - if (printer != null && event.getGraph() != null && event.isHIRValid()) { - Graph graph = event.getGraph(); - printer.print(graph, event.getLabel(), true, event.getDebugObjects()); - } - if (lazyStart) { - this.compilationFinished(event); - } - } - - @Override - public void compilationFinished(CompilationEvent event) { - if (printer != null) { - try { - printer.endGroup(); - printer.end(); - - if (socket != null) { - socket.close(); // also closes stream - } else { - stream.close(); - } - } catch (IOException e) { - e.printStackTrace(); - } finally { - printer = null; - stream = null; - socket = null; - } - } - } - -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/debug/InstructionPrinter.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/debug/InstructionPrinter.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,145 +0,0 @@ -/* - * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.compiler.debug; - -import static com.oracle.max.graal.compiler.debug.InstructionPrinter.InstructionLineColumn.*; - -import com.oracle.max.graal.nodes.*; -import com.oracle.max.graal.nodes.spi.*; - -/** - * A {@link ValueVisitor} for {@linkplain #printInstruction(ValueNode) printing} - * an {@link FixedWithNextNode} as an expression or statement. - * - * @author Doug Simon - */ -public class InstructionPrinter { - - - /** - * The columns printed in a tabulated instruction - * {@linkplain InstructionPrinter#printInstructionListing(ValueNode) listing}. - */ - public enum InstructionLineColumn { - /** - * The instruction's bytecode index. - */ - BCI(2, "bci"), - - /** - * The instruction's use count. - */ - USE(7, "use"), - - /** - * The instruction as a {@linkplain com.oracle.max.graal.compiler.util.Util#valueString(com.oracle.max.graal.compiler.ir.Value) value}. - */ - VALUE(12, "tid"), - - /** - * The instruction formatted as an expression or statement. - */ - INSTRUCTION(19, "instr"), - - END(60, ""); - - final int position; - final String label; - - private InstructionLineColumn(int position, String label) { - this.position = position; - this.label = label; - } - - /** - * Prints this column's label to a given stream after padding the stream with '_' characters - * until its {@linkplain LogStream#position() position} is equal to this column's position. - * @param out the print stream - */ - public void printLabel(LogStream out) { - out.fillTo(position + out.indentationLevel(), '_'); - out.print(label); - } - - /** - * Prints space characters to a given stream until its {@linkplain LogStream#position() position} - * is equal to this column's position. - * @param out the print stream - */ - public void advance(LogStream out) { - out.fillTo(position + out.indentationLevel(), ' '); - } - } - - private final LogStream out; - - public InstructionPrinter(LogStream out) { - this.out = out; - } - - public LogStream out() { - return out; - } - - /** - * Prints a header for the tabulated data printed by {@link #printInstructionListing(ValueNode)}. - */ - public void printInstructionListingHeader() { - BCI.printLabel(out); - USE.printLabel(out); - VALUE.printLabel(out); - INSTRUCTION.printLabel(out); - END.printLabel(out); - out.println(); - } - - /** - * Prints an instruction listing on one line. The instruction listing is composed of the - * columns specified by {@link InstructionLineColumn}. - * - * @param instruction the instruction to print - */ - public void printInstructionListing(ValueNode instruction) { - int indentation = out.indentationLevel(); - out.fillTo(BCI.position + indentation, ' '). - print(0). - fillTo(USE.position + indentation, ' '). - print("0"). - fillTo(VALUE.position + indentation, ' '). - print(instruction). - fillTo(INSTRUCTION.position + indentation, ' '); - printInstruction(instruction); - String flags = instruction.flagsToString(); - if (!flags.isEmpty()) { - out.print(" [flags: " + flags + "]"); - } - if (instruction instanceof StateSplit) { - out.print(" [state: " + ((StateSplit) instruction).stateAfter() + "]"); - } - out.println(); - } - - public void printInstruction(ValueNode node) { - out.print(node.toString()); - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/debug/LogStream.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/debug/LogStream.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,493 +0,0 @@ -/* - * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.compiler.debug; - -import java.io.*; -import java.util.*; - -import com.oracle.max.graal.nodes.*; - -/** - * A utility for printing compiler debug and informational output to an output stream. - * - * A {@link LogStream} instance maintains an internal buffer that is flushed to the underlying - * output stream every time one of the {@code println} methods is invoked, or a newline character - * ({@code '\n'}) is written. - * - * All of the {@code print} and {@code println} methods return the {code LogStream} instance - * on which they were invoked. This allows chaining of these calls to mitigate use of String - * concatenation by the caller. - * - * A {@code LogStream} maintains a current {@linkplain #indentationLevel() indentation} level. - * Each line of output written to this stream has {@code n} spaces prefixed to it where - * {@code n} is the value that would be returned by {@link #indentationLevel()} when the first - * character of a new line is written. - * - * A {@code LogStream} maintains a current {@linkplain #position() position} for the current - * line being written. This position can be advanced to a specified position by - * {@linkplain #fillTo(int, char) filling} this stream with a given character. - * - * @author Doug Simon - */ -public class LogStream { - - /** - * Null output stream that simply swallows any output sent to it. - */ - public static final LogStream SINK = new LogStream(); - - private LogStream() { - this.ps = null; - this.lineBuffer = null; - } - - /** - * The output stream to which this log stream writes. - */ - private final PrintStream ps; - - private final StringBuilder lineBuffer; - private int indentationLevel; - private char indentation = ' '; - private boolean indentationDisabled; - - /** - * The system dependent line separator. - */ - public static final String LINE_SEPARATOR = System.getProperty("line.separator"); - - /** - * Creates a new log stream. - * - * @param os the underlying output stream to which prints are sent - */ - public LogStream(OutputStream os) { - ps = os instanceof PrintStream ? (PrintStream) os : new PrintStream(os); - lineBuffer = new StringBuilder(100); - } - - /** - * Creates a new log stream that shares the same {@linkplain #ps output stream} as a given {@link LogStream}. - * - * @param log a LogStream whose output stream is shared with this one - */ - public LogStream(LogStream log) { - ps = log.ps; - lineBuffer = new StringBuilder(100); - } - - /** - * Prepends {@link #indentation} to the current output line until its write position is equal to the - * current {@linkplain #indentationLevel()} level. - */ - private void indent() { - if (ps != null) { - if (!indentationDisabled && indentationLevel != 0) { - while (lineBuffer.length() < indentationLevel) { - lineBuffer.append(indentation); - } - } - } - } - - private LogStream flushLine(boolean withNewline) { - if (ps != null) { - if (withNewline) { - lineBuffer.append(LINE_SEPARATOR); - } else { - assert lineBuffer.indexOf(LINE_SEPARATOR, lineBuffer.length() - LINE_SEPARATOR.length()) != -1; - } - ps.print(lineBuffer.toString()); - ps.flush(); - lineBuffer.setLength(0); - } - return this; - } - - /** - * Flushes the stream. This is done by terminating the current line if it is not at position 0 - * and then flushing the underlying output stream. - */ - public void flush() { - if (ps != null) { - if (lineBuffer.length() != 0) { - flushLine(true); - } - ps.flush(); - } - } - - /** - * Gets the current column position of this log stream. - * - * @return the current column position of this log stream - */ - public int position() { - return lineBuffer == null ? 0 : lineBuffer.length(); - - } - - /** - * Gets the current indentation level for this log stream. - * - * @return the current indentation level for this log stream. - */ - public int indentationLevel() { - return indentationLevel; - } - - /** - * Adjusts the current indentation level of this log stream. - * - * @param delta - */ - public void adjustIndentation(int delta) { - if (delta < 0) { - indentationLevel = Math.max(0, indentationLevel + delta); - } else { - indentationLevel += delta; - } - } - - /** - * Gets the current indentation character of this log stream. - */ - public char indentation() { - return indentation; - } - - public void disableIndentation() { - indentationDisabled = true; - } - - public void enableIndentation() { - indentationDisabled = false; - } - - /** - * Sets the character used for indentation. - */ - public void setIndentation(char c) { - indentation = c; - } - - /** - * Advances this stream's {@linkplain #position() position} to a given position by - * repeatedly appending a given character as necessary. - * - * @param position the position to which this stream's position will be advanced - * @param filler the character used to pad the stream - */ - public LogStream fillTo(int position, char filler) { - if (ps != null) { - indent(); - while (lineBuffer.length() < position) { - lineBuffer.append(filler); - } - } - return this; - } - - /** - * Writes a boolean value to this stream as {@code "true"} or {@code "false"}. - * - * @param b the value to be printed - * @return this {@link LogStream} instance - */ - public LogStream print(boolean b) { - if (ps != null) { - indent(); - lineBuffer.append(b); - } - return this; - } - - /** - * Writes a boolean value to this stream followed by a {@linkplain #LINE_SEPARATOR line separator}. - * - * @param b the value to be printed - * @return this {@link LogStream} instance - */ - public LogStream println(boolean b) { - if (ps != null) { - indent(); - lineBuffer.append(b); - return flushLine(true); - } - return this; - } - - /** - * Writes a character value to this stream. - * - * @param c the value to be printed - * @return this {@link LogStream} instance - */ - public LogStream print(char c) { - if (ps != null) { - indent(); - lineBuffer.append(c); - if (c == '\n') { - if (lineBuffer.indexOf(LINE_SEPARATOR, lineBuffer.length() - LINE_SEPARATOR.length()) != -1) { - flushLine(false); - } - } - } - return this; - } - - /** - * Writes a character value to this stream followed by a {@linkplain #LINE_SEPARATOR line separator}. - * - * @param c the value to be printed - * @return this {@link LogStream} instance - */ - public LogStream println(char c) { - if (ps != null) { - indent(); - lineBuffer.append(c); - flushLine(true); - } - return this; - } - - /** - * Prints an int value. - * - * @param i the value to be printed - * @return this {@link LogStream} instance - */ - public LogStream print(int i) { - if (ps != null) { - indent(); - lineBuffer.append(i); - } - return this; - } - - /** - * Writes an int value to this stream followed by a {@linkplain #LINE_SEPARATOR line separator}. - * - * @param i the value to be printed - * @return this {@link LogStream} instance - */ - public LogStream println(int i) { - if (ps != null) { - indent(); - lineBuffer.append(i); - return flushLine(true); - } - return this; - } - - /** - * Writes a float value to this stream. - * - * @param f the value to be printed - * @return this {@link LogStream} instance - */ - public LogStream print(float f) { - if (ps != null) { - indent(); - lineBuffer.append(f); - } - return this; - } - - /** - * Writes a float value to this stream followed by a {@linkplain #LINE_SEPARATOR line separator}. - * - * @param f the value to be printed - * @return this {@link LogStream} instance - */ - public LogStream println(float f) { - if (ps != null) { - indent(); - lineBuffer.append(f); - return flushLine(true); - } - return this; - } - - /** - * Writes a long value to this stream. - * - * @param l the value to be printed - * @return this {@link LogStream} instance - */ - public LogStream print(long l) { - if (ps != null) { - indent(); - lineBuffer.append(l); - } - return this; - } - - /** - * Writes a long value to this stream followed by a {@linkplain #LINE_SEPARATOR line separator}. - * - * @param l the value to be printed - * @return this {@link LogStream} instance - */ - public LogStream println(long l) { - if (ps != null) { - indent(); - lineBuffer.append(l); - return flushLine(true); - } - return this; - } - - /** - * Writes a double value to this stream. - * - * @param d the value to be printed - * @return this {@link LogStream} instance - */ - public LogStream print(double d) { - if (ps != null) { - indent(); - lineBuffer.append(d); - } - return this; - } - - /** - * Writes a double value to this stream followed by a {@linkplain #LINE_SEPARATOR line separator}. - * - * @param d the value to be printed - * @return this {@link LogStream} instance - */ - public LogStream println(double d) { - if (ps != null) { - indent(); - lineBuffer.append(d); - return flushLine(true); - } - return this; - } - - /** - * Writes a {@code String} value to this stream. This method ensures that the {@linkplain #position() position} - * of this stream is updated correctly with respect to any {@linkplain #LINE_SEPARATOR line separators} - * present in {@code s}. - * - * @param s the value to be printed - * @return this {@link LogStream} instance - */ - public LogStream print(String s) { - if (ps != null) { - if (s == null) { - indent(); - lineBuffer.append(s); - return this; - } - - int index = 0; - int next = s.indexOf(LINE_SEPARATOR, index); - while (index < s.length()) { - indent(); - if (next > index) { - lineBuffer.append(s.substring(index, next)); - flushLine(true); - index = next + LINE_SEPARATOR.length(); - next = s.indexOf(LINE_SEPARATOR, index); - } else { - lineBuffer.append(s.substring(index)); - break; - } - } - } - return this; - } - - /** - * Writes a {@code String} value to this stream followed by a {@linkplain #LINE_SEPARATOR line separator}. - * - * @param s the value to be printed - * @return this {@link LogStream} instance - */ - public LogStream println(String s) { - if (ps != null) { - print(s); - flushLine(true); - } - return this; - } - - /** - * Writes a formatted string to this stream. - * - * @param format a format string as described in {@link String#format(String, Object...)} - * @param args the arguments to be formatted - * @return this {@link LogStream} instance - */ - public LogStream printf(String format, Object... args) { - if (ps != null) { - print(String.format(Locale.ENGLISH, format, args)); - } - return this; - } - - /** - * Writes an instruction formatted as a {@linkplain com.oracle.max.graal.compiler.util.Util#valueString(com.oracle.max.graal.nodes.ValueNode) value} to this stream. - * - * @param value the instruction to print - * @return this {@code LogStream} instance - */ - public LogStream print(ValueNode value) { - if (ps != null) { - indent(); - lineBuffer.append(ValueUtil.valueString(value)); - } - return this; - } - - /** - * Writes an instruction formatted as a {@linkplain com.oracle.max.graal.compiler.util.Util#valueString(com.oracle.max.graal.nodes.ValueNode) value} to this stream - * followed by a {@linkplain #LINE_SEPARATOR line separator}. - * - * @param value the instruction to print - * @return this {@code LogStream} instance - */ - public LogStream println(ValueNode value) { - if (ps != null) { - print(value); - flushLine(true); - } - return this; - } - - /** - * Writes a {@linkplain #LINE_SEPARATOR line separator} to this stream. - * - * @return this {@code LogStream} instance - */ - public LogStream println() { - if (ps != null) { - indent(); - flushLine(true); - } - return this; - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/debug/TTY.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/debug/TTY.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,239 +0,0 @@ -/* - * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.compiler.debug; - -import java.io.*; -import java.util.regex.*; - -import com.oracle.max.graal.compiler.util.*; - - -/** - * A collection of static methods for printing debug and informational output to a global {@link LogStream}. - * The output can be (temporarily) suppressed per thread through use of a {@linkplain Filter filter}. - * - * @author Doug Simon - */ -public class TTY { - - /** - * Support for thread-local suppression of {@link TTY}. - * - * @author Doug Simon - */ - public static class Filter { - private LogStream previous; - private final Thread thread = Thread.currentThread(); - - /** - * Creates an object that will suppress {@link TTY} for the current thread if the given filter does not - * {@linkplain #matches(String, Object) match} the given object. To revert the suppression state to how it was - * before this call, the {@link #remove()} method must be called on the suppression object. - * - * @param filter the pattern for matching. If {@code null}, then the match is successful. If it starts with "~", - * then a regular expression {@linkplain Pattern#matches(String, CharSequence) match} is performed - * where the regular expression is specified by {@code filter} without the "~" prefix. Otherwise, a - * simple {@linkplain String#contains(CharSequence) substring} match is performed where {@code - * filter} is the substring used. - * @param object an object whose {@linkplain Object#toString() string} value is matched against {@code filter} - */ - public Filter(String filter, Object object) { - boolean suppressed = false; - if (filter != null) { - String input = object.toString(); - if (filter.startsWith("~")) { - suppressed = !Pattern.matches(filter.substring(1), input); - } else { - suppressed = !input.contains(filter); - } - if (suppressed) { - previous = out(); - out.set(LogStream.SINK); - } - } - } - - /** - * Reverts the suppression state of {@link TTY} to how it was before this object was constructed. - */ - public void remove() { - assert thread == Thread.currentThread(); - if (previous != null) { - out.set(previous); - } - } - } - - public static final String GRAAL_TTY_LOG_FILE_PROPERTY = "graal.tty.file"; - - private static final LogStream log; - static { - PrintStream out = System.out; - String value = System.getProperty(GRAAL_TTY_LOG_FILE_PROPERTY); - if (value != null) { - try { - out = new PrintStream(new FileOutputStream(value)); - } catch (FileNotFoundException e) { - Util.warning("Could not open log file " + value + ": " + e); - } - } - log = new LogStream(out); - } - - private static final ThreadLocal out = new ThreadLocal() { - @Override - protected LogStream initialValue() { - return log; - }; - }; - - public static boolean isSuppressed() { - return out.get() == LogStream.SINK; - } - - /** - * Gets the thread-local log stream to which the static methods of this class send their output. - * This will either be a global log stream or the global {@linkplain LogStream#SINK sink} depending - * on whether any suppression {@linkplain Filter filters} are in effect for the current thread. - */ - public static LogStream out() { - return out.get(); - } - - /** - * @see LogStream#print(String) - */ - public static void print(String s) { - out().print(s); - } - - /** - * @see LogStream#print(int) - */ - public static void print(int i) { - out().print(i); - } - - /** - * @see LogStream#print(long) - */ - public static void print(long i) { - out().print(i); - } - - /** - * @see LogStream#print(char) - */ - public static void print(char c) { - out().print(c); - } - - /** - * @see LogStream#print(boolean) - */ - public static void print(boolean b) { - out().print(b); - } - - /** - * @see LogStream#print(double) - */ - public static void print(double d) { - out().print(d); - } - - /** - * @see LogStream#print(float) - */ - public static void print(float f) { - out().print(f); - } - - /** - * @see LogStream#println(String) - */ - public static void println(String s) { - out().println(s); - } - - /** - * @see LogStream#println() - */ - public static void println() { - out().println(); - } - - /** - * @see LogStream#println(int) - */ - public static void println(int i) { - out().println(i); - } - - /** - * @see LogStream#println(long) - */ - public static void println(long l) { - out().println(l); - } - - /** - * @see LogStream#println(char) - */ - public static void println(char c) { - out().println(c); - } - - /** - * @see LogStream#println(boolean) - */ - public static void println(boolean b) { - out().println(b); - } - - /** - * @see LogStream#println(double) - */ - public static void println(double d) { - out().println(d); - } - - /** - * @see LogStream#println(float) - */ - public static void println(float f) { - out().println(f); - } - - public static void print(String format, Object... args) { - out().printf(format, args); - } - - public static void println(String format, Object... args) { - out().printf(format + "%n", args); - } - - public static void fillTo(int i) { - out().fillTo(i, ' '); - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/debug/package-info.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/debug/package-info.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,26 +0,0 @@ -/* - * Copyright (c) 2010, 2010, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -/** - * A collection of debugging aids for Graal development. - */ -package com.oracle.max.graal.compiler.debug; diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/gen/LIRGenerator.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/gen/LIRGenerator.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1929 +0,0 @@ -/* - * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.compiler.gen; - -import static com.sun.cri.bytecode.Bytecodes.*; -import static com.sun.cri.bytecode.Bytecodes.MemoryBarriers.*; -import static com.sun.cri.ci.CiCallingConvention.Type.*; -import static com.sun.cri.ci.CiValue.*; - -import java.lang.reflect.*; -import java.util.*; - -import com.oracle.max.asm.*; -import com.oracle.max.graal.compiler.*; -import com.oracle.max.graal.compiler.alloc.*; -import com.oracle.max.graal.compiler.alloc.OperandPool.VariableFlag; -import com.oracle.max.graal.compiler.debug.*; -import com.oracle.max.graal.compiler.globalstub.*; -import com.oracle.max.graal.compiler.graph.*; -import com.oracle.max.graal.compiler.lir.*; -import com.oracle.max.graal.compiler.util.*; -import com.oracle.max.graal.graph.*; -import com.oracle.max.graal.nodes.*; -import com.oracle.max.graal.nodes.DeoptimizeNode.DeoptAction; -import com.oracle.max.graal.nodes.FrameState.ValueProcedure; -import com.oracle.max.graal.nodes.PhiNode.PhiType; -import com.oracle.max.graal.nodes.calc.*; -import com.oracle.max.graal.nodes.extended.*; -import com.oracle.max.graal.nodes.java.*; -import com.oracle.max.graal.nodes.spi.*; -import com.sun.cri.bytecode.*; -import com.sun.cri.bytecode.Bytecodes.MemoryBarriers; -import com.sun.cri.ci.*; -import com.sun.cri.ri.*; -import com.sun.cri.ri.RiType.Representation; -import com.sun.cri.xir.CiXirAssembler.XirConstant; -import com.sun.cri.xir.CiXirAssembler.XirInstruction; -import com.sun.cri.xir.CiXirAssembler.XirOperand; -import com.sun.cri.xir.CiXirAssembler.XirParameter; -import com.sun.cri.xir.CiXirAssembler.XirRegister; -import com.sun.cri.xir.CiXirAssembler.XirTemp; -import com.sun.cri.xir.*; - -/** - * This class traverses the HIR instructions and generates LIR instructions from them. - */ -public abstract class LIRGenerator extends LIRGeneratorTool { - - /** - * Helper class for inserting memory barriers as necessary to implement the Java Memory Model - * with respect to volatile field accesses. - * - * @see MemoryBarriers - */ - class VolatileMemoryAccess { - /** - * Inserts any necessary memory barriers before a volatile write as required by the JMM. - */ - void preVolatileWrite() { - int barriers = compilation.target.arch.requiredBarriers(JMM_PRE_VOLATILE_WRITE); - if (compilation.target.isMP && barriers != 0) { - lir.membar(barriers); - } - } - - /** - * Inserts any necessary memory barriers after a volatile write as required by the JMM. - */ - void postVolatileWrite() { - int barriers = compilation.target.arch.requiredBarriers(JMM_POST_VOLATILE_WRITE); - if (compilation.target.isMP && barriers != 0) { - lir.membar(barriers); - } - } - - /** - * Inserts any necessary memory barriers before a volatile read as required by the JMM. - */ - void preVolatileRead() { - int barriers = compilation.target.arch.requiredBarriers(JMM_PRE_VOLATILE_READ); - if (compilation.target.isMP && barriers != 0) { - lir.membar(barriers); - } - } - - /** - * Inserts any necessary memory barriers after a volatile read as required by the JMM. - */ - void postVolatileRead() { - // Ensure field's data is loaded before any subsequent loads or stores. - int barriers = compilation.target.arch.requiredBarriers(LOAD_LOAD | LOAD_STORE); - if (compilation.target.isMP && barriers != 0) { - lir.membar(barriers); - } - } - } - - /** - * Forces the result of a given instruction to be available in a given register, - * inserting move instructions if necessary. - * - * @param instruction an instruction that produces a {@linkplain ValueNode#operand() result} - * @param register the {@linkplain CiRegister} in which the result of {@code instruction} must be available - * @return {@code register} as an operand - */ - protected CiValue force(ValueNode instruction, CiRegister register) { - return force(instruction, register.asValue(instruction.kind)); - } - - /** - * Forces the result of a given instruction to be available in a given operand, - * inserting move instructions if necessary. - * - * @param instruction an instruction that produces a {@linkplain ValueNode#operand() result} - * @param operand the operand in which the result of {@code instruction} must be available - * @return {@code operand} - */ - protected CiValue force(ValueNode instruction, CiValue operand) { - CiValue result = makeOperand(instruction); - if (result != operand) { - assert result.kind != CiKind.Illegal; - if (!compilation.archKindsEqual(result.kind, operand.kind)) { - // moves between different types need an intervening spill slot - CiValue tmp = forceToSpill(result, operand.kind, false); - lir.move(tmp, operand); - } else { - lir.move(result, operand); - } - } - return operand; - } - - @Override - public CiValue load(ValueNode val) { - CiValue result = makeOperand(val); - if (!result.isVariableOrRegister()) { - CiVariable operand = newVariable(val.kind); - lir.move(result, operand); - return operand; - } - return result; - } - - // the range of values in a lookupswitch or tableswitch statement - private static final class SwitchRange { - final int lowKey; - int highKey; - final LIRBlock sux; - - SwitchRange(int lowKey, LIRBlock sux) { - this.lowKey = lowKey; - this.highKey = lowKey; - this.sux = sux; - } - } - - protected final GraalCompilation compilation; - protected final IR ir; - protected final XirSupport xirSupport; - protected final RiXirGenerator xir; - protected final boolean isTwoOperand; - - private LIRBlock currentBlock; - - public final OperandPool operands; - - private ValueNode currentInstruction; - private ValueNode lastInstructionPrinted; // Debugging only - - private List constants; - private List variablesForConstants; - protected LIRList lir; - final VolatileMemoryAccess vma; - private ArrayList deoptimizationStubs; - private FrameState lastState; - - public LIRGenerator(GraalCompilation compilation) { - this.compilation = compilation; - this.ir = compilation.hir(); - this.xir = compilation.compiler.xir; - this.xirSupport = new XirSupport(); - this.isTwoOperand = compilation.target.arch.twoOperandMode(); - this.vma = new VolatileMemoryAccess(); - - constants = new ArrayList(); - variablesForConstants = new ArrayList(); - - this.operands = new OperandPool(compilation.target); - } - - @Override - public CiTarget target() { - return compilation.target; - } - - public LIRList lir() { - return lir; - } - - public ArrayList deoptimizationStubs() { - return deoptimizationStubs; - } - - private void addDeoptimizationStub(DeoptimizationStub stub) { - if (deoptimizationStubs == null) { - deoptimizationStubs = new ArrayList(); - } - deoptimizationStubs.add(stub); - } - - public static class DeoptimizationStub { - public final Label label = new Label(); - public final LIRDebugInfo info; - public final DeoptAction action; - - public DeoptimizationStub(DeoptAction action, FrameState state) { - this.action = action; - info = new LIRDebugInfo(state); - } - } - - public void doBlock(LIRBlock block) { - blockDoProlog(block); - this.currentBlock = block; - - if (GraalOptions.TraceLIRGeneratorLevel >= 1) { - TTY.println("BEGIN Generating LIR for block B" + block.blockID()); - } - - if (block == ir.startBlock) { - XirSnippet prologue = xir.genPrologue(null, compilation.method); - if (prologue != null) { - emitXir(prologue, null, null, null, false); - } - FrameState fs = setOperandsForLocals(); - if (GraalOptions.TraceLIRGeneratorLevel >= 2) { - TTY.println("STATE CHANGE (setOperandsForLocals)"); - if (GraalOptions.TraceLIRGeneratorLevel >= 3) { - TTY.println(fs.toString()); - } - } - lastState = fs; - } else if (block.blockPredecessors().size() > 0) { - FrameState fs = null; - for (LIRBlock pred : block.blockPredecessors()) { - if (fs == null) { - fs = pred.lastState(); - } else if (fs != pred.lastState()) { - fs = null; - break; - } - } - if (GraalOptions.TraceLIRGeneratorLevel >= 2) { - if (fs == null) { - TTY.println("STATE RESET"); - } else { - TTY.println("STATE CHANGE (singlePred)"); - if (GraalOptions.TraceLIRGeneratorLevel >= 3) { - TTY.println(fs.toString()); - } - } - } - lastState = fs; - } - - for (Node instr : block.getInstructions()) { - if (GraalOptions.TraceLIRGeneratorLevel >= 3) { - TTY.println("LIRGen for " + instr); - } - FrameState stateAfter = null; - if (instr instanceof StateSplit) { - stateAfter = ((StateSplit) instr).stateAfter(); - } - if (instr != instr.graph().start()) { - walkState(instr, stateAfter); - doRoot((ValueNode) instr); - } - if (stateAfter != null) { - lastState = stateAfter; - if (GraalOptions.TraceLIRGeneratorLevel >= 2) { - TTY.println("STATE CHANGE"); - if (GraalOptions.TraceLIRGeneratorLevel >= 3) { - TTY.println(stateAfter.toString()); - } - } - } - } - if (block.blockSuccessors().size() >= 1 && !block.endsWithJump()) { - NodeSuccessorsIterable successors = block.lastInstruction().successors(); - assert successors.explicitCount() >= 1 : "should have at least one successor : " + block.lastInstruction(); - block.lir().jump(getLIRBlock((FixedNode) successors.first())); - } - - if (GraalOptions.TraceLIRGeneratorLevel >= 1) { - TTY.println("END Generating LIR for block B" + block.blockID()); - } - - block.setLastState(lastState); - this.currentBlock = null; - blockDoEpilog(); - } - - @Override - public void visitMerge(MergeNode x) { - if (x.next() instanceof LoopBeginNode) { - moveToPhi((LoopBeginNode) x.next(), x); - } - } - - @Override - public void visitArrayLength(ArrayLengthNode x) { - emitArrayLength(x); - } - - public CiValue emitArrayLength(ArrayLengthNode x) { - XirArgument array = toXirArgument(x.array()); - XirSnippet snippet = xir.genArrayLength(site(x), array); - emitXir(snippet, x, stateFor(x), null, true); - return x.operand(); - } - - private FrameState setOperandsForLocals() { - CiCallingConvention args = compilation.frameMap().incomingArguments(); - int bci = 0; - if (Modifier.isSynchronized(compilation.method.accessFlags())) { - bci = FixedWithNextNode.SYNCHRONIZATION_ENTRY_BCI; - } - - boolean withReceiver = !Modifier.isStatic(compilation.method.accessFlags()); - CiKind[] arguments = Util.signatureToKinds(compilation.method.signature(), withReceiver ? CiKind.Object : null); - int[] argumentSlots = new int[arguments.length]; - int slot = 0; - for (int arg = 0; arg < arguments.length; arg++) { - argumentSlots[arg] = slot; - slot += arguments[arg].sizeInSlots(); - } - - FrameState fs = new FrameState(compilation.method, bci, compilation.method.maxLocals(), 0, 0, false, compilation.graph); - for (Node node : compilation.graph.start().usages()) { - if (node instanceof LocalNode) { - LocalNode local = (LocalNode) node; - int i = local.index(); - fs.storeLocal(argumentSlots[i], local); - - CiValue src = args.locations[i]; - assert src.isLegal() : "check"; - - CiVariable dest = newVariable(src.kind.stackKind()); - lir.move(src, dest, src.kind); - - assert src.kind.stackKind() == local.kind.stackKind() : "local type check failed"; - setResult(local, dest); - } - } - assert checkOperands(fs); - return fs; - } - - private boolean checkOperands(FrameState fs) { - boolean withReceiver = !Modifier.isStatic(compilation.method.accessFlags()); - CiKind[] arguments = Util.signatureToKinds(compilation.method.signature(), withReceiver ? CiKind.Object : null); - int slot = 0; - for (CiKind kind : arguments) { - assert fs.localAt(slot) != null : "slot: " + slot; - slot += kind.sizeInSlots(); - } - return true; - } - - @Override - public void visitCheckCast(CheckCastNode x) { - XirArgument obj = toXirArgument(x.object()); - XirSnippet snippet = xir.genCheckCast(site(x), obj, toXirArgument(x.targetClassInstruction()), x.targetClass()); - emitXir(snippet, x, stateFor(x), null, true); - } - - @Override - public void visitMonitorEnter(MonitorEnterNode x) { - XirArgument obj = toXirArgument(x.object()); - XirArgument lockAddress = toXirArgument(x.lockAddress()); - XirSnippet snippet = xir.genMonitorEnter(site(x), obj, lockAddress); - emitXir(snippet, x, stateFor(x), stateFor(x, x.stateAfter()), null, true, null); - } - - @Override - public void visitMonitorExit(MonitorExitNode x) { - XirArgument obj = toXirArgument(x.object()); - XirArgument lockAddress = toXirArgument(x.lockAddress()); - XirSnippet snippet = xir.genMonitorExit(site(x), obj, lockAddress); - emitXir(snippet, x, stateFor(x), null, true); - } - - @Override - public void visitStoreIndexed(StoreIndexedNode x) { - XirArgument array = toXirArgument(x.array()); - XirArgument length = x.length() == null ? null : toXirArgument(x.length()); - XirArgument index = toXirArgument(x.index()); - XirArgument value = toXirArgument(x.value()); - XirSnippet snippet = xir.genArrayStore(site(x), array, index, length, value, x.elementKind(), null); - emitXir(snippet, x, stateFor(x), null, true); - } - - @Override - public void visitNewInstance(NewInstanceNode x) { - XirSnippet snippet = xir.genNewInstance(site(x), x.instanceClass()); - emitXir(snippet, x, stateFor(x), null, true); - } - - @Override - public void visitNewTypeArray(NewTypeArrayNode x) { - XirArgument length = toXirArgument(x.length()); - XirSnippet snippet = xir.genNewArray(site(x), length, x.elementKind(), null, null); - emitXir(snippet, x, stateFor(x), null, true); - } - - @Override - public void visitNewObjectArray(NewObjectArrayNode x) { - XirArgument length = toXirArgument(x.length()); - XirSnippet snippet = xir.genNewArray(site(x), length, CiKind.Object, x.elementType(), x.exactType()); - emitXir(snippet, x, stateFor(x), null, true); - } - - @Override - public void visitNewMultiArray(NewMultiArrayNode x) { - XirArgument[] dims = new XirArgument[x.dimensionCount()]; - - for (int i = 0; i < dims.length; i++) { - dims[i] = toXirArgument(x.dimension(i)); - } - - XirSnippet snippet = xir.genNewMultiArray(site(x), dims, x.elementType); - emitXir(snippet, x, stateFor(x), null, true); - } - - - @Override - public void visitGuardNode(GuardNode x) { - emitGuardComp(x.node()); - } - - - @Override - public void visitConstant(ConstantNode x) { - if (!canInlineAsConstant(x)) { - CiValue res = x.operand(); - if (!(res.isLegal())) { - res = x.asConstant(); - } - if (res.isConstant()) { - CiVariable reg = createResultVariable(x); - lir.move(res, reg); - } else { - setResult(x, (CiVariable) res); - } - } - } - - @Override - public void visitExceptionObject(ExceptionObjectNode x) { - XirSnippet snippet = xir.genExceptionObject(site(x)); - emitXir(snippet, x, null, null, true); -// lastState = lastState.duplicateWithException(lastState.bci, x); -// if (GraalOptions.TraceLIRGeneratorLevel >= 2) { -// TTY.println("STATE CHANGE (visitExceptionObject)"); -// if (GraalOptions.TraceLIRGeneratorLevel >= 3) { -// TTY.println(lastState.toString()); -// } -// } - } - - @Override - public void visitAnchor(AnchorNode x) { - setNoResult(x); - } - - @Override - public void visitIf(IfNode x) { - assert x.defaultSuccessor() == x.falseSuccessor() : "wrong destination"; - emitBooleanBranch(x.compare(), getLIRBlock(x.trueSuccessor()), getLIRBlock(x.falseSuccessor()), null); - } - - public void emitBranch(BooleanNode n, Condition cond, LIRBlock trueSuccessor, LIRBlock falseSucc) { - if (n instanceof CompareNode) { - CompareNode compare = (CompareNode) n; - if (compare.x().kind.isFloat() || compare.x().kind.isDouble()) { - LIRBlock unorderedSuccBlock = falseSucc; - if (compare.unorderedIsTrue()) { - unorderedSuccBlock = trueSuccessor; - } - lir.branch(cond, trueSuccessor, unorderedSuccBlock); - return; - } - } - lir.branch(cond, trueSuccessor); - } - - public void emitBooleanBranch(BooleanNode node, LIRBlock trueSuccessor, LIRBlock falseSuccessor, LIRDebugInfo info) { - if (node instanceof NegateBooleanNode) { - emitBooleanBranch(((NegateBooleanNode) node).value(), falseSuccessor, trueSuccessor, info); - } else if (node instanceof IsNonNullNode) { - emitIsNonNullBranch((IsNonNullNode) node, trueSuccessor, falseSuccessor); - } else if (node instanceof CompareNode) { - emitCompare((CompareNode) node, trueSuccessor, falseSuccessor); - } else if (node instanceof InstanceOfNode) { - emitInstanceOf((TypeCheckNode) node, trueSuccessor, falseSuccessor, info); - } else if (node instanceof ConstantNode) { - emitConstantBranch(((ConstantNode) node).asConstant().asBoolean(), trueSuccessor, falseSuccessor, info); - } else { - throw Util.unimplemented(node.toString()); - } - } - - private void emitIsNonNullBranch(IsNonNullNode node, LIRBlock trueSuccessor, LIRBlock falseSuccessor) { - Condition cond = Condition.NE; - if (trueSuccessor == null) { - cond = cond.negate(); - trueSuccessor = falseSuccessor; - falseSuccessor = null; - } - - LIRItem xitem = new LIRItem(node.object(), this); - xitem.loadItem(); - - lir.cmp(cond, xitem.result(), CiConstant.NULL_OBJECT); - lir.branch(cond, trueSuccessor); - - if (falseSuccessor != null) { - lir.jump(falseSuccessor); - } - } - - private void emitInstanceOf(TypeCheckNode x, LIRBlock trueSuccessor, LIRBlock falseSuccessor, LIRDebugInfo info) { - XirArgument obj = toXirArgument(x.object()); - XirSnippet snippet = xir.genInstanceOf(site(x), obj, toXirArgument(x.targetClassInstruction()), x.targetClass()); - emitXir(snippet, x, info, null, false); - LIRXirInstruction instr = (LIRXirInstruction) lir.instructionsList().get(lir.instructionsList().size() - 1); - instr.setTrueSuccessor(trueSuccessor); - instr.setFalseSuccessor(falseSuccessor); - } - - public void emitMaterializeInstanceOf(MaterializeNode materialize, ValueNode resultValue, LIRDebugInfo info) { - TypeCheckNode x = (TypeCheckNode) materialize.condition(); - XirArgument obj = toXirArgument(x.object()); - XirSnippet snippet = xir.genMaterializeInstanceOf(site(x), obj, toXirArgument(x.targetClassInstruction()), x.targetClass()); - emitXir(snippet, resultValue, info, null, true); - } - - - public void emitConstantBranch(boolean value, LIRBlock trueSuccessorBlock, LIRBlock falseSuccessorBlock, LIRDebugInfo info) { - if (value) { - emitConstantBranch(trueSuccessorBlock, info); - } else { - emitConstantBranch(falseSuccessorBlock, info); - } - } - - private void emitConstantBranch(LIRBlock block, LIRDebugInfo info) { - if (block != null) { - lir.jump(block); - } - } - - public void emitCompare(CompareNode compare, LIRBlock trueSuccessorBlock, LIRBlock falseSuccessorBlock) { - CiKind kind = compare.x().kind; - - Condition cond = compare.condition(); - boolean unorderedIsTrue = compare.unorderedIsTrue(); - - if (trueSuccessorBlock == null) { - cond = cond.negate(); - unorderedIsTrue = !unorderedIsTrue; - trueSuccessorBlock = falseSuccessorBlock; - falseSuccessorBlock = null; - } - - LIRItem xitem = new LIRItem(compare.x(), this); - LIRItem yitem = new LIRItem(compare.y(), this); - LIRItem xin = xitem; - LIRItem yin = yitem; - - if (kind.isFloat() || kind.isDouble()) { - cond = floatingPointCondition(cond); - } - - xin.loadItem(); - - CiValue left = xin.result(); - CiValue right = yin.result(); - lir.cmp(cond, left, right); - - if (compare.x().kind.isFloat() || compare.x().kind.isDouble()) { - LIRBlock unorderedSuccBlock = falseSuccessorBlock; - if (unorderedIsTrue) { - unorderedSuccBlock = trueSuccessorBlock; - } - lir.branch(cond, trueSuccessorBlock, unorderedSuccBlock); - } else { - lir.branch(cond, trueSuccessorBlock); - } - - if (falseSuccessorBlock != null) { - lir.jump(falseSuccessorBlock); - } - } - - protected FrameState stateBeforeInvokeReturn(InvokeNode invoke) { - return invoke.stateAfter().duplicateModified(invoke.bci, invoke.stateAfter().rethrowException(), invoke.kind); - } - - protected FrameState stateBeforeInvokeWithArguments(InvokeNode invoke) { - return invoke.stateAfter().duplicateModified(invoke.bci, invoke.stateAfter().rethrowException(), invoke.kind, invoke.arguments().toArray(new ValueNode[0])); - } - - @Override - public void visitInvoke(InvokeNode x) { - RiMethod target = x.target(); - LIRDebugInfo info = stateFor(x, stateBeforeInvokeWithArguments(x)); - LIRDebugInfo info2 = stateFor(x, stateBeforeInvokeReturn(x)); - if (x.exceptionEdge() != null) { - info2.setExceptionEdge(getLIRBlock(x.exceptionEdge())); - } - - XirSnippet snippet = null; - - int opcode = x.opcode(); - XirArgument receiver; - switch (opcode) { - case INVOKESTATIC: - snippet = xir.genInvokeStatic(site(x), target); - break; - case INVOKESPECIAL: - receiver = toXirArgument(x.receiver()); - snippet = xir.genInvokeSpecial(site(x), receiver, target); - break; - case INVOKEVIRTUAL: - receiver = toXirArgument(x.receiver()); - snippet = xir.genInvokeVirtual(site(x), receiver, target); - break; - case INVOKEINTERFACE: - receiver = toXirArgument(x.receiver()); - snippet = xir.genInvokeInterface(site(x), receiver, target); - break; - } - - CiValue destinationAddress = null; - // emitting the template earlier can ease pressure on register allocation, but the argument loading can destroy an - // implicit calling convention between the XirSnippet and the call. - if (!GraalOptions.InvokeSnippetAfterArguments) { - destinationAddress = emitXir(snippet, x, info.copy(), x.target(), false); - } - - CiValue resultOperand = resultOperandFor(x.kind); - CiCallingConvention cc = compilation.frameMap().getCallingConvention(getSignature(x), JavaCall); - List pointerSlots = new ArrayList(2); - List argList = visitInvokeArguments(cc, x, pointerSlots); - - if (GraalOptions.InvokeSnippetAfterArguments) { - destinationAddress = emitXir(snippet, x, info.copy(), null, x.target(), false, pointerSlots); - } - - // emit direct or indirect call to the destination address - if (destinationAddress instanceof CiConstant) { - // Direct call - assert ((CiConstant) destinationAddress).isDefaultValue() : "destination address should be zero"; - lir.callDirect(target, resultOperand, argList, info2, snippet.marks, pointerSlots); - } else { - // Indirect call - argList.add(destinationAddress); - lir.callIndirect(target, resultOperand, argList, info2, snippet.marks, pointerSlots); - } - - if (resultOperand.isLegal()) { - CiValue result = createResultVariable(x); - lir.move(resultOperand, result); - } - } - - private CiKind[] getSignature(InvokeNode x) { - CiKind receiver = x.isStatic() ? null : x.target.holder().kind(); - return Util.signatureToKinds(x.target.signature(), receiver); - } - - @Override - public void visitMonitorAddress(MonitorAddressNode x) { - CiValue result = createResultVariable(x); - lir.monitorAddress(x.monitorIndex(), result); - } - - /** - * For note on volatile fields, see {@link #visitStoreField(StoreField)}. - */ - @Override - public void visitLoadField(LoadFieldNode x) { - RiField field = x.field(); - LIRDebugInfo info = stateFor(x); - XirArgument receiver = toXirArgument(x.object()); - XirSnippet snippet = x.isStatic() ? xir.genGetStatic(site(x), receiver, field) : xir.genGetField(site(x), receiver, field); - emitXir(snippet, x, info, null, true); - - if (x.isVolatile()) { - vma.postVolatileRead(); - } - } - - @Override - public void visitLoadIndexed(LoadIndexedNode x) { - XirArgument array = toXirArgument(x.array()); - XirArgument index = toXirArgument(x.index()); - XirArgument length = toXirArgument(x.length()); - XirSnippet snippet = xir.genArrayLoad(site(x), array, index, length, x.elementKind(), null); - emitXir(snippet, x, stateFor(x), null, true); - } - - protected GlobalStub stubFor(CiRuntimeCall runtimeCall) { - GlobalStub stub = compilation.compiler.lookupGlobalStub(runtimeCall); - compilation.frameMap().usesGlobalStub(stub); - return stub; - } - - protected GlobalStub stubFor(GlobalStub.Id globalStub) { - GlobalStub stub = compilation.compiler.lookupGlobalStub(globalStub); - compilation.frameMap().usesGlobalStub(stub); - return stub; - } - - protected GlobalStub stubFor(XirTemplate template) { - GlobalStub stub = compilation.compiler.lookupGlobalStub(template); - compilation.frameMap().usesGlobalStub(stub); - return stub; - } - - @Override - public void visitLocal(LocalNode x) { - if (x.operand().isIllegal()) { - createResultVariable(x); - } - } - - @Override - public void visitLookupSwitch(LookupSwitchNode x) { - CiValue tag = load(x.value()); - setNoResult(x); - - if (x.numberOfCases() == 0 || x.numberOfCases() < GraalOptions.SequentialSwitchLimit) { - int len = x.numberOfCases(); - for (int i = 0; i < len; i++) { - lir.cmp(Condition.EQ, tag, x.keyAt(i)); - lir.branch(Condition.EQ, getLIRBlock(x.blockSuccessor(i))); - } - lir.jump(getLIRBlock(x.defaultSuccessor())); - } else { - visitSwitchRanges(createLookupRanges(x), tag, getLIRBlock(x.defaultSuccessor())); - } - } - - protected LIRBlock getLIRBlock(FixedNode b) { - if (b == null) { - return null; - } - LIRBlock result = ir.valueToBlock.get(b); - if (result == null) { - TTY.println("instruction without lir block: " + b); - } - return result; - } - - @Override - public void visitFixedGuard(FixedGuardNode fixedGuard) { - for (Node n : fixedGuard.inputs()) { - if (n != null) { - emitGuardComp((BooleanNode) n); - } - } - } - - public void emitGuardComp(BooleanNode comp) { - if (comp instanceof IsNonNullNode) { - IsNonNullNode x = (IsNonNullNode) comp; - CiValue value = load(x.object()); - LIRDebugInfo info = stateFor(x); - lir.nullCheck(value, info); - } else if (comp instanceof IsTypeNode) { - IsTypeNode x = (IsTypeNode) comp; - load(x.object()); - LIRDebugInfo info = stateFor(x); - XirArgument clazz = toXirArgument(x.type().getEncoding(Representation.ObjectHub)); - XirSnippet typeCheck = xir.genTypeCheck(site(x), toXirArgument(x.object()), clazz, x.type()); - emitXir(typeCheck, x, info, compilation.method, false); - } else { - if (comp instanceof ConstantNode && comp.asConstant().asBoolean()) { - // Nothing to emit. - } else { - DeoptimizationStub stub = createDeoptStub(); - emitBooleanBranch(comp, null, new LIRBlock(stub.label, stub.info), stub.info); - } - } - } - - private DeoptimizationStub createDeoptStub() { - if (deoptimizationStubs == null) { - deoptimizationStubs = new ArrayList(); - } - - FrameState state = lastState; - assert state != null : "deoptimize instruction always needs a state"; - DeoptimizationStub stub = new DeoptimizationStub(DeoptAction.InvalidateReprofile, state); - deoptimizationStubs.add(stub); - return stub; - } - - @Override - public void deoptimizeOn(Condition cond) { - DeoptimizationStub stub = createDeoptStub(); - lir.branch(cond, stub.label, stub.info); - } - - - @Override - public void visitPhi(PhiNode i) { - Util.shouldNotReachHere(); - } - - @Override - public void visitReturn(ReturnNode x) { - if (x.kind.isVoid()) { - XirSnippet epilogue = xir.genEpilogue(site(x), compilation.method); - if (epilogue != null) { - emitXir(epilogue, x, null, compilation.method, false); - lir.returnOp(IllegalValue); - } - } else { - CiValue operand = resultOperandFor(x.kind); - CiValue result = force(x.result(), operand); - XirSnippet epilogue = xir.genEpilogue(site(x), compilation.method); - if (epilogue != null) { - emitXir(epilogue, x, null, compilation.method, false); - lir.returnOp(result); - } - } - setNoResult(x); - } - - protected XirArgument toXirArgument(CiValue v) { - if (v == null) { - return null; - } - - return XirArgument.forInternalObject(v); - } - - protected XirArgument toXirArgument(ValueNode i) { - if (i == null) { - return null; - } - - return XirArgument.forInternalObject(new LIRItem(i, this)); - } - - private CiValue allocateOperand(XirSnippet snippet, XirOperand op) { - if (op instanceof XirParameter) { - XirParameter param = (XirParameter) op; - return allocateOperand(snippet.arguments[param.parameterIndex], op, param.canBeConstant); - } else if (op instanceof XirRegister) { - XirRegister reg = (XirRegister) op; - return reg.register; - } else if (op instanceof XirTemp) { - return newVariable(op.kind); - } else { - Util.shouldNotReachHere(); - return null; - } - } - - private CiValue allocateOperand(XirArgument arg, XirOperand var, boolean canBeConstant) { - if (arg.constant != null) { - return arg.constant; - } else { - assert arg.object != null; - if (arg.object instanceof CiValue) { - return (CiValue) arg.object; - } - assert arg.object instanceof LIRItem; - LIRItem item = (LIRItem) arg.object; - if (canBeConstant) { - return item.instruction.operand(); - } else { - CiKind kind = var.kind; - if (kind == CiKind.Byte || kind == CiKind.Boolean) { - item.loadByteItem(); - } else { - item.loadItem(); - } - return item.result(); - } - } - } - - protected CiValue emitXir(XirSnippet snippet, ValueNode x, LIRDebugInfo info, RiMethod method, boolean setInstructionResult) { - return emitXir(snippet, x, info, null, method, setInstructionResult, null); - } - - protected CiValue emitXir(XirSnippet snippet, ValueNode instruction, LIRDebugInfo info, LIRDebugInfo infoAfter, RiMethod method, boolean setInstructionResult, List pointerSlots) { - if (GraalOptions.PrintXirTemplates) { - TTY.println("Emit XIR template " + snippet.template.name); - } - - final CiValue[] operands = new CiValue[snippet.template.variableCount]; - - compilation.frameMap().reserveOutgoing(snippet.template.outgoingStackSize); - - XirOperand resultOperand = snippet.template.resultOperand; - - if (snippet.template.allocateResultOperand) { - CiValue outputOperand = IllegalValue; - // This snippet has a result that must be separately allocated - // Otherwise it is assumed that the result is part of the inputs - if (resultOperand.kind != CiKind.Void && resultOperand.kind != CiKind.Illegal) { - if (setInstructionResult) { - outputOperand = newVariable(instruction.kind); - } else { - outputOperand = newVariable(resultOperand.kind); - } - assert operands[resultOperand.index] == null; - } - operands[resultOperand.index] = outputOperand; - if (GraalOptions.PrintXirTemplates) { - TTY.println("Output operand: " + outputOperand); - } - } - - for (XirTemp t : snippet.template.temps) { - if (t instanceof XirRegister) { - XirRegister reg = (XirRegister) t; - if (!t.reserve) { - operands[t.index] = reg.register; - } - } - } - - for (XirTemplate calleeTemplate : snippet.template.calleeTemplates) { - // TODO Save these for use in X86LIRAssembler - stubFor(calleeTemplate); - } - - for (XirConstant c : snippet.template.constants) { - assert operands[c.index] == null; - operands[c.index] = c.value; - } - - XirOperand[] inputOperands = snippet.template.inputOperands; - XirOperand[] inputTempOperands = snippet.template.inputTempOperands; - XirOperand[] tempOperands = snippet.template.tempOperands; - - CiValue[] operandArray = new CiValue[inputOperands.length + inputTempOperands.length + tempOperands.length]; - int[] operandIndicesArray = new int[inputOperands.length + inputTempOperands.length + tempOperands.length]; - for (int i = 0; i < inputOperands.length; i++) { - XirOperand x = inputOperands[i]; - CiValue op = allocateOperand(snippet, x); - operands[x.index] = op; - operandArray[i] = op; - operandIndicesArray[i] = x.index; - if (GraalOptions.PrintXirTemplates) { - TTY.println("Input operand: " + x); - } - } - - for (int i = 0; i < inputTempOperands.length; i++) { - XirOperand x = inputTempOperands[i]; - CiValue op = allocateOperand(snippet, x); - CiValue newOp = newVariable(op.kind); - lir.move(op, newOp); - operands[x.index] = newOp; - operandArray[i + inputOperands.length] = newOp; - operandIndicesArray[i + inputOperands.length] = x.index; - if (GraalOptions.PrintXirTemplates) { - TTY.println("InputTemp operand: " + x); - } - } - - for (int i = 0; i < tempOperands.length; i++) { - XirOperand x = tempOperands[i]; - CiValue op = allocateOperand(snippet, x); - operands[x.index] = op; - operandArray[i + inputOperands.length + inputTempOperands.length] = op; - operandIndicesArray[i + inputOperands.length + inputTempOperands.length] = x.index; - if (GraalOptions.PrintXirTemplates) { - TTY.println("Temp operand: " + x); - } - } - - for (CiValue operand : operands) { - assert operand != null; - } - - CiValue allocatedResultOperand = operands[resultOperand.index]; - if (!allocatedResultOperand.isVariableOrRegister()) { - allocatedResultOperand = IllegalValue; - } - - if (setInstructionResult && allocatedResultOperand.isLegal()) { - if (instruction.operand().isIllegal()) { - setResult(instruction, (CiVariable) allocatedResultOperand); - } else { - assert instruction.operand() == allocatedResultOperand; - } - } - - - XirInstruction[] slowPath = snippet.template.slowPath; - if (!operands[resultOperand.index].isConstant() || snippet.template.fastPath.length != 0 || (slowPath != null && slowPath.length > 0)) { - // XIR instruction is only needed when the operand is not a constant! - lir.xir(snippet, operands, allocatedResultOperand, inputTempOperands.length, tempOperands.length, - operandArray, operandIndicesArray, - (operands[resultOperand.index] == IllegalValue) ? -1 : resultOperand.index, - info, infoAfter, method, pointerSlots); - } - - return operands[resultOperand.index]; - } - - @Override - public void visitStoreField(StoreFieldNode x) { - RiField field = x.field(); - LIRDebugInfo info = stateFor(x); - - if (x.isVolatile()) { - vma.preVolatileWrite(); - } - - XirArgument receiver = toXirArgument(x.object()); - XirArgument value = toXirArgument(x.value()); - XirSnippet snippet = x.isStatic() ? xir.genPutStatic(site(x), receiver, field, value) : xir.genPutField(site(x), receiver, field, value); - emitXir(snippet, x, info, null, true); - - if (x.isVolatile()) { - vma.postVolatileWrite(); - } - } - - @Override - public void visitTableSwitch(TableSwitchNode x) { - - LIRItem value = new LIRItem(x.value(), this); - // Making a copy of the switch value is necessary when generating a jump table - value.setDestroysRegister(); - value.loadItem(); - - CiValue tag = value.result(); - setNoResult(x); - - // TODO: tune the defaults for the controls used to determine what kind of translation to use - if (x.numberOfCases() == 0 || x.numberOfCases() <= GraalOptions.SequentialSwitchLimit) { - int loKey = x.lowKey(); - int len = x.numberOfCases(); - for (int i = 0; i < len; i++) { - lir.cmp(Condition.EQ, tag, i + loKey); - lir.branch(Condition.EQ, getLIRBlock(x.blockSuccessor(i))); - } - lir.jump(getLIRBlock(x.defaultSuccessor())); - } else { - SwitchRange[] switchRanges = createLookupRanges(x); - int rangeDensity = x.numberOfCases() / switchRanges.length; - if (rangeDensity >= GraalOptions.RangeTestsSwitchDensity) { - visitSwitchRanges(switchRanges, tag, getLIRBlock(x.defaultSuccessor())); - } else { - LIRBlock[] targets = new LIRBlock[x.numberOfCases()]; - for (int i = 0; i < x.numberOfCases(); ++i) { - targets[i] = getLIRBlock(x.blockSuccessor(i)); - } - lir.tableswitch(tag, x.lowKey(), getLIRBlock(x.defaultSuccessor()), targets); - } - } - } - - @Override - public void visitDeoptimize(DeoptimizeNode deoptimize) { - assert lastState != null : "deoptimize always needs a state"; - assert lastState.bci != FixedWithNextNode.SYNCHRONIZATION_ENTRY_BCI : "bci must not be -1 for deopt framestate"; - DeoptimizationStub stub = new DeoptimizationStub(deoptimize.action(), lastState); - addDeoptimizationStub(stub); - lir.branch(Condition.TRUE, stub.label, stub.info); - } - - private void blockDoEpilog() { - if (GraalOptions.PrintIRWithLIR) { - TTY.println(); - } - - // clear out variables for local constants - constants.clear(); - variablesForConstants.clear(); - } - - private void blockDoProlog(LIRBlock block) { - if (GraalOptions.PrintIRWithLIR) { - TTY.print(block.toString()); - } - // set up the list of LIR instructions - assert block.lir() == null : "LIR list already computed for this block"; - lir = new LIRList(this); - block.setLir(lir); - - lir.branchDestination(block.label()); - } - - /** - * Copies a given value into an operand that is forced to be a stack location. - * - * @param value a value to be forced onto the stack - * @param kind the kind of new operand - * @param mustStayOnStack specifies if the new operand must never be allocated to a register - * @return the operand that is guaranteed to be a stack location when it is - * initially defined a by move from {@code value} - */ - @Override - public CiValue forceToSpill(CiValue value, CiKind kind, boolean mustStayOnStack) { - assert value.isLegal() : "value should not be illegal"; - assert kind.jvmSlots == value.kind.jvmSlots : "size mismatch"; - if (!value.isVariableOrRegister()) { - // force into a variable that must start in memory - CiValue operand = operands.newVariable(value.kind, mustStayOnStack ? VariableFlag.MustStayInMemory : VariableFlag.MustStartInMemory); - lir.move(value, operand); - return operand; - } - - // create a spill location - CiValue operand = operands.newVariable(kind, mustStayOnStack ? VariableFlag.MustStayInMemory : VariableFlag.MustStartInMemory); - // move from register to spill - lir.move(value, operand); - return operand; - } - - private CiVariable loadConstant(ConstantNode x) { - return loadConstant(x.asConstant(), x.kind); - } - - protected CiVariable loadConstant(CiConstant c, CiKind kind) { - // XXX: linear search might be kind of slow for big basic blocks - int index = constants.indexOf(c); - if (index != -1) { - GraalMetrics.LoadConstantIterations += index; - return variablesForConstants.get(index); - } - GraalMetrics.LoadConstantIterations += constants.size(); - - CiVariable result = newVariable(kind); - lir.move(c, result); - constants.add(c); - variablesForConstants.add(result); - return result; - } - - /** - * Allocates a variable operand to hold the result of a given instruction. - * This can only be performed once for any given instruction. - * - * @param x an instruction that produces a result - * @return the variable assigned to hold the result produced by {@code x} - */ - @Override - public CiVariable createResultVariable(ValueNode x) { - CiVariable operand = newVariable(x.kind); - setResult(x, operand); - return operand; - } - - @Override - public void visitRegisterFinalizer(RegisterFinalizerNode x) { - CiValue receiver = load(x.object()); - LIRDebugInfo info = stateFor(x); - callRuntime(CiRuntimeCall.RegisterFinalizer, info, receiver); - setNoResult(x); - } - - private void visitSwitchRanges(SwitchRange[] x, CiValue value, LIRBlock defaultSux) { - for (int i = 0; i < x.length; i++) { - SwitchRange oneRange = x[i]; - int lowKey = oneRange.lowKey; - int highKey = oneRange.highKey; - LIRBlock dest = oneRange.sux; - if (lowKey == highKey) { - lir.cmp(Condition.EQ, value, lowKey); - lir.branch(Condition.EQ, dest); - } else if (highKey - lowKey == 1) { - lir.cmp(Condition.EQ, value, lowKey); - lir.branch(Condition.EQ, dest); - lir.cmp(Condition.EQ, value, highKey); - lir.branch(Condition.EQ, dest); - } else { - Label l = new Label(); - lir.cmp(Condition.LT, value, lowKey); - lir.branch(Condition.LT, l); - lir.cmp(Condition.LE, value, highKey); - lir.branch(Condition.LE, dest); - lir.branchDestination(l); - } - } - lir.jump(defaultSux); - } - - protected void arithmeticOpFpu(int code, CiValue result, CiValue left, CiValue right, CiValue tmp) { - CiValue leftOp = left; - - if (isTwoOperand && leftOp != result) { - assert right != result : "malformed"; - lir.move(leftOp, result); - leftOp = result; - } - - switch (code) { - case DADD: - case FADD: - lir.add(leftOp, right, result); - break; - case FMUL: - case DMUL: - lir.mul(leftOp, right, result); - break; - case DSUB: - case FSUB: - lir.sub(leftOp, right, result); - break; - case FDIV: - case DDIV: - lir.div(leftOp, right, result, null); - break; - default: - Util.shouldNotReachHere(); - } - } - - @Override - public void integerAdd(ValueNode result, ValueNode left, ValueNode right) { - arithmeticOpInt(Bytecodes.IADD, createResultVariable(result), load(left), load(right), CiValue.IllegalValue); - } - - @Override - public void emitUnsignedShiftRight(CiValue value, CiValue count, CiValue dst, CiValue tmp) { - lir().unsignedShiftRight(value, count, dst, tmp); - } - - @Override - public void emitAdd(CiValue a, CiValue b, CiValue dest) { - lir().add(a, b, dest); - } - - public void arithmeticOpInt(int code, CiValue result, CiValue left, CiValue right, CiValue tmp) { - CiValue leftOp = left; - - if (isTwoOperand && leftOp != result) { - assert right != result : "malformed"; - lir.move(leftOp, result); - leftOp = result; - } - - switch (code) { - case IADD: - lir.add(leftOp, right, result); - break; - case IMUL: - boolean didStrengthReduce = false; - if (right.isConstant()) { - CiConstant rightConstant = (CiConstant) right; - int c = rightConstant.asInt(); - if (CiUtil.isPowerOf2(c)) { - // do not need tmp here - lir.shiftLeft(leftOp, CiUtil.log2(c), result); - didStrengthReduce = true; - } else { - didStrengthReduce = strengthReduceMultiply(leftOp, c, result, tmp); - } - } - // we couldn't strength reduce so just emit the multiply - if (!didStrengthReduce) { - lir.mul(leftOp, right, result); - } - break; - case ISUB: - lir.sub(leftOp, right, result); - break; - default: - // idiv and irem are handled elsewhere - Util.shouldNotReachHere(); - } - } - - public void arithmeticOpLong(int code, CiValue result, CiValue left, CiValue right) { - CiValue leftOp = left; - - if (isTwoOperand && leftOp != result) { - assert right != result : "malformed"; - lir.move(leftOp, result); - leftOp = result; - } - - switch (code) { - case LADD: - lir.add(leftOp, right, result); - break; - case LMUL: - lir.mul(leftOp, right, result); - break; - case LSUB: - lir.sub(leftOp, right, result); - break; - default: - // ldiv and lrem are handled elsewhere - Util.shouldNotReachHere(); - } - } - - protected final CiValue callRuntime(CiRuntimeCall runtimeCall, LIRDebugInfo info, CiValue... args) { - // get a result register - CiKind result = runtimeCall.resultKind; - CiKind[] arguments = runtimeCall.arguments; - - CiValue physReg = result.isVoid() ? IllegalValue : resultOperandFor(result); - - List argumentList; - if (arguments.length > 0) { - // move the arguments into the correct location - CiCallingConvention cc = compilation.frameMap().getCallingConvention(arguments, RuntimeCall); - assert cc.locations.length == args.length : "argument count mismatch"; - for (int i = 0; i < args.length; i++) { - CiValue arg = args[i]; - CiValue loc = cc.locations[i]; - if (loc.isRegister()) { - lir.move(arg, loc); - } else { - assert loc.isStackSlot(); - CiStackSlot slot = (CiStackSlot) loc; - if (slot.kind == CiKind.Long || slot.kind == CiKind.Double) { - lir.unalignedMove(arg, slot); - } else { - lir.move(arg, slot); - } - } - } - argumentList = Arrays.asList(cc.locations); - } else { - // no arguments - assert args == null || args.length == 0; - argumentList = Util.uncheckedCast(Collections.emptyList()); - } - - lir.callRuntime(runtimeCall, physReg, argumentList, info); - - return physReg; - } - - protected final CiVariable callRuntimeWithResult(CiRuntimeCall runtimeCall, LIRDebugInfo info, CiValue... args) { - CiVariable result = newVariable(runtimeCall.resultKind); - CiValue location = callRuntime(runtimeCall, info, args); - lir.move(location, result); - return result; - } - - SwitchRange[] createLookupRanges(LookupSwitchNode x) { - // we expect the keys to be sorted by increasing value - List res = new ArrayList(x.numberOfCases()); - int len = x.numberOfCases(); - if (len > 0) { - LIRBlock defaultSux = getLIRBlock(x.defaultSuccessor()); - int key = x.keyAt(0); - LIRBlock sux = getLIRBlock(x.blockSuccessor(0)); - SwitchRange range = new SwitchRange(key, sux); - for (int i = 1; i < len; i++) { - int newKey = x.keyAt(i); - LIRBlock newSux = getLIRBlock(x.blockSuccessor(i)); - if (key + 1 == newKey && sux == newSux) { - // still in same range - range.highKey = newKey; - } else { - // skip tests which explicitly dispatch to the default - if (range.sux != defaultSux) { - res.add(range); - } - range = new SwitchRange(newKey, newSux); - } - key = newKey; - sux = newSux; - } - if (res.size() == 0 || res.get(res.size() - 1) != range) { - res.add(range); - } - } - return res.toArray(new SwitchRange[res.size()]); - } - - SwitchRange[] createLookupRanges(TableSwitchNode x) { - // XXX: try to merge this with the code for LookupSwitch - List res = new ArrayList(x.numberOfCases()); - int len = x.numberOfCases(); - if (len > 0) { - LIRBlock sux = getLIRBlock(x.blockSuccessor(0)); - int key = x.lowKey(); - LIRBlock defaultSux = getLIRBlock(x.defaultSuccessor()); - SwitchRange range = new SwitchRange(key, sux); - for (int i = 0; i < len; i++, key++) { - LIRBlock newSux = getLIRBlock(x.blockSuccessor(i)); - if (sux == newSux) { - // still in same range - range.highKey = key; - } else { - // skip tests which explicitly dispatch to the default - if (sux != defaultSux) { - res.add(range); - } - range = new SwitchRange(key, newSux); - } - sux = newSux; - } - if (res.size() == 0 || res.get(res.size() - 1) != range) { - res.add(range); - } - } - return res.toArray(new SwitchRange[res.size()]); - } - - void doRoot(ValueNode instr) { - if (GraalOptions.TraceLIRGeneratorLevel >= 2) { - TTY.println("Emitting LIR for instruction " + instr); - } - currentInstruction = instr; - - if (GraalOptions.TraceLIRVisit) { - TTY.println("Visiting " + instr); - } - - LIRGeneratorOp op = instr.lookup(LIRGeneratorOp.class); - if (op != null) { - op.generate(instr, this); - } - - if (GraalOptions.TraceLIRVisit) { - TTY.println("Operand for " + instr + " = " + instr.operand()); - } - } - - protected void logicOp(int code, CiValue resultOp, CiValue leftOp, CiValue rightOp) { - if (isTwoOperand && leftOp != resultOp) { - assert rightOp != resultOp : "malformed"; - lir.move(leftOp, resultOp); - leftOp = resultOp; - } - - switch (code) { - case IAND: - case LAND: - lir.logicalAnd(leftOp, rightOp, resultOp); - break; - - case IOR: - case LOR: - lir.logicalOr(leftOp, rightOp, resultOp); - break; - - case IXOR: - case LXOR: - lir.logicalXor(leftOp, rightOp, resultOp); - break; - - default: - Util.shouldNotReachHere(); - } - } - - /*void moveToPhi(PhiResolver resolver, Value curVal, Value suxVal, List phis, int predIndex) { - // move current value to referenced phi function - if (suxVal instanceof Phi) { - Phi phi = (Phi) suxVal; - - // curVal can be null without phi being null in conjunction with inlining - if (!phi.isDead() && curVal != null && curVal != phi) { - - assert phis.contains(phi); - if (phi.valueAt(predIndex) != curVal) { - phi.print(TTY.out()); - } - assert phi.valueAt(predIndex) == curVal : "curVal=" + curVal + "valueAt(" + predIndex + ")=" + phi.valueAt(predIndex); - - assert !phi.isDead() : "illegal phi cannot be marked as live"; - if (curVal instanceof Phi) { - operandForPhi((Phi) curVal); - } - CiValue operand = curVal.operand(); - if (operand.isIllegal()) { - assert curVal instanceof Constant || curVal instanceof Local : "these can be produced lazily"; - operand = operandForInstruction(curVal); - } - resolver.move(operand, operandForPhi(phi)); - } - } - }*/ - - @Override - public void visitEndNode(EndNode end) { - setNoResult(end); - assert end.merge() != null; - moveToPhi(end.merge(), end); - LIRBlock lirBlock = getLIRBlock(end.merge()); - assert lirBlock != null : end; - lir.jump(lirBlock); - } - - @Override - public void visitMemoryRead(ReadNode memRead) { - lir.move(memRead.location().createAddress(this, memRead.object()), createResultVariable(memRead), memRead.location().getValueKind()); - } - - - @Override - public void visitMemoryWrite(WriteNode memWrite) { - lir.move(load(memWrite.value()), memWrite.location().createAddress(this, memWrite.object()), memWrite.location().getValueKind()); - } - - - @Override - public void visitLoopEnd(LoopEndNode x) { - setNoResult(x); - moveToPhi(x.loopBegin(), x); - if (GraalOptions.GenSafepoints) { - xir.genSafepoint(site(x)); - } - lir.jump(getLIRBlock(x.loopBegin())); - } - - private void moveToPhi(MergeNode merge, Node pred) { - if (GraalOptions.TraceLIRGeneratorLevel >= 1) { - TTY.println("MOVE TO PHI from " + pred + " to " + merge); - } - int nextSuccIndex = merge.phiPredecessorIndex(pred); - PhiResolver resolver = new PhiResolver(this); - for (PhiNode phi : merge.phis()) { - if (phi.type() == PhiType.Value) { - ValueNode curVal = phi.valueAt(nextSuccIndex); - if (curVal != null && curVal != phi) { - if (curVal instanceof PhiNode) { - operandForPhi((PhiNode) curVal); - } - CiValue operand = curVal.operand(); - if (operand.isIllegal()) { - assert curVal instanceof ConstantNode || curVal instanceof LocalNode : "these can be produced lazily" + curVal + "/" + phi; - operand = operandForInstruction(curVal); - } - resolver.move(operand, operandForPhi(phi)); - } - } - } - resolver.dispose(); - } - - /** - * Creates a new {@linkplain CiVariable variable}. - * - * @param kind the kind of the variable - * @return a new variable - */ - @Override - public CiVariable newVariable(CiKind kind) { - return operands.newVariable(kind); - } - - CiValue operandForInstruction(ValueNode x) { - CiValue operand = x.operand(); - if (operand.isIllegal()) { - if (x instanceof ConstantNode) { - x.setOperand(x.asConstant()); - } else { - assert x instanceof PhiNode || x instanceof LocalNode : "only for Phi and Local : " + x; - // allocate a variable for this local or phi - createResultVariable(x); - } - } - return x.operand(); - } - - private CiValue operandForPhi(PhiNode phi) { - assert phi.type() == PhiType.Value : "wrong phi type: " + phi.id(); - if (phi.operand().isIllegal()) { - // allocate a variable for this phi - createResultVariable(phi); - } - return phi.operand(); - } - - protected void postGCWriteBarrier(CiValue addr, CiValue newVal) { - XirSnippet writeBarrier = xir.genWriteBarrier(toXirArgument(addr)); - if (writeBarrier != null) { - emitXir(writeBarrier, null, null, null, false); - } - } - - protected void preGCWriteBarrier(CiValue addrOpr, boolean patch, LIRDebugInfo info) { - } - - protected void setNoResult(ValueNode x) { - x.clearOperand(); - } - - public CiValue setResult(ValueNode x, CiVariable operand) { - x.setOperand(operand); - if (GraalOptions.DetailedAsserts) { - operands.recordResult(operand, x); - } - return operand; - } - - protected void shiftOp(int code, CiValue resultOp, CiValue value, CiValue count, CiValue tmp) { - if (isTwoOperand && value != resultOp) { - assert count != resultOp : "malformed"; - lir.move(value, resultOp); - value = resultOp; - } - - assert count.isConstant() || count.isVariableOrRegister(); - switch (code) { - case ISHL: - case LSHL: - lir.shiftLeft(value, count, resultOp, tmp); - break; - case ISHR: - case LSHR: - lir.shiftRight(value, count, resultOp, tmp); - break; - case IUSHR: - case LUSHR: - lir.unsignedShiftRight(value, count, resultOp, tmp); - break; - default: - Util.shouldNotReachHere(); - } - } - - protected void walkState(final Node x, FrameState state) { - if (state == null) { - return; - } - - state.forEachLiveStateValue(new ValueProcedure() { - public void doValue(ValueNode value) { - if (value == x) { - // nothing to do, will be visited shortly - } else if (value instanceof PhiNode && ((PhiNode) value).type() == PhiType.Value) { - // phi's are special - operandForPhi((PhiNode) value); - } else if (value.operand().isIllegal()) { - // instruction doesn't have an operand yet - CiValue operand = makeOperand(value); - assert operand.isLegal() : "must be evaluated now"; - } - } - }); - } - - protected LIRDebugInfo stateFor(ValueNode x) { - assert lastState != null : "must have state before instruction for " + x; - return stateFor(x, lastState); - } - - protected LIRDebugInfo stateFor(ValueNode x, FrameState state) { - if (compilation.placeholderState != null) { - state = compilation.placeholderState; - } - return new LIRDebugInfo(state); - } - - List visitInvokeArguments(CiCallingConvention cc, InvokeNode x, List pointerSlots) { - // for each argument, load it into the correct location - List argList = new ArrayList(); - int j = 0; - for (ValueNode arg : x.arguments()) { - if (arg != null) { - CiValue operand = cc.locations[j++]; - if (operand.isRegister()) { - force(arg, operand); - } else { - LIRItem param = new LIRItem(arg, this); - assert operand.isStackSlot(); - CiStackSlot slot = (CiStackSlot) operand; - assert !slot.inCallerFrame(); - param.loadForStore(slot.kind); - if (slot.kind == CiKind.Long || slot.kind == CiKind.Double) { - lir.unalignedMove(param.result(), slot); - } else { - lir.move(param.result(), slot); - } - - if (arg.kind == CiKind.Object && pointerSlots != null) { - // This slot must be marked explicitly in the pointer map. - pointerSlots.add(slot); - } - } - argList.add(operand); - } - } - return argList; - } - - /** - * Ensures that an operand has been {@linkplain ValueNode#setOperand(CiValue) initialized} - * for storing the result of an instruction. - * - * @param instruction an instruction that produces a result value - */ - @Override - public CiValue makeOperand(ValueNode instruction) { - if (instruction == null) { - return CiValue.IllegalValue; - } - CiValue operand = instruction.operand(); - if (operand.isIllegal()) { - if (instruction instanceof PhiNode) { - // a phi may not have an operand yet if it is for an exception block - operand = operandForPhi((PhiNode) instruction); - } else if (instruction instanceof ConstantNode) { - operand = operandForInstruction(instruction); - } - } - // the value must be a constant or have a valid operand - assert operand.isLegal() : "this root has not been visited yet; instruction=" + instruction + " currentBlock=" + currentBlock; - return operand; - } - - /** - * Gets the ABI specific operand used to return a value of a given kind from a method. - * - * @param kind the kind of value being returned - * @return the operand representing the ABI defined location used return a value of kind {@code kind} - */ - protected CiValue resultOperandFor(CiKind kind) { - if (kind == CiKind.Void) { - return IllegalValue; - } - CiRegister returnRegister = compilation.registerConfig.getReturnRegister(kind); - return returnRegister.asValue(kind); - } - - protected XirSupport site(ValueNode x) { - return xirSupport.site(x); - } - - public void maybePrintCurrentInstruction() { - if (currentInstruction != null && lastInstructionPrinted != currentInstruction) { - lastInstructionPrinted = currentInstruction; - InstructionPrinter ip = new InstructionPrinter(TTY.out()); - ip.printInstructionListing(currentInstruction); - } - } - - public abstract boolean canInlineAsConstant(ValueNode i); - - protected abstract boolean canStoreAsConstant(ValueNode i, CiKind kind); - - protected abstract boolean strengthReduceMultiply(CiValue left, int constant, CiValue result, CiValue tmp); - - protected abstract CiAddress genAddress(CiValue base, CiValue index, int shift, int disp, CiKind kind); - - protected abstract void genCmpMemInt(Condition condition, CiValue base, int disp, int c, LIRDebugInfo info); - - protected abstract void genCmpRegMem(Condition condition, CiValue reg, CiValue base, int disp, CiKind kind, LIRDebugInfo info); - - /** - * Implements site-specific information for the XIR interface. - */ - static class XirSupport implements XirSite { - ValueNode current; - - XirSupport() { - } - - public CiCodePos getCodePos() { - // TODO: get the code position of the current instruction if possible - return null; - } - - public boolean isNonNull(XirArgument argument) { - return false; - } - - public boolean requiresNullCheck() { - return current == null || true; - } - - public boolean requiresBoundsCheck() { - return true; - } - - public boolean requiresReadBarrier() { - return current == null || true; - } - - public boolean requiresWriteBarrier() { - return current == null || true; - } - - public boolean requiresArrayStoreCheck() { - return true; - } - - public RiType getApproximateType(XirArgument argument) { - return current == null ? null : current.declaredType(); - } - - public RiType getExactType(XirArgument argument) { - return current == null ? null : current.exactType(); - } - - XirSupport site(ValueNode v) { - current = v; - return this; - } - - @Override - public String toString() { - return "XirSupport<" + current + ">"; - } - - - } - - @Override - public void visitFrameState(FrameState i) { - // nothing to do for now - } - - @Override - public void visitUnwind(UnwindNode x) { - // move exception oop into fixed register - CiCallingConvention callingConvention = compilation.frameMap().getCallingConvention(new CiKind[]{CiKind.Object}, RuntimeCall); - CiValue argumentOperand = callingConvention.locations[0]; - lir.move(makeOperand(x.exception()), argumentOperand); - List args = new ArrayList(1); - lir.callRuntime(CiRuntimeCall.UnwindException, CiValue.IllegalValue, args, null); - setNoResult(x); - } - - public abstract Condition floatingPointCondition(Condition cond); - - @Override - public void visitConditional(ConditionalNode conditional) { - - BooleanNode condition = conditional.condition(); - LIRGenerator generator = this; - - // try to use cmp + cmov first - Condition cond = null; - CiValue left = null; - CiValue right = null; - boolean floating = false; - boolean unOrderedIsSecond = false; - boolean negate = false; - while (condition instanceof NegateBooleanNode) { - negate = !negate; - condition = ((NegateBooleanNode) condition).value(); - } - if (condition instanceof CompareNode) { - CompareNode compare = (CompareNode) condition; - ValueNode x = compare.x(); - ValueNode y = compare.y(); - cond = compare.condition(); - if (x.kind.isFloatOrDouble()) { - floating = true; - unOrderedIsSecond = !compare.unorderedIsTrue(); - cond = generator.floatingPointCondition(cond); - } - left = generator.load(x); - if (!generator.canInlineAsConstant(y)) { - right = generator.load(y); - } else { - right = generator.makeOperand(y); - } - } else if (condition instanceof IsNonNullNode) { - IsNonNullNode isNonNull = (IsNonNullNode) condition; - left = generator.load(isNonNull.object()); - right = CiConstant.NULL_OBJECT; - cond = Condition.NE; - } else if (condition instanceof ConstantNode) { - generator.lir().move(condition.asConstant(), generator.createResultVariable(conditional)); - } else if (condition instanceof InstanceOfNode) { - if (conditional instanceof MaterializeNode && !negate) { - generator.emitMaterializeInstanceOf((MaterializeNode) conditional, conditional, null); - } else { - generator.emitMaterializeInstanceOf((MaterializeNode) conditional, condition, null); - left = condition.operand(); - right = CiConstant.INT_1; - cond = Condition.EQ; - } - } else { - throw Util.shouldNotReachHere("Currently not implemented because we can not create blocks during LIRGen : " + condition); - } - - if (cond != null) { - CiVariable result = generator.createResultVariable(conditional); - CiValue tVal = generator.makeOperand(conditional.trueValue()); - CiValue fVal = generator.makeOperand(conditional.falseValue()); - if (negate) { - cond = cond.negate(); - } - assert left != null && right != null; - generator.lir().cmp(cond, left, right); - if (floating) { - generator.lir().fcmove(cond, tVal, fVal, result, unOrderedIsSecond); - } else { - generator.lir().cmove(cond, tVal, fVal, result); - } - } - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/gen/LIRItem.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/gen/LIRItem.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,189 +0,0 @@ -/* - * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.compiler.gen; - -import com.oracle.max.graal.compiler.alloc.OperandPool.VariableFlag; -import com.oracle.max.graal.compiler.util.*; -import com.oracle.max.graal.nodes.*; -import com.sun.cri.ci.*; - -/** - * A helper utility for loading the {@linkplain ValueNode#operand() result} - * of an instruction for use by another instruction. This helper takes - * into account the specifics of the consuming instruction such as whether - * it requires the input operand to be in memory or a register, any - * register size requirements of the input operand, and whether the - * usage has the side-effect of overwriting the input operand. To satisfy - * these constraints, an intermediate operand may be created and move - * instruction inserted to copy the output of the producer instruction - * into the intermediate operand. - * - * @author Marcelo Cintra - * @author Thomas Wuerthinger - * @author Doug Simon - */ -public class LIRItem { - - /** - * The instruction whose usage by another instruction is being modeled by this object. - * An instruction {@code x} uses instruction {@code y} if the {@linkplain ValueNode#operand() result} - * of {@code y} is an input operand of {@code x}. - */ - public ValueNode instruction; - - /** - * The LIR context of this helper object. - */ - private final LIRGenerator gen; - - /** - * The operand holding the result of this item's {@linkplain #instruction}. - */ - private CiValue resultOperand; - - /** - * Denotes if the use of the instruction's {@linkplain #resultOperand result operand} - * overwrites the value in the operand. That is, the use both uses and defines the - * operand. In this case, an {@linkplain #intermediateOperand intermediate operand} - * is created for the use so that other consumers of this item's {@linkplain #instruction} - * are not impacted. - */ - private boolean destructive; - - /** - * @see #destructive - */ - private CiValue intermediateOperand; - - public LIRItem(ValueNode instruction, LIRGenerator gen) { - this.gen = gen; - this.instruction = instruction; - resultOperand = gen.makeOperand(instruction); - intermediateOperand = CiValue.IllegalValue; - } - - public void loadForStore(CiKind kind) { - if (gen.canStoreAsConstant(instruction, kind)) { - resultOperand = instruction.operand(); - if (!resultOperand.isConstant()) { - resultOperand = instruction.asConstant(); - } - } else if (kind == CiKind.Byte || kind == CiKind.Boolean) { - loadByteItem(); - } else { - loadItem(); - } - } - - public CiValue result() { - assert !destructive || !resultOperand.isRegister() : "shouldn't use setDestroysRegister with physical registers"; - if (destructive && (resultOperand.isVariable() || resultOperand.isConstant())) { - if (intermediateOperand.isIllegal()) { - intermediateOperand = gen.newVariable(instruction.kind); - gen.lir.move(resultOperand, intermediateOperand); - } - return intermediateOperand; - } else { - return resultOperand; - } - } - - public void setDestroysRegister() { - destructive = true; - } - - /** - * Determines if the operand is in a stack slot. - */ - public boolean isStack() { - return resultOperand.isAddress() || resultOperand.isStackSlot(); - } - - /** - * Determines if the operand is in a register or may be - * resolved to a register by the register allocator. - */ - public boolean isRegisterOrVariable() { - return resultOperand.isVariableOrRegister(); - } - - public void loadByteItem() { - if (gen.compilation.target.arch.isX86()) { - loadItem(); - CiValue res = result(); - - if (!res.isVariable() || !gen.operands.mustBeByteRegister(res)) { - // make sure that it is a byte register - assert !instruction.kind.isFloat() && !instruction.kind.isDouble() : "can't load floats in byte register"; - CiValue reg = gen.operands.newVariable(CiKind.Byte, VariableFlag.MustBeByteRegister); - gen.lir.move(res, reg); - resultOperand = reg; - } - } else if (gen.compilation.target.arch.isSPARC()) { - loadItem(); - } else { - Util.shouldNotReachHere(); - } - } - - public void loadNonconstant() { - assert gen.compilation.target.arch.isX86(); - CiValue r = instruction.operand(); - if (r.isConstant()) { - resultOperand = r; - } else { - loadItem(); - } - } - - private void setResult(CiVariable operand) { - gen.setResult(instruction, operand); - resultOperand = operand; - } - - /** - * Creates an operand containing the result of {@linkplain #instruction input instruction}. - */ - public void loadItem() { - if (result().isIllegal()) { - // update the item's result - resultOperand = instruction.operand(); - } - CiValue result = result(); - if (!result.isVariableOrRegister()) { - CiVariable operand; - operand = gen.newVariable(instruction.kind); - gen.lir.move(result, operand); - if (result.isConstant()) { - resultOperand = operand; - } else { - setResult(operand); - } - } - } - - @Override - public String toString() { - return result().toString(); - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/gen/PhiResolver.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/gen/PhiResolver.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,234 +0,0 @@ -/* - * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.compiler.gen; - -import static com.sun.cri.ci.CiValue.*; - -import java.util.*; - -import com.oracle.max.graal.nodes.*; -import com.sun.cri.ci.*; - -/** - * Converts {@link PhiNode} instructions into moves. - * - * Resolves cycles: - *
- *
- *  r1 := r2  becomes  temp := r1
- *  r2 := r1           r1 := r2
- *                     r2 := temp
- * 
- * - * and orders moves: - * - *
- *  r2 := r3  becomes  r1 := r2
- *  r1 := r2           r2 := r3
- * 
- */ -public class PhiResolver { - - /** - * Tracks a data flow dependency between a source operand and any number of the destination operands. - */ - static class PhiResolverNode { - - /** - * A source operand whose value flows into the {@linkplain #destinations destination} operands. - */ - final CiValue operand; - - /** - * The operands whose values are defined by the {@linkplain #operand source} operand. - */ - final ArrayList destinations; - - /** - * Denotes if a move instruction has already been emitted to initialize the value of {@link #operand}. - */ - boolean assigned; - - /** - * Specifies if this operand been visited for the purpose of emitting a move instruction. - */ - boolean visited; - - /** - * Specifies if this is the initial definition in data flow path for a given value. - */ - boolean startNode; - - PhiResolverNode(CiValue operand) { - this.operand = operand; - destinations = new ArrayList(4); - } - - @Override - public String toString() { - StringBuilder buf = new StringBuilder(operand.toString()); - if (!destinations.isEmpty()) { - buf.append(" ->"); - for (PhiResolverNode node : destinations) { - buf.append(' ').append(node.operand); - } - } - return buf.toString(); - } - } - - private final LIRGenerator gen; - - /** - * The operand loop header phi for the operand currently being process in {@link #dispose()}. - */ - private PhiResolverNode loop; - - private CiValue temp; - - private final ArrayList variableOperands = new ArrayList(3); - private final ArrayList otherOperands = new ArrayList(3); - - /** - * Maps operands to nodes. - */ - private final HashMap operandToNodeMap = new HashMap(); - - public PhiResolver(LIRGenerator gen) { - this.gen = gen; - temp = IllegalValue; - } - - public void dispose() { - // resolve any cycles in moves from and to variables - for (int i = variableOperands.size() - 1; i >= 0; i--) { - PhiResolverNode node = variableOperands.get(i); - if (!node.visited) { - loop = null; - move(null, node); - node.startNode = true; - assert temp.isIllegal() : "moveTempTo() call missing"; - } - } - - // generate move for move from non variable to arbitrary destination - for (int i = otherOperands.size() - 1; i >= 0; i--) { - PhiResolverNode node = otherOperands.get(i); - for (int j = node.destinations.size() - 1; j >= 0; j--) { - emitMove(node.operand, node.destinations.get(j).operand); - } - } - } - - public void move(CiValue src, CiValue dest) { - assert dest.isVariable() : "destination must be virtual"; - // tty.print("move "); src.print(); tty.print(" to "); dest.print(); tty.cr(); - assert src.isLegal() : "source for phi move is illegal"; - assert dest.isLegal() : "destination for phi move is illegal"; - PhiResolverNode srcNode = sourceNode(src); - PhiResolverNode destNode = destinationNode(dest); - srcNode.destinations.add(destNode); - } - - private PhiResolverNode createNode(CiValue operand, boolean source) { - PhiResolverNode node; - if (operand.isVariable()) { - node = operandToNodeMap.get(operand); - assert node == null || node.operand.equals(operand); - if (node == null) { - node = new PhiResolverNode(operand); - operandToNodeMap.put(operand, node); - } - // Make sure that all variables show up in the list when - // they are used as the source of a move. - if (source) { - if (!variableOperands.contains(node)) { - variableOperands.add(node); - } - } - } else { - assert source; - node = new PhiResolverNode(operand); - otherOperands.add(node); - } - return node; - } - - private PhiResolverNode destinationNode(CiValue opr) { - return createNode(opr, false); - } - - private void emitMove(CiValue src, CiValue dest) { - assert src.isLegal(); - assert dest.isLegal(); - gen.lir.move(src, dest); - } - - // Traverse assignment graph in depth first order and generate moves in post order - // ie. two assignments: b := c, a := b start with node c: - // Call graph: move(NULL, c) -> move(c, b) -> move(b, a) - // Generates moves in this order: move b to a and move c to b - // ie. cycle a := b, b := a start with node a - // Call graph: move(NULL, a) -> move(a, b) -> move(b, a) - // Generates moves in this order: move b to temp, move a to b, move temp to a - private void move(PhiResolverNode src, PhiResolverNode dest) { - if (!dest.visited) { - dest.visited = true; - for (int i = dest.destinations.size() - 1; i >= 0; i--) { - move(dest, dest.destinations.get(i)); - } - } else if (!dest.startNode) { - // cycle in graph detected - assert loop == null : "only one loop valid!"; - loop = dest; - moveToTemp(src.operand); - return; - } // else dest is a start node - - if (!dest.assigned) { - if (loop == dest) { - moveTempTo(dest.operand); - dest.assigned = true; - } else if (src != null) { - emitMove(src.operand, dest.operand); - dest.assigned = true; - } - } - } - - private void moveTempTo(CiValue dest) { - assert temp.isLegal(); - emitMove(temp, dest); - temp = IllegalValue; - } - - private void moveToTemp(CiValue src) { - assert temp.isIllegal(); - temp = gen.newVariable(src.kind); - emitMove(src, temp); - } - - private PhiResolverNode sourceNode(CiValue opr) { - return createNode(opr, true); - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/gen/PhiSimplifier.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/gen/PhiSimplifier.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,119 +0,0 @@ -/* - * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.compiler.gen; - -import com.oracle.max.graal.graph.*; -import com.oracle.max.graal.graph.collections.*; -import com.oracle.max.graal.nodes.*; - -/** - * The {@code PhiSimplifier} class is a helper class that can reduce phi instructions. - */ -public final class PhiSimplifier { - - private NodeBitMap visited; - private NodeBitMap cannotSimplify; - - public PhiSimplifier(Graph graph) { - visited = graph.createNodeBitMap(); - cannotSimplify = graph.createNodeBitMap(); - - for (Node n : graph.getNodes()) { - if (n instanceof PhiNode) { - simplify((PhiNode) n); - } - } - } - - private ValueNode simplify(ValueNode x) { - if (x == null || !(x instanceof PhiNode)) { - return x; - } - PhiNode phi = (PhiNode) x; - - if (phi.valueCount() == 1 && !cannotSimplify.isMarked(phi)) { - ValueNode result = phi.valueAt(0); - phi.replaceAndDelete(result); - return result; - } - - if (cannotSimplify.isMarked(phi)) { - // already tried, cannot simplify this phi - return phi; - } else if (visited.isMarked(phi)) { - // break cycles in phis - return phi; - } else { - // attempt to simplify the phi by recursively simplifying its operands - visited.mark(phi); - ValueNode phiSubst = null; - int max = phi.valueCount(); - boolean cannotSimplify = false; - for (int i = 0; i < max; i++) { - ValueNode oldInstr = phi.valueAt(i); - - if (oldInstr == null) { - // if one operand is illegal, make the entire phi illegal - visited.clear(phi); - phi.replaceAndDelete(null); - return null; - } - - ValueNode newInstr = simplify(oldInstr); - - if (newInstr == null) { - // if the subst instruction is illegal, make the entire phi illegal - visited.clear(phi); - phi.replaceAndDelete(null); - return null; - } - - // attempt to simplify this operand - if (!cannotSimplify) { - - if (newInstr != phi && newInstr != phiSubst) { - if (phiSubst == null) { - phiSubst = newInstr; - continue; - } - // this phi cannot be simplified - cannotSimplify = true; - } - } - } - if (cannotSimplify) { - this.cannotSimplify.mark(phi); - visited.clear(phi); - return phi; - } - - // successfully simplified the phi - assert phiSubst != null : "illegal phi function"; - visited.clear(phi); - - phi.replaceAndDelete(phiSubst); - - return phiSubst; - } - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/gen/package-info.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/gen/package-info.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,30 +0,0 @@ -/* - * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -/** - * This package contains the port of the LIRGenerator which translates - * HIR instructions to LIR instructions for the backend. - * - * @author Marcelo Cintra - * @author Thomas Wuerthinger - */ -package com.oracle.max.graal.compiler.gen; diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/globalstub/GlobalStub.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/globalstub/GlobalStub.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,73 +0,0 @@ -/* - * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.compiler.globalstub; - -import static com.sun.cri.ci.CiKind.*; - -import com.sun.cri.ci.*; - -/** - * A global stub is a shared routine that performs an operation on behalf of compiled code. - * Typically the routine is too large to inline, is infrequent, or requires runtime support. - * Global stubs are called with a callee-save convention; the global stub must save any - * registers it may destroy and then restore them upon return. This allows the register - * allocator to ignore calls to global stubs. Parameters to global stubs are - * passed on the stack in order to preserve registers for the rest of the code. - * - * @author Thomas Wuerthinger - * @author Ben L. Titzer - */ -public class GlobalStub { - - public enum Id { - f2i(Int, Float), - f2l(Long, Float), - d2i(Int, Double), - d2l(Long, Double); - - public final CiKind resultKind; - public final CiKind[] arguments; - - private Id(CiKind resultKind, CiKind... args) { - this.resultKind = resultKind; - this.arguments = args; - } - } - - public final Id id; - public final CiKind resultKind; - public final Object stubObject; - public final int argsSize; - public final int[] argOffsets; - public final int resultOffset; - - public GlobalStub(Id id, CiKind resultKind, Object stubObject, int argsSize, int[] argOffsets, int resultOffset) { - this.id = id; - this.resultKind = resultKind; - this.stubObject = stubObject; - this.argsSize = argsSize; - this.argOffsets = argOffsets; - this.resultOffset = resultOffset; - } - -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/globalstub/GlobalStubEmitter.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/globalstub/GlobalStubEmitter.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,39 +0,0 @@ -/* - * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.compiler.globalstub; - -import com.sun.cri.ci.*; -import com.sun.cri.ri.*; -import com.sun.cri.xir.*; - -/** - * An interface to represent the entity that generates stubs. - * - * @author Thomas Wuerthinger - * @author Ben L. Titzer - */ -public interface GlobalStubEmitter { - GlobalStub emit(GlobalStub.Id stub, RiRuntime runtime); - GlobalStub emit(CiRuntimeCall runtimeCall, RiRuntime runtime); - GlobalStub emit(XirTemplate t, RiRuntime runtime); -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/graph/BlockMap.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/graph/BlockMap.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,699 +0,0 @@ -/* - * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.compiler.graph; - -import static com.sun.cri.bytecode.Bytecodes.*; - -import java.util.*; - -import com.oracle.max.graal.compiler.*; -import com.oracle.max.graal.compiler.debug.*; -import com.oracle.max.graal.nodes.*; -import com.sun.cri.bytecode.*; -import com.sun.cri.ci.*; -import com.sun.cri.ri.*; - -/** - * Builds a mapping between bytecodes and basic blocks and builds a conservative control flow - * graph. Note that this class serves a similar role to C1's {@code BlockListBuilder}, but makes fewer assumptions about - * what the compiler interface provides. It builds all basic blocks for the control flow graph without requiring the - * compiler interface to provide a bitmap of the beginning of basic blocks. It makes two linear passes; one over the - * bytecodes to build block starts and successor lists, and one pass over the block map to build the CFG. - * - * Note that the CFG built by this class is not connected to the actual {@code BlockBegin} instances; this class - * does, however, compute and assign the reverse postorder number of the blocks. This comment needs refinement. (MJJ) - * - *

More Details on {@link BlockMap#build}

- * - * If the method has any exception handlers the {@linkplain #exceptionMap exception map} will be created (TBD). - * - * The bytecodes are then scanned linearly looking for bytecodes that contain control transfers, e.g., {@code GOTO}, - * {@code RETURN}, {@code IFGE}, and creating the corresponding entries in {@link #successorMap} and {@link #blockMap}. - * In addition, if {@link #exceptionMap} is not null, entries are made for any bytecode that can cause an exception. - * More TBD. - * - * Observe that this process finds bytecodes that terminate basic blocks, so the {@link #moveSuccessorLists} method is - * called to reassign the successors to the {@code BlockBegin} node that actually starts the block. - * - *

Example

- * - * Consider the following source code: - * - *
- * 
- *     public static int test(int arg1, int arg2) {
- *         int x = 0;
- *         while (arg2 > 0) {
- *             if (arg1 > 0) {
- *                 x += 1;
- *             } else if (arg1 < 0) {
- *                 x -= 1;
- *             }
- *         }
- *         return x;
- *     }
- * 
- * 
- * - * This is translated by javac to the following bytecode: - * - *
- * 
- *    0:   iconst_0
- *    1:   istore_2
- *    2:   goto    22
- *    5:   iload_0
- *    6:   ifle    15
- *    9:   iinc    2, 1
- *    12:  goto    22
- *    15:  iload_0
- *    16:  ifge    22
- *    19:  iinc    2, -1
- *    22:  iload_1
- *    23:  ifgt    5
- *    26:  iload_2
- *    27:  ireturn
- *    
- * 
- * - * There are seven basic blocks in this method, 0..2, 5..6, 9..12, 15..16, 19..19, 22..23 and 26..27. Therefore, before - * the call to {@code moveSuccessorLists}, the {@code blockMap} array has {@code BlockBegin} nodes at indices 0, 5, 9, - * 15, 19, 22 and 26. The {@code successorMap} array has entries at 2, 6, 12, 16, 23, 27 corresponding to the control - * transfer bytecodes. The entry at index 6, for example, is a length two array of {@code BlockBegin} nodes for indices - * 9 and 15, which are the successors for the basic block 5..6. After the call to {@code moveSuccessors}, {@code - * successorMap} has entries at 0, 5, 9, 15, 19, 22 and 26, i.e, matching {@code blockMap}. - *

- * Next the blocks are numbered using reverse - * post-order. For the above example this results in the numbering 2, 4, 7, 5, 6, 3, 8. Also loop header blocks are - * detected during the traversal by detecting a repeat visit to a block that is still being processed. This causes the - * block to be flagged as a loop header and also added to the {@link #loopBlocks} list. The {@code loopBlocks} list - * contains the blocks at 0, 5, 9, 15, 19, 22, with 22 as the loop header. (N.B. the loop header block is added multiple - * (4) times to this list). (Should 0 be in? It's not inside the loop). - * - * If the {@code computeStoresInLoops} argument to {@code build} is true, the {@code loopBlocks} list is processed to - * mark all local variables that are stored in the blocks in the list. - */ -public final class BlockMap { - public static class Block { - public int startBci; - public int endBci; - public boolean isExceptionEntry; - public boolean isLoopHeader; - public int blockID; - - public FixedWithNextNode firstInstruction; - - final HashSet successors = new LinkedHashSet(); - private boolean visited; - private boolean active; - private long loops; - } - - public static class ExceptionBlock extends Block { - public RiExceptionHandler handler; - public Block next; - public int deoptBci; - } - - public static class DeoptBlock extends Block { - } - - public static class BranchOverride { - public DeoptBlock block; - public boolean taken; - } - - private static final Block[] NO_SUCCESSORS = new Block[0]; - - /** - * The blocks found in this method, in reverse postorder. - */ - public final List blocks; - - /** - * A bit map covering the locals with a bit set for each local that might be stored to within a - * loop. If the bit is cleared, it is guaranteed that the local is never stored in a loop. - */ - public final BitSet storesInLoops; - - private final RiMethod method; - - private final RiExceptionHandler[] exceptionHandlers; - - public final HashMap branchOverride; - - private Block[] blockMap; - - private BitSet canTrap; - - /** - * Creates a new BlockMap instance from bytecode of the given method . - * @param method the compiler interface method containing the code - */ - public BlockMap(RiMethod method) { - this.method = method; - exceptionHandlers = method.exceptionHandlers(); - this.blockMap = new Block[method.codeSize()]; - if (method.exceptionHandlers().length != 0) { - this.canTrap = new BitSet(blockMap.length); - } - this.blocks = new ArrayList(); - this.storesInLoops = new BitSet(method.maxLocals()); - branchOverride = new HashMap(); - } - - public RiExceptionHandler[] exceptionHandlers() { - return exceptionHandlers; - } - - /** - * Builds the block map and conservative CFG and numbers blocks. - */ - public void build() { - makeExceptionEntries(); - iterateOverBytecodes(); - addExceptionEdges(); - computeBlockOrder(); - - initializeBlockIds(); - - // Discard big arrays so that they can be GCed - blockMap = null; - canTrap = null; - } - - private void initializeBlockIds() { - for (int i = 0; i < blocks.size(); i++) { - blocks.get(i).blockID = i; - } - } - - private void makeExceptionEntries() { - // start basic blocks at all exception handler blocks and mark them as exception entries - for (RiExceptionHandler h : this.exceptionHandlers) { - Block xhandler = makeBlock(h.handlerBCI()); - xhandler.isExceptionEntry = true; - } - } - - private void iterateOverBytecodes() { - // iterate over the bytecodes top to bottom. - // mark the entrypoints of basic blocks and build lists of successors for - // all bytecodes that end basic blocks (i.e. goto, ifs, switches, throw, jsr, returns, ret) - byte[] code = method.code(); - Block current = null; - int bci = 0; - while (bci < code.length) { - if (current == null || blockMap[bci] != null) { - Block b = makeBlock(bci); - if (current != null) { - setSuccessors(current.endBci, b); - } - current = b; - } - blockMap[bci] = current; - current.endBci = bci; - - int opcode = Bytes.beU1(code, bci); - switch (opcode) { - case IRETURN: // fall through - case LRETURN: // fall through - case FRETURN: // fall through - case DRETURN: // fall through - case ARETURN: // fall through - case WRETURN: // fall through - case RETURN: { - current = null; - - assert lengthOf(code, bci) == 1; - bci += 1; - break; - } - - case ATHROW: { - current = null; - if (canTrap != null) { - canTrap.set(bci); - } - - assert lengthOf(code, bci) == 1; - bci += 1; - break; - } - - case IFEQ: // fall through - case IFNE: // fall through - case IFLT: // fall through - case IFGE: // fall through - case IFGT: // fall through - case IFLE: // fall through - case IF_ICMPEQ: // fall through - case IF_ICMPNE: // fall through - case IF_ICMPLT: // fall through - case IF_ICMPGE: // fall through - case IF_ICMPGT: // fall through - case IF_ICMPLE: // fall through - case IF_ACMPEQ: // fall through - case IF_ACMPNE: // fall through - case IFNULL: // fall through - case IFNONNULL: { - current = null; - - double probability = GraalOptions.UseBranchPrediction ? method.branchProbability(bci) : -1; - - Block b1 = probability == 1.0 ? makeBranchOverrideBlock(bci, bci + 3, false) : makeBlock(bci + 3); - Block b2 = probability == 0.0 ? makeBranchOverrideBlock(bci, bci + Bytes.beS2(code, bci + 1), true) : makeBlock(bci + Bytes.beS2(code, bci + 1)); - setSuccessors(bci, b1, b2); - - assert lengthOf(code, bci) == 3; - bci += 3; - break; - } - - case GOTO: { - current = null; - Block b1 = makeBlock(bci + Bytes.beS2(code, bci + 1)); - setSuccessors(bci, b1); - - assert lengthOf(code, bci) == 3; - bci += 3; - break; - } - - case GOTO_W: { - current = null; - Block b1 = makeBlock(bci + Bytes.beS4(code, bci + 1)); - setSuccessors(bci, b1); - - assert lengthOf(code, bci) == 5; - bci += 5; - break; - } - - case TABLESWITCH: { - BytecodeTableSwitch sw = new BytecodeTableSwitch(code, bci); - setSuccessors(bci, makeSwitchSuccessors(sw)); - current = null; - - assert lengthOf(code, bci) == sw.size(); - bci += sw.size(); - break; - } - - case LOOKUPSWITCH: { - current = null; - BytecodeLookupSwitch sw = new BytecodeLookupSwitch(code, bci); - setSuccessors(bci, makeSwitchSuccessors(sw)); - - assert lengthOf(code, bci) == sw.size(); - bci += sw.size(); - break; - } - - case JSR: { - throw new JSRNotSupportedBailout(); - } - case JSR_W: { - throw new JSRNotSupportedBailout(); - } - case RET: { - throw new JSRNotSupportedBailout(); - } - - case WIDE: { - bci += lengthOf(code, bci); - break; - } - - default: { - if (canTrap != null && canTrap(opcode)) { - canTrap.set(bci); - } - - assert lengthOf(code, bci) == lengthOf(opcode); - bci += lengthOf(opcode); - } - } - } - } - - public static boolean canTrap(int opcode) { - switch (opcode) { - case INVOKESTATIC: - case INVOKESPECIAL: - case INVOKEVIRTUAL: - case INVOKEINTERFACE: { - return true; - } - } - return false; - } - - private Block makeBlock(int startBci) { - Block oldBlock = blockMap[startBci]; - if (oldBlock == null) { - Block newBlock = new Block(); - newBlock.startBci = startBci; - blockMap[startBci] = newBlock; - return newBlock; - - } else if (oldBlock.startBci != startBci) { - // Backward branch into the middle of an already processed block. - // Add the correct fall-through successor. - Block newBlock = new Block(); - newBlock.startBci = startBci; - newBlock.endBci = oldBlock.endBci; - newBlock.successors.addAll(oldBlock.successors); - - oldBlock.endBci = startBci - 1; - oldBlock.successors.clear(); - oldBlock.successors.add(newBlock); - - for (int i = startBci; i <= newBlock.endBci; i++) { - blockMap[i] = newBlock; - } - return newBlock; - - } else { - return oldBlock; - } - } - - private Block makeBranchOverrideBlock(int branchBci, int startBci, boolean taken) { - DeoptBlock newBlock = new DeoptBlock(); - newBlock.startBci = startBci; - BranchOverride override = new BranchOverride(); - override.block = newBlock; - override.taken = taken; - assert branchOverride.get(branchBci) == null; - branchOverride.put(branchBci, override); - return newBlock; - } - - private Block[] makeSwitchSuccessors(BytecodeSwitch tswitch) { - int max = tswitch.numberOfCases(); - Block[] successors = new Block[max + 1]; - for (int i = 0; i < max; i++) { - successors[i] = makeBlock(tswitch.targetAt(i)); - } - successors[max] = makeBlock(tswitch.defaultTarget()); - return successors; - } - - private void setSuccessors(int predBci, Block... successors) { - for (Block sux : successors) { - if (sux.isExceptionEntry) { - throw new CiBailout("Exception handler can be reached by both normal and exceptional control flow"); - } - } - Block predecessor = blockMap[predBci]; - assert predecessor.successors.size() == 0; - predecessor.successors.addAll(Arrays.asList(successors)); - } - - private HashMap exceptionDispatch = new HashMap(); - - private ExceptionBlock unwindBlock; - - private Block makeExceptionDispatch(List handlers, int index, int bci) { - RiExceptionHandler handler = handlers.get(index); - if (handler.isCatchAll()) { - return blockMap[handler.handlerBCI()]; - } - ExceptionBlock block = exceptionDispatch.get(handler); - if (block == null) { - block = new ExceptionBlock(); - block.startBci = -1; - block.endBci = -1; - block.deoptBci = bci; - block.handler = handler; - block.successors.add(blockMap[handler.handlerBCI()]); - if (index < handlers.size() - 1) { - block.next = makeExceptionDispatch(handlers, index + 1, bci); - block.successors.add(block.next); - } - exceptionDispatch.put(handler, block); - } - return block; - } - - private void addExceptionEdges() { - if (canTrap == null) { - return; - } - - for (int bci = canTrap.nextSetBit(0); bci >= 0; bci = canTrap.nextSetBit(bci + 1)) { - Block block = blockMap[bci]; - - ArrayList handlers = null; - for (RiExceptionHandler h : this.exceptionHandlers) { - if (h.startBCI() <= bci && bci < h.endBCI()) { - if (handlers == null) { - handlers = new ArrayList(); - } - handlers.add(h); - if (h.isCatchAll()) { - break; - } - } - } - if (handlers != null) { - Block dispatch = makeExceptionDispatch(handlers, 0, bci); - block.successors.add(dispatch); - } - } - } - - private void computeBlockOrder() { - long loop = computeBlockOrder(blockMap[0]); - - if (loop != 0) { - // There is a path from a loop end to the method entry that does not pass the loop header. - // Therefore, the loop is non reducible (has more than one entry). - // We don't want to compile such methods because the IR only supports structured loops. - throw new CiBailout("Non-reducible loop"); - } - - // Convert postorder to the desired reverse postorder. - Collections.reverse(blocks); - } - - /** - * The next available loop number. - */ - private int nextLoop; - - /** - * Mark the block as a loop header, using the next available loop number. - * Also checks for corner cases that we don't want to compile. - */ - private void makeLoopHeader(Block block) { - if (!block.isLoopHeader) { - block.isLoopHeader = true; - - if (block.isExceptionEntry) { - // Loops that are implicitly formed by an exception handler lead to all sorts of corner cases. - // Don't compile such methods for now, until we see a concrete case that allows checking for correctness. - throw new CiBailout("Loop formed by an exception handler"); - } - if (nextLoop >= Long.SIZE) { - // This restriction can be removed by using a fall-back to a BitSet in case we have more than 32 loops - // Don't compile such methods for now, until we see a concrete case that allows checking for correctness. - throw new CiBailout("Too many loops in method"); - } - - assert block.loops == 0; - block.loops = (long) 1 << (long) nextLoop; - nextLoop++; - } - assert Long.bitCount(block.loops) == 1; - } - - /** - * Depth-first traversal of the control flow graph. The flag {@linkplain Block#visited} is used to - * visit every block only once. The flag {@linkplain Block#active} is used to detect cycles (backward - * edges). - */ - private long computeBlockOrder(Block block) { - if (block.visited) { - if (block.active) { - // Reached block via backward branch. - makeLoopHeader(block); - } - // Return cached loop information for this block. - return block.loops; - } - - block.visited = true; - block.active = true; - - int loops = 0; - for (Block successor : block.successors) { - // Recursively process successors. - loops |= computeBlockOrder(successor); - } - - if (loops != 0) { - processLoopBlock(block); - } - if (block.isLoopHeader) { - assert Long.bitCount(block.loops) == 1; - loops &= ~block.loops; - } - - block.loops = loops; - block.active = false; - blocks.add(block); - - return loops; - } - - private void processLoopBlock(Block block) { - // process all the stores in this block - byte[] code = method.code(); - int bci = block.startBci; - if (bci >= 0) { - while (bci <= block.endBci) { - int opcode = Bytes.beU1(code, bci); - if (isStore(opcode)) { - processStore(opcode, Bytes.beU1(code, bci + 1)); - - } else if (opcode == WIDE) { - opcode = Bytes.beU1(code, bci + 1); - if (isStore(opcode)) { - processStore(opcode, Bytes.beU2(code, bci + 2)); - } - } - bci += lengthOf(code, bci); - } - } - } - - private void processStore(int opcode, int local) { - switch (opcode) { - case IINC: - case ISTORE: - case FSTORE: - case WSTORE: - case ASTORE: - storesInLoops.set(local); - break; - - case LSTORE: - case DSTORE: - storesInLoops.set(local); - storesInLoops.set(local + 1); - break; - - case ISTORE_0: - case FSTORE_0: - case ASTORE_0: - case WSTORE_0: - storesInLoops.set(0); - break; - case ISTORE_1: - case FSTORE_1: - case ASTORE_1: - case WSTORE_1: - storesInLoops.set(1); - break; - case ISTORE_2: - case FSTORE_2: - case ASTORE_2: - case WSTORE_2: - storesInLoops.set(2); - break; - case ISTORE_3: - case FSTORE_3: - case ASTORE_3: - case WSTORE_3: - storesInLoops.set(3); - break; - - case LSTORE_0: - case DSTORE_0: - storesInLoops.set(0); - storesInLoops.set(1); - break; - case LSTORE_1: - case DSTORE_1: - storesInLoops.set(1); - storesInLoops.set(2); - break; - case LSTORE_2: - case DSTORE_2: - storesInLoops.set(2); - storesInLoops.set(3); - break; - case LSTORE_3: - case DSTORE_3: - storesInLoops.set(3); - storesInLoops.set(4); - break; - - default: - throw new InternalError("undefined store bytecode"); - } - } - - - - /** - * Print block information in the format required by {@linkplain CFGPrinter}. The method must - * be here because it accesses private state of a block. - */ - public void printBlock(Block block, LogStream out) { - out.print("name \"B").print(block.startBci).println('"'); - out.print("from_bci ").println(block.startBci); - out.print("to_bci ").println(block.endBci); - - out.println("predecessors "); - - out.print("successors "); - for (Block succ : block.successors) { - if (!succ.isExceptionEntry) { - out.print("\"B").print(succ.startBci).print("\" "); - } - } - out.println(); - - out.print("xhandlers"); - for (Block succ : block.successors) { - if (succ.isExceptionEntry) { - out.print("\"B").print(succ.startBci).print("\" "); - } - } - out.println(); - - out.print("flags "); - if (block.isExceptionEntry) { - out.print("\"ex\" "); - } - if (block.isLoopHeader) { - out.print("\"plh\" "); - } - out.println(); - - out.print("loop_depth ").println(Long.bitCount(block.loops)); - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/graph/IR.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/graph/IR.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,295 +0,0 @@ -/* - * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.compiler.graph; - -import java.util.*; - -import com.oracle.max.graal.compiler.*; -import com.oracle.max.graal.compiler.alloc.*; -import com.oracle.max.graal.compiler.lir.*; -import com.oracle.max.graal.compiler.observer.*; -import com.oracle.max.graal.compiler.phases.*; -import com.oracle.max.graal.compiler.schedule.*; -import com.oracle.max.graal.extensions.*; -import com.oracle.max.graal.graph.*; -import com.oracle.max.graal.nodes.*; - -/** - * This class implements the overall container for the HIR (high-level IR) graph - * and directs its construction, optimization, and finalization. - */ -public class IR { - - /** - * The compilation associated with this IR. - */ - public final GraalCompilation compilation; - - /** - * The start block of this IR. - */ - public LIRBlock startBlock; - - /** - * The linear-scan ordered list of blocks. - */ - private List linearScanOrder; - - /** - * The order in which the code is emitted. - */ - private List codeEmittingOrder; - - /** - * Creates a new IR instance for the specified compilation. - * @param compilation the compilation - */ - public IR(GraalCompilation compilation) { - this.compilation = compilation; - } - - public Map valueToBlock; - - /** - * Builds the graph, optimizes it, and computes the linear scan block order. - */ - public void build() { - -// Object stored = GraphBuilderPhase.cachedGraphs.get(compilation.method); -// if (stored != null) { -// Map replacements = new HashMap(); -// CompilerGraph duplicate = (CompilerGraph) stored; -// replacements.put(duplicate.start(), compilation.graph.start()); -// compilation.graph.addDuplicate(duplicate.getNodes(), replacements); -// } else { - new GraphBuilderPhase(compilation, compilation.method, false).apply(compilation.graph); -// } - - Graph graph = compilation.graph; - - if (GraalOptions.TestGraphDuplication) { - new DuplicationPhase().apply(graph); - } - - new DeadCodeEliminationPhase().apply(graph); - - if (GraalOptions.ProbabilityAnalysis) { - new ComputeProbabilityPhase().apply(graph); - } - - if (GraalOptions.Inline) { - new InliningPhase(compilation, this, null).apply(graph); - } - - - if (GraalOptions.OptCanonicalizer) { - new CanonicalizerPhase().apply(graph); - new DeadCodeEliminationPhase().apply(graph); - } - - if (GraalOptions.Extend) { - extensionOptimizations(graph); - } - - if (GraalOptions.OptLoops) { - graph.mark(); - new LoopPhase().apply(graph); - if (GraalOptions.OptCanonicalizer) { - new CanonicalizerPhase(true).apply(graph); - new DeadCodeEliminationPhase().apply(graph); - } - } - - if (GraalOptions.EscapeAnalysis) { - new EscapeAnalysisPhase(compilation, this).apply(graph); - new CanonicalizerPhase().apply(graph); - new DeadCodeEliminationPhase().apply(graph); - } - - if (GraalOptions.OptGVN) { - graph.recordModifications(EdgeType.USAGES); // GVN 'ideals' will get new usages - new GlobalValueNumberingPhase().apply(graph); - if (GraalOptions.Rematerialize) { - //new Rematerialization2Phase().apply(graph); - //new RematerializationPhase().apply(graph); - } - graph.stopRecordModifications(); - } - - new LoweringPhase(compilation.runtime).apply(graph); - if (GraalOptions.Lower) { - new MemoryPhase().apply(graph); - if (GraalOptions.OptGVN) { - graph.recordModifications(EdgeType.USAGES); - new GlobalValueNumberingPhase().apply(graph); - if (GraalOptions.Rematerialize) { - //new RematerializationPhase().apply(graph); - } - graph.stopRecordModifications(); - } - if (GraalOptions.OptReadElimination) { - new ReadEliminationPhase().apply(graph); - } - } - - IdentifyBlocksPhase schedule = new IdentifyBlocksPhase(true); - schedule.apply(graph); - compilation.stats.loopCount = schedule.loopCount(); - - if (compilation.compiler.isObserved()) { - Map debug = new HashMap(); - debug.put("schedule", schedule); - compilation.compiler.fireCompilationEvent(new CompilationEvent(compilation, "After IdentifyBlocksPhase", graph, true, false, debug)); - } - - - List blocks = schedule.getBlocks(); - List lirBlocks = new ArrayList(); - Map map = new HashMap(); - for (Block b : blocks) { - LIRBlock block = new LIRBlock(b.blockID()); - map.put(b, block); - block.setInstructions(b.getInstructions()); - block.setLinearScanNumber(b.blockID()); - block.setLoopDepth(b.loopDepth()); - block.setLoopIndex(b.loopIndex()); - - if (b.isLoopEnd()) { - block.setLinearScanLoopEnd(); - } - - if (b.isLoopHeader()) { - block.setLinearScanLoopHeader(); - } - - block.setFirstInstruction(b.firstNode()); - block.setLastInstruction(b.lastNode()); - lirBlocks.add(block); - } - - for (Block b : blocks) { - for (Block succ : b.getSuccessors()) { - map.get(b).blockSuccessors().add(map.get(succ)); - } - - for (Block pred : b.getPredecessors()) { - map.get(b).blockPredecessors().add(map.get(pred)); - } - } - - valueToBlock = new HashMap(); - for (LIRBlock b : lirBlocks) { - for (Node i : b.getInstructions()) { - valueToBlock.put(i, b); - } - } - startBlock = valueToBlock.get(graph.start()); - assert startBlock != null; - assert startBlock.blockPredecessors().size() == 0; - - - if (GraalOptions.Time) { - GraalTimers.COMPUTE_LINEAR_SCAN_ORDER.start(); - } - - ComputeLinearScanOrder clso = new ComputeLinearScanOrder(lirBlocks.size(), compilation.stats.loopCount, startBlock); - linearScanOrder = clso.linearScanOrder(); - codeEmittingOrder = clso.codeEmittingOrder(); - - int z = 0; - for (LIRBlock b : linearScanOrder) { - b.setLinearScanNumber(z++); - } - - printGraph("After linear scan order", compilation.graph); - - if (GraalOptions.Time) { - GraalTimers.COMPUTE_LINEAR_SCAN_ORDER.stop(); - } - - } - - - - public static ThreadLocal> optimizerLoader = new ThreadLocal>(); - - private void extensionOptimizations(Graph graph) { - - ServiceLoader serviceLoader = optimizerLoader.get(); - if (serviceLoader == null) { - serviceLoader = ServiceLoader.load(Optimizer.class); - optimizerLoader.set(serviceLoader); - } - - for (Optimizer o : serviceLoader) { - o.optimize(compilation.runtime, graph); - } - } - - /** - * Gets the linear scan ordering of blocks as a list. - * @return the blocks in linear scan order - */ - public List linearScanOrder() { - return linearScanOrder; - } - - public List codeEmittingOrder() { - return codeEmittingOrder; - } - - public void printGraph(String phase, Graph graph) { - if (compilation.compiler.isObserved()) { - compilation.compiler.fireCompilationEvent(new CompilationEvent(compilation, phase, graph, true, false)); - } - } - - public int numLoops() { - return compilation.stats.loopCount; - } - - /** - * Gets the maximum number of locks in the graph's frame states. - */ - public final int maxLocks() { - int maxLocks = 0; - for (Node node : compilation.graph.getNodes()) { - if (node instanceof FrameState) { - FrameState current = (FrameState) node; - int lockCount = 0; - while (current != null) { - lockCount += current.locksSize(); - current = current.outerFrameState(); - } - if (lockCount > maxLocks) { - maxLocks = lockCount; - } - } - } - return maxLocks; - } - - public FixedWithNextNode getHIRStartBlock() { - return (FixedWithNextNode) compilation.graph.start().successors().first(); - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/graph/JSRNotSupportedBailout.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/graph/JSRNotSupportedBailout.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,34 +0,0 @@ -/* - * Copyright (c) 2011, 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.compiler.graph; - -import com.sun.cri.ci.*; - - -public class JSRNotSupportedBailout extends CiBailout{ - private static final long serialVersionUID = -7476925652727154272L; - - public JSRNotSupportedBailout() { - super("jsr/ret not supported"); - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/graph/MergeableState.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/graph/MergeableState.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,35 +0,0 @@ -/* - * Copyright (c) 2011, 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.compiler.graph; - -import java.util.*; - -import com.oracle.max.graal.nodes.*; - -public interface MergeableState { - T clone(); - boolean merge(MergeNode merge, Collection withStates); - void loopBegin(LoopBeginNode loopBegin); - void loopEnd(LoopEndNode loopEnd, T loopEndState); - void afterSplit(FixedNode node); -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/graph/PostOrderNodeIterator.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/graph/PostOrderNodeIterator.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,195 +0,0 @@ -/* - * Copyright (c) 2011, 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.compiler.graph; - -import java.util.*; - -import com.oracle.max.graal.graph.*; -import com.oracle.max.graal.graph.collections.*; -import com.oracle.max.graal.nodes.*; - -public abstract class PostOrderNodeIterator> { - - private final NodeBitMap visitedEnds; - private final Deque nodeQueue; - private final HashMap nodeStates; - private final FixedNode start; - - protected T state; - - public PostOrderNodeIterator(FixedNode start, T initialState) { - visitedEnds = start.graph().createNodeBitMap(); - nodeQueue = new ArrayDeque(); - nodeStates = new HashMap(); - this.start = start; - this.state = initialState; - } - - public void apply() { - FixedNode current = start; - - do { - if (current instanceof InvokeNode) { - invoke((InvokeNode) current); - queueSuccessors(current); - current = nextQueuedNode(); - } else if (current instanceof LoopBeginNode) { - state.loopBegin((LoopBeginNode) current); - nodeStates.put(current, state); - state = state.clone(); - loopBegin((LoopBeginNode) current); - current = ((LoopBeginNode) current).next(); - assert current != null; - } else if (current instanceof LoopEndNode) { - T loopBeginState = nodeStates.get(((LoopEndNode) current).loopBegin()); - if (loopBeginState != null) { - loopBeginState.loopEnd((LoopEndNode) current, state); - } - loopEnd((LoopEndNode) current); - current = nextQueuedNode(); - } else if (current instanceof MergeNode) { - merge((MergeNode) current); - current = ((MergeNode) current).next(); - assert current != null; - } else if (current instanceof FixedWithNextNode) { - FixedNode next = ((FixedWithNextNode) current).next(); - node(current); - current = next; - assert current != null; - } else if (current instanceof EndNode) { - end((EndNode) current); - queueMerge((EndNode) current); - current = nextQueuedNode(); - } else if (current instanceof DeoptimizeNode) { - deoptimize((DeoptimizeNode) current); - current = nextQueuedNode(); - } else if (current instanceof ReturnNode) { - returnNode((ReturnNode) current); - current = nextQueuedNode(); - } else if (current instanceof UnwindNode) { - unwind((UnwindNode) current); - current = nextQueuedNode(); - } else if (current instanceof ControlSplitNode) { - controlSplit((ControlSplitNode) current); - queueSuccessors(current); - current = nextQueuedNode(); - } else { - assert false : current.shortName(); - } - } while(current != null); - } - - private void queueSuccessors(FixedNode x) { - nodeStates.put(x, state); - for (Node node : x.successors()) { - if (node != null) { - nodeQueue.addFirst((FixedNode) node); - } - } - } - - private FixedNode nextQueuedNode() { - int maxIterations = nodeQueue.size(); - while (maxIterations-- > 0) { - FixedNode node = nodeQueue.removeFirst(); - if (node instanceof MergeNode) { - MergeNode merge = (MergeNode) node; - state = nodeStates.get(merge.endAt(0)).clone(); - ArrayList states = new ArrayList(merge.endCount() - 1); - for (int i = 1; i < merge.endCount(); i++) { - T other = nodeStates.get(merge.endAt(i)); - assert other != null; - states.add(other); - } - boolean ready = state.merge(merge, states); - if (ready) { - return merge; - } else { - nodeQueue.addLast(merge); - } - } else { - assert node.predecessor() != null; - state = nodeStates.get(node.predecessor()).clone(); - state.afterSplit(node); - return node; - } - } - return null; - } - - private void queueMerge(EndNode end) { - assert !visitedEnds.isMarked(end); - assert !nodeStates.containsKey(end); - nodeStates.put(end, state); - visitedEnds.mark(end); - MergeNode merge = end.merge(); - boolean endsVisited = true; - for (int i = 0; i < merge.endCount(); i++) { - if (!visitedEnds.isMarked(merge.endAt(i))) { - endsVisited = false; - break; - } - } - if (endsVisited) { - nodeQueue.add(merge); - } - } - - protected abstract void node(FixedNode node); - - protected void end(EndNode endNode) { - node(endNode); - } - - protected void merge(MergeNode merge) { - node(merge); - } - - protected void loopBegin(LoopBeginNode loopBegin) { - node(loopBegin); - } - - protected void loopEnd(LoopEndNode loopEnd) { - node(loopEnd); - } - - protected void deoptimize(DeoptimizeNode deoptimize) { - node(deoptimize); - } - - protected void controlSplit(ControlSplitNode controlSplit) { - node(controlSplit); - } - - protected void returnNode(ReturnNode returnNode) { - node(returnNode); - } - - protected void invoke(InvokeNode invoke) { - node(invoke); - } - - protected void unwind(UnwindNode unwind) { - node(unwind); - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/graph/package-info.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/graph/package-info.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,31 +0,0 @@ -/* - * Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -/** - *

IR Graph building

- * - * The {@link com.oracle.max.graal.compiler.graph.IR} class drives the generation of the HIR graph for a method, making use of other - * utility classes in this package. - * - */ -package com.oracle.max.graal.compiler.graph; diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/FrameMap.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/FrameMap.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,390 +0,0 @@ -/* - * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.compiler.lir; - -import static com.sun.cri.ci.CiCallingConvention.Type.*; -import static com.sun.cri.ci.CiKind.*; -import static java.lang.reflect.Modifier.*; - -import com.oracle.max.graal.compiler.*; -import com.oracle.max.graal.compiler.globalstub.*; -import com.oracle.max.graal.compiler.util.*; -import com.sun.cri.bytecode.*; -import com.sun.cri.ci.*; -import com.sun.cri.ci.CiCallingConvention.Type; -import com.sun.cri.ri.*; - -/** - * This class is used to build the stack frame layout for a compiled method. - * - * This is the format of a stack frame on an x86 (i.e. IA32 or X64) platform: - *
- *   Base       Contents
- *
- *          :                                :
- *          | incoming overflow argument n   |
- *          |     ...                        |
- *          | incoming overflow argument 0   |
- *          | return address                 | Caller frame
- *   -------+--------------------------------+----------------  ---
- *          |                                |                   ^
- *          : callee save area               :                   |
- *          |                                |                   |
- *          +--------------------------------+                   |
- *          | alignment padding              |                   |
- *          +--------------------------------+                   |
- *          | ALLOCA block n                 |                   |
- *          :     ...                        :                   |
- *          | ALLOCA block 0                 | Current frame     |
- *          +--------------------------------+                   |
- *          | monitor n                      |                   |
- *          :     ...                        :                   |
- *          | monitor 0                      |                   |
- *          +--------------------------------+    ---            |
- *          | spill slot n                   |     ^           frame
- *          :     ...                        :     |           size
- *          | spill slot 0                   |  shared           |
- *          +- - - - - - - - - - - - - - - - +   slot            |
- *          | outgoing overflow argument n   |  indexes          |
- *          |     ...                        |     |             |
- *    %sp   | outgoing overflow argument 0   |     v             v
- *   -------+--------------------------------+----------------  ---
- *
- * 
- * Note that the size {@link Bytecodes#ALLOCA ALLOCA} blocks and {@code monitor}s in the frame may be greater - * than the size of a {@linkplain CiTarget#spillSlotSize spill slot}. - */ -public final class FrameMap { - - private final GraalCompilation compilation; - private final CiCallingConvention incomingArguments; - - /** - * Number of monitors used in this frame. - */ - private final int monitorCount; - - /** - * The final frame size. - * Value is only set after register allocation is complete. - */ - private int frameSize; - - /** - * The number of spill slots allocated by the register allocator. - * The value {@code -2} means that the size of outgoing argument stack slots - * is not yet fixed. The value {@code -1} means that the register - * allocator has started allocating spill slots and so the size of - * outgoing stack slots cannot change as outgoing stack slots and - * spill slots share the same slot index address space. - */ - private int spillSlotCount; - - /** - * The amount of memory allocated within the frame for uses of {@link Bytecodes#ALLOCA}. - */ - private int stackBlocksSize; - - /** - * Area occupied by outgoing overflow arguments. - * This value is adjusted as calling conventions for outgoing calls are retrieved. - */ - private int outgoingSize; - - /** - * Creates a new frame map for the specified method. - * - * @param compilation the compilation context - * @param method the outermost method being compiled - * @param monitors the number of monitors allocated on the stack for this method - */ - public FrameMap(GraalCompilation compilation, RiMethod method, int monitors) { - this.compilation = compilation; - this.frameSize = -1; - this.spillSlotCount = -2; - - assert monitors >= 0 : "not set"; - monitorCount = monitors; - if (method == null) { - incomingArguments = new CiCallingConvention(new CiValue[0], 0); - } else { - CiKind receiver = !isStatic(method.accessFlags()) ? method.holder().kind() : null; - incomingArguments = getCallingConvention(CiUtil.signatureToKinds(method.signature(), receiver), JavaCallee); - } - } - - /** - * Gets the calling convention for a call with the specified signature. - * - * @param type the type of calling convention being requested - * @param signature the signature of the arguments - * @return a {@link CiCallingConvention} instance describing the location of parameters and the return value - */ - public CiCallingConvention getCallingConvention(CiKind[] signature, Type type) { - CiCallingConvention cc = compilation.registerConfig.getCallingConvention(type, signature, compilation.target, false); - if (type == RuntimeCall) { - assert cc.stackSize == 0 : "runtime call should not have stack arguments"; - } else if (type.out) { - assert frameSize == -1 : "frame size must not yet be fixed!"; - reserveOutgoing(cc.stackSize); - } - return cc; - } - - /** - * Gets the calling convention for the incoming arguments to the compiled method. - * @return the calling convention for incoming arguments - */ - public CiCallingConvention incomingArguments() { - return incomingArguments; - } - - /** - * Gets the frame size of the compiled frame. - * @return the size in bytes of the frame - */ - public int frameSize() { - assert this.frameSize != -1 : "frame size not computed yet"; - return frameSize; - } - - /** - * Sets the frame size for this frame. - * @param frameSize the frame size in bytes - */ - public void setFrameSize(int frameSize) { - assert this.frameSize == -1 : "should only be calculated once"; - this.frameSize = frameSize; - } - - /** - * Computes the frame size for this frame, given the number of spill slots. - * @param spillSlotCount the number of spill slots - */ - public void finalizeFrame(int spillSlotCount) { - assert this.spillSlotCount == -1 : "can only be set once"; - assert this.frameSize == -1 : "should only be calculated once"; - assert spillSlotCount >= 0 : "must be positive"; - - this.spillSlotCount = spillSlotCount; - int frameSize = offsetToStackBlocksEnd(); - frameSize += compilation.registerConfig.getCalleeSaveLayout().size; - this.frameSize = compilation.target.alignFrameSize(frameSize); - } - - /** - * Informs the frame map that the compiled code uses a particular global stub, which - * may need stack space for outgoing arguments. - * - * @param stub the global stub - */ - public void usesGlobalStub(GlobalStub stub) { - reserveOutgoing(stub.argsSize); - } - - /** - * Converts a stack slot into a stack address. - * - * @param slot a stack slot - * @return a stack address - */ - public CiAddress toStackAddress(CiStackSlot slot) { - int size = compilation.target.sizeInBytes(slot.kind); - if (slot.inCallerFrame()) { - int offset = slot.index() * compilation.target.spillSlotSize + frameSize() + 8; - return new CiAddress(slot.kind, CiRegister.Frame.asValue(), offset); - } else { - int offset = offsetForOutgoingOrSpillSlot(slot.index(), size); - return new CiAddress(slot.kind, CiRegister.Frame.asValue(), offset); - } - } - - /** - * Gets the stack address within this frame for a given reserved stack block. - * - * @param stackBlock the value returned from {@link #reserveStackBlock(int)} identifying the stack block - * @return a representation of the stack location - */ - public CiAddress toStackAddress(StackBlock stackBlock) { - return new CiAddress(CiKind.Word, compilation.registerConfig.getFrameRegister().asValue(Word), offsetForStackBlock(stackBlock)); - } - - /** - * Converts the monitor index into the stack address of the object reference in the on-stack monitor. - * - * @param monitorIndex the monitor index - * @return a representation of the stack address - */ - public CiStackSlot toMonitorObjectStackAddress(int monitorIndex) { - int byteIndex = offsetForMonitorObject(monitorIndex); - assert byteIndex % compilation.target.wordSize == 0; - return CiStackSlot.get(CiKind.Object, byteIndex / compilation.target.wordSize); - } - - /** - * Converts the monitor index into the stack address of the on-stak monitor. - * - * @param monitorIndex the monitor index - * @return a representation of the stack address - */ - public CiStackSlot toMonitorBaseStackAddress(int monitorIndex) { - int byteIndex = offsetForMonitorBase(monitorIndex); - assert byteIndex % compilation.target.wordSize == 0; - return CiStackSlot.get(CiKind.Object, byteIndex / compilation.target.wordSize); - } - - /** - * Reserves space for stack-based outgoing arguments. - * - * @param argsSize the amount of space to reserve for stack-based outgoing arguments - */ - public void reserveOutgoing(int argsSize) { - assert spillSlotCount == -2 : "cannot reserve outgoing stack slot space once register allocation has started"; - if (argsSize > outgoingSize) { - outgoingSize = Util.roundUp(argsSize, compilation.target.spillSlotSize); - } - } - - /** - * Encapsulates the details of a stack block reserved by a call to {@link FrameMap#reserveStackBlock(int)}. - */ - public static final class StackBlock { - /** - * The size of this stack block. - */ - public final int size; - - /** - * The offset of this stack block within the frame space reserved for stack blocks. - */ - public final int offset; - - public StackBlock(int size, int offset) { - this.size = size; - this.offset = offset; - } - } - - /** - * Reserves a block of memory in the frame of the method being compiled. - * - * @param size the number of bytes to reserve - * @return a descriptor of the reserved block that can be used with {@link #toStackAddress(StackBlock)} once register - * allocation is complete and the size of the frame has been {@linkplain #finalizeFrame(int) finalized}. - */ - public StackBlock reserveStackBlock(int size) { - int wordSize = compilation.target.sizeInBytes(CiKind.Word); - assert (size % wordSize) == 0; - StackBlock block = new StackBlock(size, stackBlocksSize); - stackBlocksSize += size; - return block; - } - - private int offsetForStackBlock(StackBlock stackBlock) { - assert stackBlock.offset >= 0 && stackBlock.offset + stackBlock.size <= stackBlocksSize : "invalid stack block"; - int offset = offsetToStackBlocks() + stackBlock.offset; - assert offset <= (frameSize() - stackBlock.size) : "spill outside of frame"; - return offset; - } - - /** - * Gets the stack pointer offset for a outgoing stack argument or compiler spill slot. - * - * @param slotIndex the index of the stack slot within the slot index space reserved for - * @param size - * @return - */ - private int offsetForOutgoingOrSpillSlot(int slotIndex, int size) { - assert slotIndex >= 0 && slotIndex < (initialSpillSlot() + spillSlotCount) : "invalid spill slot"; - int offset = slotIndex * compilation.target.spillSlotSize; - assert offset <= (frameSize() - size) : "slot outside of frame"; - return offset; - } - - private int offsetForMonitorBase(int index) { - assert index >= 0 && index < monitorCount : "invalid monitor index : " + index + " (monitorCount=" + monitorCount + ")"; - int size = compilation.runtime.sizeOfBasicObjectLock(); - assert size != 0 : "monitors are not on the stack in this VM"; - int offset = offsetToMonitors() + index * size; - assert offset <= (frameSize() - size) : "monitor outside of frame"; - return offset; - } - - private int offsetToSpillArea() { - return outgoingSize; - } - - private int offsetToSpillEnd() { - return offsetToSpillArea() + spillSlotCount * compilation.target.spillSlotSize; - } - - private int offsetToMonitors() { - return offsetToCustomArea() + customAreaSize(); - } - - public int customAreaSize() { - return compilation.runtime.getCustomStackAreaSize(); - } - - public int offsetToCustomArea() { - return offsetToSpillEnd(); - } - - private int offsetToMonitorsEnd() { - return offsetToMonitors() + (monitorCount * compilation.runtime.sizeOfBasicObjectLock()); - } - - private int offsetToStackBlocks() { - return offsetToMonitorsEnd(); - } - - private int offsetToStackBlocksEnd() { - return offsetToStackBlocks() + stackBlocksSize; - } - - public int offsetToCalleeSaveAreaStart() { - return offsetToCalleeSaveAreaEnd() - compilation.registerConfig.getCalleeSaveLayout().size; - } - - public int offsetToCalleeSaveAreaEnd() { - return frameSize; - } - - private int offsetForMonitorObject(int index) { - return offsetForMonitorBase(index) + compilation.runtime.basicObjectLockOffsetInBytes(); - } - - /** - * Gets the index of the first available spill slot relative to the base of the frame. - * After this call, no further outgoing stack slots can be {@linkplain #reserveOutgoing(int) reserved}. - * - * @return the index of the first available spill slot - */ - public int initialSpillSlot() { - if (spillSlotCount == -2) { - spillSlotCount = -1; - } - return outgoingSize / compilation.target.spillSlotSize; - } - -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/LIRAssembler.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/LIRAssembler.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,490 +0,0 @@ -/* - * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.compiler.lir; - -import java.util.*; - -import com.oracle.max.asm.*; -import com.oracle.max.graal.compiler.*; -import com.oracle.max.graal.compiler.asm.*; -import com.oracle.max.graal.compiler.debug.*; -import com.oracle.max.graal.compiler.gen.*; -import com.oracle.max.graal.compiler.lir.FrameMap.StackBlock; -import com.oracle.max.graal.compiler.util.*; -import com.oracle.max.graal.nodes.calc.*; -import com.sun.cri.ci.*; -import com.sun.cri.ci.CiTargetMethod.Mark; -import com.sun.cri.ri.*; -import com.sun.cri.xir.CiXirAssembler.XirMark; - -/** - * The {@code LIRAssembler} class definition. - */ -public abstract class LIRAssembler { - - public final GraalCompilation compilation; - public final TargetMethodAssembler tasm; - public final AbstractAssembler asm; - public final FrameMap frameMap; - public int registerRestoreEpilogueOffset = -1; - - protected final List xirSlowPath; - - private int lastDecodeStart; - - protected static class SlowPath { - public final LIRXirInstruction instruction; - public final Label[] labels; - public final Map marks; - - public SlowPath(LIRXirInstruction instruction, Label[] labels, Map marks) { - this.instruction = instruction; - this.labels = labels; - this.marks = marks; - } - } - - public LIRAssembler(GraalCompilation compilation) { - this.compilation = compilation; - this.tasm = compilation.assembler(); - this.asm = tasm.asm; - this.frameMap = compilation.frameMap(); - this.xirSlowPath = new ArrayList(); - } - - protected RiMethod method() { - return compilation.method; - } - - protected void addSlowPath(SlowPath sp) { - xirSlowPath.add(sp); - } - - public void emitLocalStubs() { - for (SlowPath sp : xirSlowPath) { - emitSlowPath(sp); - } - - // No more code may be emitted after this point - } - - protected int codePos() { - return asm.codeBuffer.position(); - } - - public abstract void emitTraps(); - - public void emitCode(List hir) { - if (GraalOptions.PrintLIR && !TTY.isSuppressed()) { - LIRList.printLIR(hir); - } - - for (LIRBlock b : hir) { - emitBlock(b); - } - - assert checkNoUnboundLabels(); - } - - void emitBlock(LIRBlock block) { - - if (block.align()) { - emitAlignment(); - } - - block.setBlockEntryPco(codePos()); - - if (GraalOptions.PrintLIRWithAssembly) { - block.printWithoutPhis(TTY.out()); - } - - assert block.lir() != null : "must have LIR"; - if (GraalOptions.CommentedAssembly) { - String st = String.format(" block B%d", block.blockID()); - tasm.blockComment(st); - } - - emitLirList(block.lir()); - } - - void emitLirList(LIRList list) { - doPeephole(list); - - for (LIRInstruction op : list.instructionsList()) { - if (GraalOptions.CommentedAssembly) { - // Only print out branches - if (op.code == LIROpcode.Branch) { - tasm.blockComment(op.toStringWithIdPrefix()); - } - } - if (GraalOptions.PrintLIRWithAssembly && !TTY.isSuppressed()) { - // print out the LIR operation followed by the resulting assembly - TTY.println(op.toStringWithIdPrefix()); - TTY.println(); - } - - op.emitCode(this); - - if (GraalOptions.PrintLIRWithAssembly) { - printAssembly(asm); - } - } - } - - private void printAssembly(AbstractAssembler asm) { - byte[] currentBytes = asm.codeBuffer.copyData(lastDecodeStart, asm.codeBuffer.position()); - if (currentBytes.length > 0) { - String disasm = compilation.runtime.disassemble(currentBytes, lastDecodeStart); - if (disasm.length() != 0) { - TTY.println(disasm); - } else { - TTY.println("Code [+%d]: %d bytes", lastDecodeStart, currentBytes.length); - Util.printBytes(lastDecodeStart, currentBytes, GraalOptions.PrintAssemblyBytesPerLine); - } - } - lastDecodeStart = asm.codeBuffer.position(); - } - - boolean checkNoUnboundLabels() { -// for (int i = 0; i < branchTargetBlocks.size() - 1; i++) { -// if (!branchTargetBlocks.get(i).label().isBound()) { -// TTY.println(String.format("label of block B%d is not bound", branchTargetBlocks.get(i).blockID())); -// assert false : "unbound label"; -// } -// } - - return true; - } - - void emitCall(LIRCall op) { - verifyOopMap(op.info); - - switch (op.code) { - case DirectCall: - emitCallAlignment(op.code); - // fall through - case ConstDirectCall: - if (op.marks != null) { - op.marks.put(XirMark.CALLSITE, tasm.recordMark(null, new Mark[0])); - } - emitDirectCall(op.target, op.info); - break; - case IndirectCall: - emitCallAlignment(op.code); - if (op.marks != null) { - op.marks.put(XirMark.CALLSITE, tasm.recordMark(null, new Mark[0])); - } - emitIndirectCall(op.target, op.info, op.targetAddress()); - break; - case NativeCall: { - emitNativeCall((String) op.target, op.info, op.targetAddress()); - break; - } - case TemplateCall: { - emitTemplateCall(op.targetAddress()); - break; - } - default: - throw Util.shouldNotReachHere(); - } - } - - void emitOpLabel(LIRLabel op) { - asm.bind(op.label()); - } - - void emitOp1(LIROp1 op) { - switch (op.code) { - case Move: - assert !op.operand().isIllegal(); - if (op.moveKind() == LIROp1.LIRMoveKind.Volatile) { - emitVolatileMove(op.operand(), op.result(), op.kind, op.info); - } else { - moveOp(op.operand(), op.result(), op.kind, op.info, op.moveKind() == LIROp1.LIRMoveKind.Unaligned); - } - break; - case Prefetchr: - emitReadPrefetch(op.operand()); - break; - case Prefetchw: - emitReadPrefetch(op.operand()); - break; - case Return: - emitReturn(op.operand()); - break; - case Neg: - emitNegate((LIRNegate) op); - break; - case Lea: - emitLea(op.operand(), op.result()); - break; - case NullCheck: - emitNullCheck(op.operand(), op.info); - break; - case Lsb: - emitSignificantBitOp(false, op.operand(), op.result()); - break; - case Msb: - emitSignificantBitOp(true, op.operand(), op.result()); - break; - default: - throw Util.shouldNotReachHere(); - } - } - - public void emitOp0(LIROp0 op) { - switch (op.code) { - case Label: - throw Util.shouldNotReachHere(); - case Breakpoint: - emitBreakpoint(); - break; - default: - throw Util.shouldNotReachHere(); - } - } - - protected void emitOp2(LIROp2 op) { - switch (op.code) { - case Cmp: - emitCompare(op.condition(), op.operand1(), op.operand2(), op); - break; - - case Cmpl2i: - case Cmpfd2i: - case Ucmpfd2i: - emitCompare2Int(op.code, op.operand1(), op.operand2(), op.result(), op); - break; - - case FCmove: - emitConditionalMove(op.condition(), op.operand1(), op.operand2(), op.result(), true, false); - break; - case UFCmove: - emitConditionalMove(op.condition(), op.operand1(), op.operand2(), op.result(), true, true); - break; - case Cmove: - emitConditionalMove(op.condition(), op.operand1(), op.operand2(), op.result(), false, false); - break; - - case Shl: - case Shr: - case Ushr: - if (op.operand2().isConstant()) { - emitShiftOp(op.code, op.operand1(), ((CiConstant) op.operand2()).asInt(), op.result()); - } else { - emitShiftOp(op.code, op.operand1(), op.operand2(), op.result(), op.tmp()); - } - break; - - case Add: - case Sub: - case Mul: - case Div: - case Rem: - emitArithOp(op.code, op.operand1(), op.operand2(), op.result(), op.info); - break; - - case Abs: - case Sqrt: - case Sin: - case Tan: - case Cos: - case Log: - case Log10: - emitIntrinsicOp(op.code, op.operand1(), op.operand2(), op.result(), op); - break; - - case LogicAnd: - case LogicOr: - case LogicXor: - emitLogicOp(op.code, op.operand1(), op.operand2(), op.result()); - break; - - default: - throw Util.shouldNotReachHere(); - } - } - - public void moveOp(CiValue src, CiValue dest, CiKind kind, LIRDebugInfo info, boolean unaligned) { - if (src.isRegister()) { - if (dest.isRegister()) { - assert info == null : "no patching and info allowed here"; - reg2reg(src, dest); - } else if (dest.isStackSlot()) { - assert info == null : "no patching and info allowed here"; - reg2stack(src, dest, kind); - } else if (dest.isAddress()) { - reg2mem(src, dest, kind, info, unaligned); - } else { - throw Util.shouldNotReachHere(); - } - - } else if (src.isStackSlot()) { - assert info == null : "no patching and info allowed here"; - if (dest.isRegister()) { - stack2reg(src, dest, kind); - } else if (dest.isStackSlot()) { - stack2stack(src, dest, kind); - } else { - throw Util.shouldNotReachHere(); - } - - } else if (src.isConstant()) { - if (dest.isRegister()) { - const2reg(src, dest, info); // patching is possible - } else if (dest.isStackSlot()) { - assert info == null : "no patching and info allowed here"; - const2stack(src, dest); - } else if (dest.isAddress()) { - const2mem(src, dest, kind, info); - } else { - throw Util.shouldNotReachHere(); - } - - } else if (src.isAddress()) { - if (dest.isStackSlot()) { - assert info == null && !unaligned; - mem2stack(src, dest, kind); - } else if (dest.isAddress()) { - assert info == null && !unaligned; - mem2mem(src, dest, kind); - } else { - mem2reg(src, dest, kind, info, unaligned); - } - - } else { - throw Util.shouldNotReachHere(src.toString() + ", dest=" + dest.toString() + ", " + kind); - } - } - - public void verifyOopMap(LIRDebugInfo info) { - if (GraalOptions.VerifyPointerMaps) { - // TODO: verify oops - Util.shouldNotReachHere(); - } - } - - protected abstract int initialFrameSizeInBytes(); - - protected abstract void doPeephole(LIRList list); - - protected abstract void emitSlowPath(SlowPath sp); - - public abstract void emitDeoptizationStub(LIRGenerator.DeoptimizationStub stub); - - protected abstract void emitAlignment(); - - protected abstract void emitBreakpoint(); - - protected abstract void emitLea(CiValue src, CiValue dst); - - protected abstract void emitNullCheck(CiValue src, LIRDebugInfo info); - - protected abstract void emitNegate(LIRNegate negate); - - protected abstract void emitMonitorAddress(int monitor, CiValue dst); - - protected abstract void emitStackAllocate(StackBlock src, CiValue dst); - - protected abstract void emitReturn(CiValue inOpr); - - protected abstract void emitReadPrefetch(CiValue inOpr); - - protected abstract void emitVolatileMove(CiValue inOpr, CiValue result, CiKind kind, LIRDebugInfo info); - - protected abstract void emitLogicOp(LIROpcode code, CiValue inOpr1, CiValue inOpr2, CiValue dst); - - protected abstract void emitIntrinsicOp(LIROpcode code, CiValue inOpr1, CiValue inOpr2, CiValue dst, LIROp2 op); - - protected abstract void emitArithOp(LIROpcode code, CiValue inOpr1, CiValue inOpr2, CiValue dst, LIRDebugInfo info); - - protected abstract void emitShiftOp(LIROpcode code, CiValue inOpr1, CiValue inOpr2, CiValue dst, CiValue tmpOpr); - - protected abstract void emitShiftOp(LIROpcode code, CiValue inOpr1, int asJint, CiValue dst); - - protected abstract void emitSignificantBitOp(boolean most, CiValue inOpr1, CiValue dst); - - protected abstract void emitConditionalMove(Condition condition, CiValue inOpr1, CiValue inOpr2, CiValue dst, boolean mayBeUnordered, boolean unorderedcmovOpr1); - - protected abstract void emitCompare2Int(LIROpcode code, CiValue inOpr1, CiValue inOpr2, CiValue dst, LIROp2 op); - - protected abstract void emitCompare(Condition condition, CiValue inOpr1, CiValue inOpr2, LIROp2 op); - - protected abstract void emitBranch(LIRBranch branch); - - protected abstract void emitTableSwitch(LIRTableSwitch tableSwitch); - - protected abstract void emitConvert(LIRConvert convert); - - protected abstract void emitOp3(LIROp3 op3); - - protected abstract void emitCompareAndSwap(LIRCompareAndSwap compareAndSwap); - - protected abstract void emitXir(LIRXirInstruction xirInstruction); - - protected abstract void emitIndirectCall(Object target, LIRDebugInfo info, CiValue callAddress); - - protected abstract void emitDirectCall(Object target, LIRDebugInfo info); - - protected abstract void emitNativeCall(String symbol, LIRDebugInfo info, CiValue callAddress); - - protected abstract void emitTemplateCall(CiValue address); - - protected abstract void emitCallAlignment(LIROpcode code); - - protected abstract void emitMemoryBarriers(int barriers); - - protected abstract void reg2stack(CiValue src, CiValue dest, CiKind kind); - - protected abstract void reg2mem(CiValue src, CiValue dest, CiKind kind, LIRDebugInfo info, boolean unaligned); - - protected abstract void mem2reg(CiValue src, CiValue dest, CiKind kind, LIRDebugInfo info, boolean unaligned); - - protected abstract void const2mem(CiValue src, CiValue dest, CiKind kind, LIRDebugInfo info); - - protected abstract void const2stack(CiValue src, CiValue dest); - - protected abstract void const2reg(CiValue src, CiValue dest, LIRDebugInfo info); - - protected abstract void mem2stack(CiValue src, CiValue dest, CiKind kind); - - protected abstract void mem2mem(CiValue src, CiValue dest, CiKind kind); - - protected abstract void stack2stack(CiValue src, CiValue dest, CiKind kind); - - protected abstract void stack2reg(CiValue src, CiValue dest, CiKind kind); - - protected abstract void reg2reg(CiValue src, CiValue dest); - - protected abstract boolean trueOnUnordered(Condition condition); - - protected abstract boolean falseOnUnordered(Condition condition); - - protected boolean mayBeTrueOnUnordered(Condition condition) { - return trueOnUnordered(condition) || !falseOnUnordered(condition); - } - - protected boolean mayBeFalseOnUnordered(Condition condition) { - return falseOnUnordered(condition) || !trueOnUnordered(condition); - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/LIRBlock.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/LIRBlock.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,300 +0,0 @@ -/* - * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.compiler.lir; - -import java.util.*; - -import com.oracle.max.asm.*; -import com.oracle.max.graal.compiler.alloc.*; -import com.oracle.max.graal.compiler.debug.*; -import com.oracle.max.graal.compiler.util.*; -import com.oracle.max.graal.graph.*; -import com.oracle.max.graal.nodes.*; -import com.oracle.max.graal.nodes.java.*; - -/** - * The {@code LIRBlock} class definition. - */ -public final class LIRBlock { - - public final Label label; - private LIRList lir; - private final int blockID; - private FrameState lastState; - private List instructions = new ArrayList(4); - private List predecessors = new ArrayList(4); - private List successors = new ArrayList(4); - private LIRDebugInfo debugInfo; - private boolean align; - - /** - * Bit map specifying which {@linkplain OperandPool operands} are live upon entry to this block. - * These are values used in this block or any of its successors where such value are not defined - * in this block. - * The bit index of an operand is its {@linkplain OperandPool#operandNumber(com.sun.cri.ci.CiValue) operand number}. - */ - public BitMap liveIn; - - /** - * Bit map specifying which {@linkplain OperandPool operands} are live upon exit from this block. - * These are values used in a successor block that are either defined in this block or were live - * upon entry to this block. - * The bit index of an operand is its {@linkplain OperandPool#operandNumber(com.sun.cri.ci.CiValue) operand number}. - */ - public BitMap liveOut; - - /** - * Bit map specifying which {@linkplain OperandPool operands} are used (before being defined) in this block. - * That is, these are the values that are live upon entry to the block. - * The bit index of an operand is its {@linkplain OperandPool#operandNumber(com.sun.cri.ci.CiValue) operand number}. - */ - public BitMap liveGen; - - /** - * Bit map specifying which {@linkplain OperandPool operands} are defined/overwritten in this block. - * The bit index of an operand is its {@linkplain OperandPool#operandNumber(com.sun.cri.ci.CiValue) operand number}. - */ - public BitMap liveKill; - - private int firstLirInstructionID; - private int lastLirInstructionID; - public int blockEntryPco; - - public LIRBlock(Label label, LIRDebugInfo debugInfo) { - this.label = label; - blockID = -1; - this.debugInfo = debugInfo; - } - - public LIRDebugInfo debugInfo() { - return this.debugInfo; - } - - public LIRBlock(int blockID) { - this.blockID = blockID; - label = new Label(); - loopIndex = -1; - linearScanNumber = blockID; - instructions = new ArrayList(4); - predecessors = new ArrayList(4); - successors = new ArrayList(4); - } - - public List getInstructions() { - return instructions; - } - - public int firstLirInstructionId() { - return firstLirInstructionID; - } - - public boolean align() { - return align; - } - - public void setAlign(boolean b) { - align = b; - } - - public void setFirstLirInstructionId(int firstLirInstructionId) { - this.firstLirInstructionID = firstLirInstructionId; - } - - public int lastLirInstructionId() { - return lastLirInstructionID; - } - - public void setLastLirInstructionId(int lastLirInstructionId) { - this.lastLirInstructionID = lastLirInstructionId; - } - - public int loopDepth; - - public LIRList lir() { - return lir; - } - - public void setLir(LIRList lir) { - this.lir = lir; - } - - public void setBlockEntryPco(int codePos) { - this.blockEntryPco = codePos; - } - - public void printWithoutPhis(LogStream out) { - out.println("LIR Block " + blockID()); - } - - public int blockID() { - return blockID; - } - - public int numberOfPreds() { - return predecessors.size(); - } - - public int numberOfSux() { - return successors.size(); - } - - public boolean isPredecessor(LIRBlock block) { - return predecessors.contains(block); - } - - public LIRBlock predAt(int i) { - return predecessors.get(i); - } - - public LIRBlock suxAt(int i) { - return successors.get(i); - } - - public List blockSuccessors() { - return successors; - } - - @Override - public String toString() { - return "B" + blockID(); - } - - public List blockPredecessors() { - return predecessors; - } - - public int loopDepth() { - return loopDepth; - } - - public int loopIndex() { - return loopIndex; - } - - public void setLoopIndex(int v) { - loopIndex = v; - } - - public void setLoopDepth(int v) { - this.loopDepth = v; - } - - private int loopIndex; - - public Label label() { - return label; - } - - private int linearScanNumber = -1; - private boolean linearScanLoopEnd; - private boolean linearScanLoopHeader; - - public void setLinearScanNumber(int v) { - linearScanNumber = v; - } - - public int linearScanNumber() { - return linearScanNumber; - } - - public void setLinearScanLoopEnd() { - linearScanLoopEnd = true; - } - - public boolean isLinearScanLoopEnd() { - return linearScanLoopEnd; - } - - public void setLinearScanLoopHeader() { - this.linearScanLoopHeader = true; - } - - public boolean isLinearScanLoopHeader() { - return linearScanLoopHeader; - } - - public void replaceWith(LIRBlock other) { - for (LIRBlock pred : predecessors) { - Util.replaceAllInList(this, other, pred.successors); - } - for (int i = 0; i < other.predecessors.size(); ++i) { - if (other.predecessors.get(i) == this) { - other.predecessors.remove(i); - other.predecessors.addAll(i, this.predecessors); - } - } - successors.clear(); - predecessors.clear(); - } - - public void setInstructions(List list) { - instructions = list; - } - - public void setLastState(FrameState fs) { - lastState = fs; - } - - public FrameState lastState() { - return lastState; - } - - private Node first; - private Node last; - - public Node firstInstruction() { - return first; - } - - - public Node lastInstruction() { - return last; - } - - public void setFirstInstruction(Node n) { - first = n; - } - - - public void setLastInstruction(Node n) { - last = n; - } - - public boolean endsWithJump() { - List instructionsList = lir.instructionsList(); - if (instructionsList.size() == 0) { - return false; - } - LIRInstruction lirInstruction = instructionsList.get(instructionsList.size() - 1); - if (lirInstruction instanceof LIRXirInstruction) { - LIRXirInstruction lirXirInstruction = (LIRXirInstruction) lirInstruction; - return (lirXirInstruction.falseSuccessor() != null) && (lirXirInstruction.trueSuccessor() != null); - } - LIROpcode code = lirInstruction.code; - return code == LIROpcode.Branch || code == LIROpcode.TableSwitch; - } - - public boolean isExceptionEntry() { - return firstInstruction() instanceof ExceptionObjectNode; - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/LIRBranch.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/LIRBranch.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,156 +0,0 @@ -/* - * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.compiler.lir; - -import com.oracle.max.asm.*; -import com.oracle.max.graal.nodes.calc.*; -import com.sun.cri.ci.*; - -/** - * @author Marcelo Cintra - * @author Thomas Wuerthinger - * - */ -public class LIRBranch extends LIRInstruction { - - private Condition cond; - private Label label; - - /** - * The target block of this branch. - */ - private LIRBlock block; - - /** - * This is the unordered block for a float branch. - */ - private LIRBlock unorderedBlock; - - - public LIRBranch(Condition cond, Label label) { - this(cond, label, null); - } - - /** - * Creates a new LIRBranch instruction. - * - * @param cond the branch condition - * @param label target label - * - */ - public LIRBranch(Condition cond, Label label, LIRDebugInfo info) { - super(LIROpcode.Branch, CiValue.IllegalValue, info, false); - this.cond = cond; - this.label = label; - } - - /** - * Creates a new LIRBranch instruction. - * - * @param cond - * @param kind - * @param block - * - */ - public LIRBranch(Condition cond, LIRBlock block) { - super(LIROpcode.Branch, CiValue.IllegalValue, block.debugInfo(), false); - this.cond = cond; - this.label = block.label(); - this.block = block; - this.unorderedBlock = null; - } - - public LIRBranch(Condition cond, LIRBlock block, LIRBlock ublock) { - super(LIROpcode.CondFloatBranch, CiValue.IllegalValue, (block.debugInfo() != null ? block.debugInfo() : (ublock != null ? ublock.debugInfo() : null)), false); - this.cond = cond; - this.label = block.label(); - this.block = block; - this.unorderedBlock = ublock; - } - - /** - * @return the condition - */ - public Condition cond() { - return cond; - } - - public Label label() { - return label; - } - - public LIRBlock block() { - return block; - } - - public LIRBlock unorderedBlock() { - return unorderedBlock; - } - - public void changeBlock(LIRBlock b) { - assert block != null : "must have old block"; - assert block.label() == label() : "must be equal"; - assert b != null; - - this.block = b; - this.label = b.label(); - } - - public void negateCondition() { - cond = cond.negate(); - } - - @Override - public void emitCode(LIRAssembler masm) { - masm.emitBranch(this); - } - - @Override - public String operationString(OperandFormatter operandFmt) { - StringBuilder buf = new StringBuilder(cond().operator).append(' '); - if (block() != null) { - buf.append("[B").append(block.blockID()).append(']'); - } else if (label().isBound()) { - buf.append("[label:0x").append(Integer.toHexString(label().position())).append(']'); - } else { - buf.append("[label:??]"); - } - if (unorderedBlock() != null) { - buf.append("unordered: [B").append(unorderedBlock().blockID()).append(']'); - } - return buf.toString(); - } - - public void substitute(LIRBlock oldBlock, LIRBlock newBlock) { - assert newBlock != null; - if (block == oldBlock) { - block = newBlock; - LIRInstruction instr = newBlock.lir().instructionsList().get(0); - assert instr instanceof LIRLabel : "first instruction of block must be label"; - label = ((LIRLabel) instr).label(); - } - if (unorderedBlock == oldBlock) { - unorderedBlock = newBlock; - } - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/LIRCall.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/LIRCall.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,143 +0,0 @@ -/* - * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.compiler.lir; - -import java.util.*; - -import com.sun.cri.ci.*; -import com.sun.cri.ci.CiTargetMethod.Mark; -import com.sun.cri.ri.*; -import com.sun.cri.xir.CiXirAssembler.XirMark; - -/** - * This class represents a call instruction; either to a {@linkplain CiRuntimeCall runtime method}, - * a {@linkplain RiMethod Java method}, a native function or a global stub. - * - * @author Marcelo Cintra - */ -public class LIRCall extends LIRInstruction { - - /** - * The target of the call. This will be a {@link CiRuntimeCall}, {@link RiMethod} or {@link CiValue} - * object denoting a call to the runtime, a Java method or a native function respectively. - */ - public final Object target; - /** - * The call site needs to be marked if this is non-null. - */ - public final Map marks; - - private final int targetAddressIndex; - - public final List pointerSlots; - - - private static CiValue[] toArray(List arguments) { - return arguments.toArray(new CiValue[arguments.size()]); - } - - public LIRCall(LIROpcode opcode, - Object target, - CiValue result, - List arguments, - LIRDebugInfo info, - Map marks, - boolean calleeSaved, - List pointerSlots) { - super(opcode, result, info, !calleeSaved, 0, 0, toArray(arguments)); - this.marks = marks; - this.pointerSlots = pointerSlots; - if (opcode == LIROpcode.DirectCall) { - this.targetAddressIndex = -1; - } else { - // The last argument is the operand holding the address for the indirect call - this.targetAddressIndex = arguments.size() - 1; - } - this.target = target; - } - - /** - * Emits target assembly code for this instruction. - * - * @param masm the target assembler - */ - @Override - public void emitCode(LIRAssembler masm) { - masm.emitCall(this); - } - - /** - * Returns the receiver for this method call. - * @return the receiver - */ - public CiValue receiver() { - return operand(0); - } - - public RiMethod method() { - return (RiMethod) target; - } - - public CiRuntimeCall runtimeCall() { - return (CiRuntimeCall) target; - } - - public CiValue targetAddress() { - if (targetAddressIndex >= 0) { - return operand(targetAddressIndex); - } - return null; - } - - @Override - public String operationString(OperandFormatter operandFmt) { - StringBuilder buf = new StringBuilder(); - if (result().isLegal()) { - buf.append(operandFmt.format(result())).append(" = "); - } - String targetAddress = null; - if (code == LIROpcode.RuntimeCall) { - buf.append(target); - } else if (code != LIROpcode.DirectCall && code != LIROpcode.ConstDirectCall) { - if (targetAddressIndex >= 0) { - targetAddress = operandFmt.format(targetAddress()); - buf.append(targetAddress); - } - } - buf.append('('); - boolean first = true; - for (LIROperand operandSlot : operands) { - String operand = operandFmt.format(operandSlot.value(this)); - if (!operand.isEmpty() && !operand.equals(targetAddress)) { - if (!first) { - buf.append(", "); - } else { - first = false; - } - buf.append(operand); - } - } - buf.append(')'); - return buf.toString(); - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/LIRCompareAndSwap.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/LIRCompareAndSwap.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,81 +0,0 @@ -/* - * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.compiler.lir; - -import com.sun.cri.ci.*; - -/** - * The {@code LIRCompareAndSwap} class definition. - * - * @author Marcelo Cintra - * - */ -public class LIRCompareAndSwap extends LIRInstruction { - - /** - * Constructs a new LIRCompareAndSwap instruction. - * @param addr - * @param expectedValue - * @param newValue - */ - public LIRCompareAndSwap(LIROpcode opcode, CiValue addr, CiValue expectedValue, CiValue newValue) { - super(opcode, CiValue.IllegalValue, null, false, 0, 0, addr, expectedValue, newValue); - } - - /** - * Gets the address of compare and swap. - * - * @return the address - */ - public CiValue address() { - return operand(0); - } - - /** - * Gets the cmpValue of this class. - * - * @return the cmpValue - */ - public CiValue expectedValue() { - return operand(1); - } - - /** - * Gets the newValue of this class. - * - * @return the newValue - */ - public CiValue newValue() { - return operand(2); - } - - /** - * Emits target assembly code for this instruction. - * - * @param masm the target assembler - */ - @Override - public void emitCode(LIRAssembler masm) { - masm.emitCompareAndSwap(this); - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/LIRConvert.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/LIRConvert.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,69 +0,0 @@ -/* - * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.compiler.lir; - -import com.oracle.max.graal.compiler.globalstub.*; -import com.sun.cri.bytecode.*; -import com.sun.cri.ci.*; - -/** - * The {@code LIRConvert} class definition. - * - * @author Marcelo Cintra - * - */ -public class LIRConvert extends LIROp1 { - - public final int bytecode; - public GlobalStub globalStub; - - /** - * Constructs a new instruction LIRConvert for a given operand. - * - * @param bytecode the opcode of the bytecode for this conversion - * @param operand the input operand for this instruction - * @param result the result operand for this instruction - */ - public LIRConvert(int bytecode, CiValue operand, CiValue result) { - super(LIROpcode.Convert, operand, result); - this.bytecode = bytecode; - } - - /** - * Emits target assembly code for this LIRConvert instruction. - * - * @param masm the LIRAssembler - */ - @Override - public void emitCode(LIRAssembler masm) { - masm.emitConvert(this); - } - - /** - * Prints this instruction to a LogStream. - */ - @Override - public String operationString(OperandFormatter operandFmt) { - return "[" + Bytecodes.nameOf(bytecode) + "] " + super.operationString(operandFmt); - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/LIRDebugInfo.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/LIRDebugInfo.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,109 +0,0 @@ -/* - * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.compiler.lir; - -import com.oracle.max.graal.compiler.*; -import com.oracle.max.graal.graph.*; -import com.oracle.max.graal.nodes.*; -import com.sun.cri.ci.*; - -/** - * This class represents debugging and deoptimization information attached to a LIR instruction. - */ -public class LIRDebugInfo { - - public abstract static class ValueLocator { - public abstract CiValue getLocation(ValueNode value); - } - - public final FrameState state; - private LIRBlock exceptionEdge; - public CiDebugInfo debugInfo; - - public LIRDebugInfo(FrameState state) { - assert state != null; - this.state = state; - } - - public LIRBlock exceptionEdge() { - return exceptionEdge; - } - - public void setExceptionEdge(LIRBlock exceptionEdge) { - this.exceptionEdge = exceptionEdge; - } - - private LIRDebugInfo(LIRDebugInfo info) { - this.state = info.state; - this.exceptionEdge = info.exceptionEdge; - } - - public LIRDebugInfo copy() { - return new LIRDebugInfo(this); - } - - public void setOop(CiValue location, GraalCompilation compilation, BitMap frameRefMap, BitMap regRefMap) { - CiTarget target = compilation.target; - if (location.isAddress()) { - CiAddress stackLocation = (CiAddress) location; - assert stackLocation.index.isIllegal(); - if (stackLocation.base == CiRegister.Frame.asValue()) { - int offset = stackLocation.displacement; - assert offset % target.wordSize == 0 : "must be aligned"; - int stackMapIndex = offset / target.wordSize; - setBit(frameRefMap, stackMapIndex); - } - } else if (location.isStackSlot()) { - CiStackSlot stackSlot = (CiStackSlot) location; - assert !stackSlot.inCallerFrame(); - assert target.spillSlotSize == target.wordSize; - setBit(frameRefMap, stackSlot.index()); - } else { - assert location.isRegister() : "objects can only be in a register"; - CiRegisterValue registerLocation = (CiRegisterValue) location; - int reg = registerLocation.reg.number; - assert reg >= 0 : "object cannot be in non-object register " + registerLocation.reg; - assert reg < target.arch.registerReferenceMapBitCount; - setBit(regRefMap, reg); - } - } - - public CiDebugInfo debugInfo() { - assert debugInfo != null : "debug info not allocated yet"; - return debugInfo; - } - - public boolean hasDebugInfo() { - return debugInfo != null; - } - - public static void setBit(BitMap refMap, int bit) { - assert !refMap.get(bit) : "Ref map entry " + bit + " is already set."; - refMap.set(bit); - } - - @Override - public String toString() { - return state.toString(); - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/LIRInstruction.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/LIRInstruction.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,553 +0,0 @@ -/* - * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.compiler.lir; - -import static com.oracle.max.graal.compiler.GraalCompilation.*; - -import java.util.*; - -import com.oracle.max.graal.compiler.*; -import com.oracle.max.graal.compiler.lir.LIROperand.LIRAddressOperand; -import com.oracle.max.graal.compiler.lir.LIROperand.LIRVariableOperand; -import com.oracle.max.graal.graph.*; -import com.sun.cri.ci.*; - -/** - * The {@code LIRInstruction} class definition. - * - * @author Marcelo Cintra - * @author Thomas Wuerthinger - */ -public abstract class LIRInstruction { - - private static final LIROperand ILLEGAL_SLOT = new LIROperand(CiValue.IllegalValue); - - private static final CiValue[] NO_OPERANDS = {}; - - public static final OperandMode[] OPERAND_MODES = OperandMode.values(); - - /** - * Constants denoting how a LIR instruction uses an operand. Any combination of these modes - * can be applied to an operand as long as every operand has at least one mode applied to it. - */ - public enum OperandMode { - /** - * An operand that is defined by a LIR instruction and is live after the code emitted for a LIR instruction. - */ - Output, - - /** - * An operand that is used by a LIR instruction and is live before the code emitted for a LIR instruction. - * Unless such an operand is also an output or temp operand, it must not be modified by a LIR instruction. - */ - Input, - - /** - * An operand that is both modified and used by a LIR instruction. - */ - Temp - } - - /** - * The opcode of this instruction. - */ - public final LIROpcode code; - - /** - * The result operand for this instruction. - */ - private final LIROperand result; - - /** - * The input and temporary operands of this instruction. - */ - protected final LIROperand[] operands; - - /** - * Used to emit debug information. - */ - public final LIRDebugInfo info; - - /** - * Value id for register allocation. - */ - private int id; - - /** - * Determines if all caller-saved registers are destroyed by this instruction. - */ - public final boolean hasCall; - - /** - * The number of variable or register output operands for this instruction. - * These operands are at indexes {@code [0 .. allocatorOutputCount-1]} in {@link #allocatorOperands}. - * - * @see OperandMode#Output - */ - private byte allocatorOutputCount; - - /** - * The number of variable or register input operands for this instruction. - * These operands are at indexes {@code [allocatorOutputCount .. (allocatorInputCount+allocatorOutputCount-1)]} in {@link #allocatorOperands}. - * - * @see OperandMode#Input - */ - private byte allocatorInputCount; - - /** - * The number of variable or register temp operands for this instruction. - * These operands are at indexes {@code [allocatorInputCount+allocatorOutputCount .. (allocatorTempCount+allocatorInputCount+allocatorOutputCount-1)]} in {@link #allocatorOperands}. - * - * @see OperandMode#Temp - */ - private byte allocatorTempCount; - - /** - * The number of variable or register input or temp operands for this instruction. - */ - private byte allocatorTempInputCount; - - /** - * The set of operands that must be known to the register allocator either to bind a register - * or stack slot to a {@linkplain CiVariable variable} or to inform the allocator about operands - * that are already fixed to a specific register. - * This set excludes all constant operands as well as operands that are bound to - * a stack slot in the {@linkplain CiStackSlot#inCallerFrame() caller's frame}. - * This array is partitioned as follows. - *
-     *
-     *   <-- allocatorOutputCount --> <-- allocatorInputCount --> <-- allocatorTempCount -->
-     *  +----------------------------+---------------------------+--------------------------+
-     *  |       output operands      |       input operands      |      temp operands       |
-     *  +----------------------------+---------------------------+--------------------------+
-     *
-     * 
- */ - final List allocatorOperands; - - /** - * Constructs a new LIR instruction that has no input or temp operands. - * - * @param opcode the opcode of the new instruction - * @param result the operand that holds the operation result of this instruction. This will be - * {@link CiValue#IllegalValue} for instructions that do not produce a result. - * @param info the {@link LIRDebugInfo} info that is to be preserved for the instruction. This will be {@code null} when no debug info is required for the instruction. - * @param hasCall specifies if all caller-saved registers are destroyed by this instruction - */ - public LIRInstruction(LIROpcode opcode, CiValue result, LIRDebugInfo info, boolean hasCall) { - this(opcode, result, info, hasCall, 0, 0, NO_OPERANDS); - } - - /** - * Constructs a new LIR instruction. The {@code operands} array is partitioned as follows: - *
-     *
-     *                              <------- tempInput -------> <--------- temp --------->
-     *  +--------------------------+---------------------------+--------------------------+
-     *  |       input operands     |   input+temp operands     |      temp operands       |
-     *  +--------------------------+---------------------------+--------------------------+
-     *
-     * 
- * - * @param opcode the opcode of the new instruction - * @param result the operand that holds the operation result of this instruction. This will be - * {@link CiValue#IllegalValue} for instructions that do not produce a result. - * @param info the {@link LIRDebugInfo} that is to be preserved for the instruction. This will be {@code null} when no debug info is required for the instruction. - * @param hasCall specifies if all caller-saved registers are destroyed by this instruction - * @param tempInput the number of operands that are both {@linkplain OperandMode#Input input} and {@link OperandMode#Temp temp} operands for this instruction - * @param temp the number of operands that are {@link OperandMode#Temp temp} operands for this instruction - * @param operands the input and temp operands for the instruction - */ - public LIRInstruction(LIROpcode opcode, CiValue result, LIRDebugInfo info, boolean hasCall, int tempInput, int temp, CiValue... operands) { - this.code = opcode; - this.info = info; - this.hasCall = hasCall; - - assert opcode != LIROpcode.Move || result != CiValue.IllegalValue; - allocatorOperands = new ArrayList(operands.length + 3); - this.result = initOutput(result); - - GraalMetrics.LIRInstructions++; - - if (opcode == LIROpcode.Move) { - GraalMetrics.LIRMoveInstructions++; - } - id = -1; - this.operands = new LIROperand[operands.length]; - initInputsAndTemps(tempInput, temp, operands); - - assert verifyOperands(); - } - - public final int id() { - return id; - } - - public final void setId(int id) { - this.id = id; - } - - private LIROperand initOutput(CiValue output) { - assert output != null; - if (output != CiValue.IllegalValue) { - if (output.isAddress()) { - return addAddress((CiAddress) output); - } - if (output.isStackSlot()) { - return new LIROperand(output); - } - - assert allocatorOperands.size() == allocatorOutputCount; - allocatorOperands.add(output); - allocatorOutputCount++; - return new LIRVariableOperand(allocatorOperands.size() - 1); - } else { - return ILLEGAL_SLOT; - } - } - - /** - * Adds a {@linkplain CiValue#isLegal() legal} value that is part of an address to - * the list of {@linkplain #allocatorOperands register allocator operands}. If - * the value is {@linkplain CiVariable variable}, then its index into the list - * of register allocator operands is returned. Otherwise, {@code -1} is returned. - */ - private int addAddressPart(CiValue part) { - if (part.isRegister()) { - allocatorInputCount++; - allocatorOperands.add(part); - return -1; - } - if (part.isVariable()) { - allocatorInputCount++; - allocatorOperands.add(part); - return allocatorOperands.size() - 1; - } - assert part.isIllegal(); - return -1; - } - - private LIROperand addAddress(CiAddress address) { - assert address.base.isVariableOrRegister(); - - int base = addAddressPart(address.base); - int index = addAddressPart(address.index); - - if (base != -1 || index != -1) { - return new LIRAddressOperand(base, index, address); - } - - assert address.base.isRegister() && (address.index.isIllegal() || address.index.isRegister()); - return new LIROperand(address); - } - - private LIROperand addOperand(CiValue operand, boolean isInput, boolean isTemp) { - assert operand != null; - if (operand != CiValue.IllegalValue) { - assert !(operand.isAddress()); - if (operand.isStackSlot()) { - // no variables to add - return new LIROperand(operand); - } else if (operand.isConstant()) { - // no variables to add - return new LIROperand(operand); - } else { - assert allocatorOperands.size() == allocatorOutputCount + allocatorInputCount + allocatorTempInputCount + allocatorTempCount; - allocatorOperands.add(operand); - - if (isInput && isTemp) { - allocatorTempInputCount++; - } else if (isInput) { - allocatorInputCount++; - } else { - assert isTemp; - allocatorTempCount++; - } - - return new LIRVariableOperand(allocatorOperands.size() - 1); - } - } else { - return ILLEGAL_SLOT; - } - } - - /** - * Gets an input or temp operand of this instruction. - * - * @param index the index of the operand requested - * @return the {@code index}'th operand - */ - public final CiValue operand(int index) { - if (index >= operands.length) { - return CiValue.IllegalValue; - } - - return operands[index].value(this); - } - - private void initInputsAndTemps(int tempInputCount, int tempCount, CiValue[] operands) { - - // Addresses in instruction - for (int i = 0; i < operands.length; i++) { - CiValue op = operands[i]; - if (op.isAddress()) { - this.operands[i] = addAddress((CiAddress) op); - } - } - - int z = 0; - // Input-only operands - for (int i = 0; i < operands.length - tempInputCount - tempCount; i++) { - if (this.operands[z] == null) { - this.operands[z] = addOperand(operands[z], true, false); - } - z++; - } - - // Operands that are both inputs and temps - for (int i = 0; i < tempInputCount; i++) { - if (this.operands[z] == null) { - this.operands[z] = addOperand(operands[z], true, true); - } - z++; - } - - // Temp-only operands - for (int i = 0; i < tempCount; i++) { - if (this.operands[z] == null) { - this.operands[z] = addOperand(operands[z], false, true); - } - z++; - } - } - - private boolean verifyOperands() { - for (LIROperand operandSlot : operands) { - assert operandSlot != null; - } - - for (CiValue operand : this.allocatorOperands) { - assert operand != null; - assert operand.isVariableOrRegister() : "LIR operands can only be variables and registers initially, not " + operand.getClass().getSimpleName(); - } - return true; - } - - /** - * Gets the result operand for this instruction. - * - * @return return the result operand - */ - public final CiValue result() { - return result.value(this); - } - - /** - * Gets the instruction name. - * - * @return the name of the enum constant that represents the instruction opcode, exactly as declared in the enum - * LIROpcode declaration. - */ - public String name() { - return code.name(); - } - - /** - * Abstract method to be used to emit target code for this instruction. - * - * @param masm the target assembler. - */ - public abstract void emitCode(LIRAssembler masm); - - /** - * Utility for specializing how a {@linkplain CiValue LIR operand} is formatted to a string. - * The {@linkplain OperandFormatter#DEFAULT default formatter} returns the value of - * {@link CiValue#toString()}. - */ - public static class OperandFormatter { - public static final OperandFormatter DEFAULT = new OperandFormatter(); - - /** - * Formats a given operand as a string. - * - * @param operand the operand to format - * @return {@code operand} as a string - */ - public String format(CiValue operand) { - return operand.toString(); - } - } - - /** - * Gets the operation performed by this instruction in terms of its operands as a string. - */ - public String operationString(OperandFormatter operandFmt) { - StringBuilder buf = new StringBuilder(); - if (result != ILLEGAL_SLOT) { - buf.append(operandFmt.format(result.value(this))).append(" = "); - } - if (operands.length > 1) { - buf.append("("); - } - boolean first = true; - for (LIROperand operandSlot : operands) { - String operand = operandFmt.format(operandSlot.value(this)); - if (!operand.isEmpty()) { - if (!first) { - buf.append(", "); - } else { - first = false; - } - buf.append(operand); - } - } - if (operands.length > 1) { - buf.append(")"); - } - return buf.toString(); - } - - public boolean verify() { - return true; - } - - /** - * Determines if a given opcode is in a given range of valid opcodes. - * - * @param opcode the opcode to be tested. - * @param start the lower bound range limit of valid opcodes - * @param end the upper bound range limit of valid opcodes - */ - protected static boolean isInRange(LIROpcode opcode, LIROpcode start, LIROpcode end) { - return start.ordinal() < opcode.ordinal() && opcode.ordinal() < end.ordinal(); - } - - public boolean hasOperands() { - if (info != null || hasCall) { - return true; - } - return allocatorOperands.size() > 0; - } - - public final int operandCount(OperandMode mode) { - if (mode == OperandMode.Output) { - return allocatorOutputCount; - } else if (mode == OperandMode.Input) { - return allocatorInputCount + allocatorTempInputCount; - } else { - assert mode == OperandMode.Temp; - return allocatorTempInputCount + allocatorTempCount; - } - } - - public final CiValue operandAt(OperandMode mode, int index) { - if (mode == OperandMode.Output) { - assert index < allocatorOutputCount; - return allocatorOperands.get(index); - } else if (mode == OperandMode.Input) { - assert index < allocatorInputCount + allocatorTempInputCount; - return allocatorOperands.get(index + allocatorOutputCount); - } else { - assert mode == OperandMode.Temp; - assert index < allocatorTempInputCount + allocatorTempCount; - return allocatorOperands.get(index + allocatorOutputCount + allocatorInputCount); - } - } - - public final void setOperandAt(OperandMode mode, int index, CiValue location) { - assert index < operandCount(mode); - assert location.kind != CiKind.Illegal; - assert operandAt(mode, index).isVariable(); - if (mode == OperandMode.Output) { - assert index < allocatorOutputCount; - allocatorOperands.set(index, location); - } else if (mode == OperandMode.Input) { - assert index < allocatorInputCount + allocatorTempInputCount; - allocatorOperands.set(index + allocatorOutputCount, location); - } else { - assert mode == OperandMode.Temp; - assert index < allocatorTempInputCount + allocatorTempCount; - allocatorOperands.set(index + allocatorOutputCount + allocatorInputCount, location); - } - } - - public final LIRBlock exceptionEdge() { - return (info == null) ? null : info.exceptionEdge(); - } - - @Override - public String toString() { - return toString(OperandFormatter.DEFAULT); - } - - public final String toStringWithIdPrefix() { - if (id != -1) { - return String.format("%4d %s", id, toString()); - } - return " " + toString(); - } - - protected static String refMapToString(CiDebugInfo debugInfo, OperandFormatter operandFmt) { - StringBuilder buf = new StringBuilder(); - if (debugInfo.hasStackRefMap()) { - BitMap bm = debugInfo.frameRefMap; - for (int slot = bm.nextSetBit(0); slot >= 0; slot = bm.nextSetBit(slot + 1)) { - if (buf.length() != 0) { - buf.append(", "); - } - buf.append(operandFmt.format(CiStackSlot.get(CiKind.Object, slot))); - } - } - if (debugInfo.hasRegisterRefMap()) { - BitMap bm = debugInfo.registerRefMap; - for (int reg = bm.nextSetBit(0); reg >= 0; reg = bm.nextSetBit(reg + 1)) { - if (buf.length() != 0) { - buf.append(", "); - } - CiRegisterValue register = compilation().target.arch.registers[reg].asValue(CiKind.Object); - buf.append(operandFmt.format(register)); - } - } - return buf.toString(); - } - - protected void appendDebugInfo(StringBuilder buf, OperandFormatter operandFmt, LIRDebugInfo info) { - if (info != null) { - buf.append(" [bci:").append(info.state.bci); - if (info.hasDebugInfo()) { - CiDebugInfo debugInfo = info.debugInfo(); - String refmap = refMapToString(debugInfo, operandFmt); - if (refmap.length() != 0) { - buf.append(", refmap(").append(refmap.trim()).append(')'); - } - } - buf.append(']'); - } - } - - public String toString(OperandFormatter operandFmt) { - StringBuilder buf = new StringBuilder(name()).append(' ').append(operationString(operandFmt)); - appendDebugInfo(buf, operandFmt, info); - return buf.toString(); - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/LIRLabel.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/LIRLabel.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,71 +0,0 @@ -/* - * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.compiler.lir; - -import com.oracle.max.asm.*; -import com.sun.cri.ci.*; - -/** - * The {@code LIRLabel} class definition. - * - * @author Marcelo Cintra - */ -public class LIRLabel extends LIROp0 { - - private Label label; - - /** - * Constructs a LIRLabel instruction. - * @param label the label - */ - public LIRLabel(Label label) { - super(LIROpcode.Label, CiValue.IllegalValue, null); - assert label != null; - this.label = label; - } - - /** - * Gets the label associated to this instruction. - * @return the label - */ - public Label label() { - return label; - } - - /** - * Emits target assembly code for this LIRLabel instruction. - * @param masm the LIRAssembler - */ - @Override - public void emitCode(LIRAssembler masm) { - masm.emitOpLabel(this); - } - - /** - * Prints this instruction to a LogStream. - */ - @Override - public String operationString(OperandFormatter operandFmt) { - return label.isBound() ? String.valueOf(label.position()) : "?"; - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/LIRList.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/LIRList.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,482 +0,0 @@ -/* - * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.compiler.lir; - -import java.util.*; - -import com.oracle.max.asm.*; -import com.oracle.max.graal.compiler.*; -import com.oracle.max.graal.compiler.alloc.*; -import com.oracle.max.graal.compiler.debug.*; -import com.oracle.max.graal.compiler.gen.*; -import com.oracle.max.graal.compiler.globalstub.*; -import com.oracle.max.graal.nodes.calc.*; -import com.sun.cri.ci.*; -import com.sun.cri.ci.CiTargetMethod.Mark; -import com.sun.cri.ri.*; -import com.sun.cri.xir.CiXirAssembler.XirMark; -import com.sun.cri.xir.*; - -/** - * This class represents a list of LIR instructions and contains factory methods for creating and appending LIR - * instructions to this list. - */ -public final class LIRList { - - private List operations; - private final LIRGenerator generator; - - private final LIROpcode runtimeCallOp; - - private LIROpcode directCallOp(RiMethod method) { - return GraalOptions.UseConstDirectCall && method.hasCompiledCode() ? LIROpcode.ConstDirectCall : LIROpcode.DirectCall; - } - - public LIRList(LIRGenerator generator) { - this.generator = generator; - this.operations = new ArrayList(8); - runtimeCallOp = GraalOptions.UseConstDirectCall ? LIROpcode.ConstDirectCall : LIROpcode.DirectCall; - } - - private void append(LIRInstruction op) { - if (GraalOptions.PrintIRWithLIR && !TTY.isSuppressed()) { - generator.maybePrintCurrentInstruction(); - TTY.println(op.toStringWithIdPrefix()); - TTY.println(); - } - operations.add(op); - assert op.verify(); - } - - public List instructionsList() { - return operations; - } - - public int length() { - return operations.size(); - } - - public LIRInstruction at(int i) { - return operations.get(i); - } - - public void callDirect(RiMethod method, CiValue result, List arguments, LIRDebugInfo info, Map marks, List pointerSlots) { - append(new LIRCall(directCallOp(method), method, result, arguments, info, marks, false, pointerSlots)); - } - - public void callIndirect(RiMethod method, CiValue result, List arguments, LIRDebugInfo info, Map marks, List pointerSlots) { - append(new LIRCall(LIROpcode.IndirectCall, method, result, arguments, info, marks, false, pointerSlots)); - } - - public void callNative(String symbol, CiValue result, List arguments, LIRDebugInfo info, Map marks) { - append(new LIRCall(LIROpcode.NativeCall, symbol, result, arguments, info, marks, false, null)); - } - - public void templateCall(CiValue result, List arguments) { - append(new LIRCall(LIROpcode.TemplateCall, null, result, arguments, null, null, false, null)); - } - - public void membar(int barriers) { - append(new LIRMemoryBarrier(barriers)); - } - - public void branchDestination(Label lbl) { - append(new LIRLabel(lbl)); - } - - public void negate(CiValue src, CiValue dst) { - LIRNegate op = new LIRNegate(src, dst); - append(op); - } - - public void lea(CiValue src, CiValue dst) { - append(new LIROp1(LIROpcode.Lea, src, dst)); - } - - public void unalignedMove(CiValue src, CiValue dst) { - append(new LIROp1(LIROp1.LIRMoveKind.Unaligned, src, dst, dst.kind, null)); - } - - public void move(CiAddress src, CiValue dst, LIRDebugInfo info) { - append(new LIROp1(LIROpcode.Move, src, dst, src.kind, info)); - } - - public void move(CiValue src, CiAddress dst, LIRDebugInfo info) { - append(new LIROp1(LIROpcode.Move, src, dst, dst.kind, info)); - } - - public void move(CiValue src, CiValue dst, CiKind kind) { - append(new LIROp1(LIROpcode.Move, src, dst, kind, null)); - } - - public void move(CiValue src, CiValue dst) { - append(new LIROp1(LIROpcode.Move, src, dst, dst.kind, null)); - } - - public void volatileMove(CiValue src, CiValue dst, CiKind kind, LIRDebugInfo info) { - append(new LIROp1(LIROp1.LIRMoveKind.Volatile, src, dst, kind, info)); - } - - public void oop2reg(Object o, CiValue reg) { - append(new LIROp1(LIROpcode.Move, CiConstant.forObject(o), reg)); - } - - public void returnOp(CiValue result) { - append(new LIROp1(LIROpcode.Return, result)); - } - - public void monitorAddress(int monitor, CiValue dst) { - append(new LIRMonitorAddress(dst, monitor)); - } - - public void convert(int code, CiValue left, CiValue dst, GlobalStub globalStub) { - LIRConvert op = new LIRConvert(code, left, dst); - op.globalStub = globalStub; - append(op); - } - - public void logicalAnd(CiValue left, CiValue right, CiValue dst) { - append(new LIROp2(LIROpcode.LogicAnd, left, right, dst)); - } - - public void logicalOr(CiValue left, CiValue right, CiValue dst) { - append(new LIROp2(LIROpcode.LogicOr, left, right, dst)); - } - - public void logicalXor(CiValue left, CiValue right, CiValue dst) { - append(new LIROp2(LIROpcode.LogicXor, left, right, dst)); - } - - public void nullCheck(CiValue opr, LIRDebugInfo info) { - append(new LIROp1(LIROpcode.NullCheck, opr, info)); - } - - public void compareTo(CiValue left, CiValue right, CiValue dst) { - append(new LIROp2(LIROpcode.CompareTo, left, right, dst)); - } - - public void cmp(Condition condition, CiValue left, CiValue right, LIRDebugInfo info) { - append(new LIROp2(LIROpcode.Cmp, condition, left, right, info)); - } - - public void cmp(Condition condition, CiValue left, CiValue right) { - cmp(condition, left, right, null); - } - - public void cmp(Condition condition, CiValue left, int right, LIRDebugInfo info) { - cmp(condition, left, CiConstant.forInt(right), info); - } - - public void cmp(Condition condition, CiValue left, int right) { - cmp(condition, left, right, null); - } - - public void cmove(Condition condition, CiValue src1, CiValue src2, CiValue dst) { - append(new LIROp2(LIROpcode.Cmove, condition, src1, src2, dst)); - } - - public void fcmove(Condition condition, CiValue src1, CiValue src2, CiValue dst, boolean unorderedIsSecond) { - append(new LIROp2(unorderedIsSecond ? LIROpcode.FCmove : LIROpcode.UFCmove, condition, src1, src2, dst)); - } - - public void abs(CiValue from, CiValue to, CiValue tmp) { - append(new LIROp2(LIROpcode.Abs, from, tmp, to)); - } - - public void sqrt(CiValue from, CiValue to, CiValue tmp) { - append(new LIROp2(LIROpcode.Sqrt, from, tmp, to)); - } - - public void log(CiValue from, CiValue to, CiValue tmp) { - append(new LIROp2(LIROpcode.Log, from, tmp, to)); - } - - public void log10(CiValue from, CiValue to, CiValue tmp) { - append(new LIROp2(LIROpcode.Log10, from, tmp, to)); - } - - public void sin(CiValue from, CiValue to, CiValue tmp1, CiValue tmp2) { - append(new LIROp2(LIROpcode.Sin, from, tmp1, to, tmp2)); - } - - public void cos(CiValue from, CiValue to, CiValue tmp1, CiValue tmp2) { - append(new LIROp2(LIROpcode.Cos, from, tmp1, to, tmp2)); - } - - public void tan(CiValue from, CiValue to, CiValue tmp1, CiValue tmp2) { - append(new LIROp2(LIROpcode.Tan, from, tmp1, to, tmp2)); - } - - public void add(CiValue left, CiValue right, CiValue res) { - append(new LIROp2(LIROpcode.Add, left, right, res)); - } - - public void sub(CiValue left, CiValue right, CiValue res) { - append(new LIROp2(LIROpcode.Sub, left, right, res)); - } - - public void mul(CiValue left, CiValue right, CiValue res) { - append(new LIROp2(LIROpcode.Mul, left, right, res)); - } - - public void div(CiValue left, CiValue right, CiValue res, LIRDebugInfo info) { - append(new LIROp2(LIROpcode.Div, left, right, res, info)); - } - - public void rem(CiValue left, CiValue right, CiValue res, LIRDebugInfo info) { - append(new LIROp2(LIROpcode.Rem, left, right, res, info)); - } - - public void jump(LIRBlock block) { - assert block != null; - append(new LIRBranch(Condition.TRUE, block)); - } - - public void branch(Condition cond, Label lbl) { - append(new LIRBranch(cond, lbl)); - } - - public void branch(Condition cond, Label lbl, LIRDebugInfo info) { - append(new LIRBranch(cond, lbl, info)); - } - - public void branch(Condition cond, LIRBlock block) { - append(new LIRBranch(cond, block)); - } - - public void branch(Condition cond, LIRBlock block, LIRBlock unordered) { - append(new LIRBranch(cond, block, unordered)); - } - - public void tableswitch(CiValue index, int lowKey, LIRBlock defaultTargets, LIRBlock[] targets) { - append(new LIRTableSwitch(index, lowKey, defaultTargets, targets)); - } - - public void shiftLeft(CiValue value, int count, CiValue dst) { - shiftLeft(value, CiConstant.forInt(count), dst, CiValue.IllegalValue); - } - - public void shiftRight(CiValue value, int count, CiValue dst) { - shiftRight(value, CiConstant.forInt(count), dst, CiValue.IllegalValue); - } - - public void lcmp2int(CiValue left, CiValue right, CiValue dst) { - append(new LIROp2(LIROpcode.Cmpl2i, left, right, dst)); - } - - public void callRuntime(CiRuntimeCall rtCall, CiValue result, List arguments, LIRDebugInfo info) { - append(new LIRCall(runtimeCallOp, rtCall, result, arguments, info, null, false, null)); - } - - public void breakpoint() { - append(new LIROp0(LIROpcode.Breakpoint)); - } - - public void prefetch(CiAddress addr, boolean isStore) { - append(new LIROp1(isStore ? LIROpcode.Prefetchw : LIROpcode.Prefetchr, addr)); - } - - public void idiv(CiValue left, CiValue right, CiValue res, CiValue tmp, LIRDebugInfo info) { - append(new LIROp3(LIROpcode.Idiv, left, right, tmp, res, info)); - } - - public void irem(CiValue left, CiValue right, CiValue res, CiValue tmp, LIRDebugInfo info) { - append(new LIROp3(LIROpcode.Irem, left, right, tmp, res, info)); - } - - public void ldiv(CiValue left, CiValue right, CiValue res, CiValue tmp, LIRDebugInfo info) { - append(new LIROp3(LIROpcode.Ldiv, left, right, tmp, res, info)); - } - - public void lrem(CiValue left, CiValue right, CiValue res, CiValue tmp, LIRDebugInfo info) { - append(new LIROp3(LIROpcode.Lrem, left, right, tmp, res, info)); - } - - public void lsb(CiValue src, CiValue dst) { - append(new LIRSignificantBit(LIROpcode.Lsb, src, dst)); - } - - public void msb(CiValue src, CiValue dst) { - append(new LIRSignificantBit(LIROpcode.Msb, src, dst)); - } - - public void wdiv(CiValue left, CiValue right, CiValue res, CiValue tmp, LIRDebugInfo info) { - append(new LIROp3(LIROpcode.Wdiv, left, right, tmp, res, info)); - } - - public void wrem(CiValue left, CiValue right, CiValue res, CiValue tmp, LIRDebugInfo info) { - append(new LIROp3(LIROpcode.Wrem, left, right, tmp, res, info)); - } - - public void wdivi(CiValue left, CiValue right, CiValue res, CiValue tmp, LIRDebugInfo info) { - append(new LIROp3(LIROpcode.Wdivi, left, right, tmp, res, info)); - } - - public void wremi(CiValue left, CiValue right, CiValue res, CiValue tmp, LIRDebugInfo info) { - append(new LIROp3(LIROpcode.Wremi, left, right, tmp, res, info)); - } - - public void cmpMemInt(Condition condition, CiValue base, int disp, int c, LIRDebugInfo info) { - append(new LIROp2(LIROpcode.Cmp, condition, new CiAddress(CiKind.Int, base, disp), CiConstant.forInt(c), info)); - } - - public void cmpRegMem(Condition condition, CiValue reg, CiAddress addr, LIRDebugInfo info) { - append(new LIROp2(LIROpcode.Cmp, condition, reg, addr, info)); - } - - public void shiftLeft(CiValue value, CiValue count, CiValue dst, CiValue tmp) { - append(new LIROp2(LIROpcode.Shl, value, count, dst, tmp)); - } - - public void shiftRight(CiValue value, CiValue count, CiValue dst, CiValue tmp) { - append(new LIROp2(LIROpcode.Shr, value, count, dst, tmp)); - } - - public void unsignedShiftRight(CiValue value, CiValue count, CiValue dst, CiValue tmp) { - append(new LIROp2(LIROpcode.Ushr, value, count, dst, tmp)); - } - - public void fcmp2int(CiValue left, CiValue right, CiValue dst, boolean isUnorderedLess) { - append(new LIROp2(isUnorderedLess ? LIROpcode.Ucmpfd2i : LIROpcode.Cmpfd2i, left, right, dst)); - } - - public void casLong(CiValue addr, CiValue cmpValue, CiValue newValue) { - // Compare and swap produces condition code "zero" if contentsOf(addr) == cmpValue, - // implying successful swap of newValue into addr - append(new LIRCompareAndSwap(LIROpcode.CasLong, addr, cmpValue, newValue)); - } - - public void casObj(CiValue addr, CiValue cmpValue, CiValue newValue) { - // Compare and swap produces condition code "zero" if contentsOf(addr) == cmpValue, - // implying successful swap of newValue into addr - append(new LIRCompareAndSwap(LIROpcode.CasObj, addr, cmpValue, newValue)); - } - - public void casInt(CiValue addr, CiValue cmpValue, CiValue newValue) { - // Compare and swap produces condition code "zero" if contentsOf(addr) == cmpValue, - // implying successful swap of newValue into addr - append(new LIRCompareAndSwap(LIROpcode.CasInt, addr, cmpValue, newValue)); - } - - public void store(CiValue src, CiAddress dst, LIRDebugInfo info) { - append(new LIROp1(LIROpcode.Move, src, dst, dst.kind, info)); - } - - public void load(CiAddress src, CiValue dst, LIRDebugInfo info) { - append(new LIROp1(LIROpcode.Move, src, dst, src.kind, info)); - } - - public static void printBlock(LIRBlock x) { - // print block id - TTY.print("B%d ", x.blockID()); - - // print flags - if (x.isLinearScanLoopHeader()) { - TTY.print("lh "); - } - if (x.isLinearScanLoopEnd()) { - TTY.print("le "); - } - - // print block bci range - TTY.print("[%d, %d] ", -1, -1); - - // print predecessors and successors - if (x.numberOfPreds() > 0) { - TTY.print("preds: "); - for (int i = 0; i < x.numberOfPreds(); i++) { - TTY.print("B%d ", x.predAt(i).blockID()); - } - } - - if (x.numberOfSux() > 0) { - TTY.print("sux: "); - for (int i = 0; i < x.numberOfSux(); i++) { - TTY.print("B%d ", x.suxAt(i).blockID()); - } - } - - TTY.println(); - } - - public static void printLIR(List blocks) { - if (TTY.isSuppressed()) { - return; - } - TTY.println("LIR:"); - int i; - for (i = 0; i < blocks.size(); i++) { - LIRBlock bb = blocks.get(i); - printBlock(bb); - TTY.println("__id_Instruction___________________________________________"); - bb.lir().printInstructions(); - } - } - - private void printInstructions() { - for (int i = 0; i < operations.size(); i++) { - TTY.println(operations.get(i).toStringWithIdPrefix()); - TTY.println(); - } - TTY.println(); - } - - public void append(LIRInsertionBuffer buffer) { - assert this == buffer.lirList() : "wrong lir list"; - int n = operations.size(); - - if (buffer.numberOfOps() > 0) { - // increase size of instructions list - for (int i = 0; i < buffer.numberOfOps(); i++) { - operations.add(null); - } - // insert ops from buffer into instructions list - int opIndex = buffer.numberOfOps() - 1; - int ipIndex = buffer.numberOfInsertionPoints() - 1; - int fromIndex = n - 1; - int toIndex = operations.size() - 1; - for (; ipIndex >= 0; ipIndex--) { - int index = buffer.indexAt(ipIndex); - // make room after insertion point - while (index < fromIndex) { - operations.set(toIndex--, operations.get(fromIndex--)); - } - // insert ops from buffer - for (int i = buffer.countAt(ipIndex); i > 0; i--) { - operations.set(toIndex--, buffer.opAt(opIndex--)); - } - } - } - - buffer.finish(); - } - - public void insertBefore(int i, LIRInstruction op) { - operations.add(i, op); - } - - public void xir(XirSnippet snippet, CiValue[] operands, CiValue outputOperand, int tempInputCount, int tempCount, CiValue[] inputOperands, int[] operandIndices, int outputOperandIndex, - LIRDebugInfo info, LIRDebugInfo infoAfter, RiMethod method, List pointerSlots) { - append(new LIRXirInstruction(snippet, operands, outputOperand, tempInputCount, tempCount, inputOperands, operandIndices, outputOperandIndex, info, infoAfter, method, pointerSlots)); - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/LIRMemoryBarrier.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/LIRMemoryBarrier.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,46 +0,0 @@ -/* - * Copyright (c) 2010, 2010, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.compiler.lir; - -import com.sun.cri.bytecode.Bytecodes.MemoryBarriers; -import com.sun.cri.ci.*; - -/** - * LIR instruction implementing a {@linkplain MemoryBarriers memory barrier}. - * - * @author Doug Simon - */ -public class LIRMemoryBarrier extends LIRInstruction { - - public final int barriers; - - public LIRMemoryBarrier(int barriers) { - super(LIROpcode.Membar, CiValue.IllegalValue, null, false); - this.barriers = barriers; - } - - @Override - public void emitCode(LIRAssembler masm) { - masm.emitMemoryBarriers(barriers); - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/LIRMonitorAddress.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/LIRMonitorAddress.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,45 +0,0 @@ -/* - * Copyright (c) 2010, 2010, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.compiler.lir; - -import com.sun.cri.ci.*; - -/** - * LIR instruction used in to represent the address of a monitor object within the stack frame. - * - * @author Doug Simon - */ -public class LIRMonitorAddress extends LIRInstruction { - - public final int monitor; - - public LIRMonitorAddress(CiValue result, int monitor) { - super(LIROpcode.MonitorAddress, result, null, false); - this.monitor = monitor; - } - - @Override - public void emitCode(LIRAssembler masm) { - masm.emitMonitorAddress(monitor, this.result()); - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/LIRNegate.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/LIRNegate.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,44 +0,0 @@ -/* - * Copyright (c) 2010, 2010, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.compiler.lir; - -import com.sun.cri.ci.*; - -/** - * The {@code LIRNegate} class definition. - * - * @author Thomas Wuerthinger - * - */ -public class LIRNegate extends LIROp1 { - - /** - * Constructs a new instruction LIRNegate for a given operand. - * - * @param operand the input operand for this instruction - * @param result the result operand for this instruction - */ - public LIRNegate(CiValue operand, CiValue result) { - super(LIROpcode.Neg, operand, result); - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/LIROp0.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/LIROp0.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,74 +0,0 @@ -/* - * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.compiler.lir; - -import com.sun.cri.ci.*; - -/** - * The {@code LIROp0} class definition. - * - * @author Marcelo Cintra - * - */ -public class LIROp0 extends LIRInstruction { - - /** - * Creates a LIROp0 instruction. - * - * @param opcode the opcode of the new instruction - */ - public LIROp0(LIROpcode opcode) { - this(opcode, CiValue.IllegalValue); - } - - /** - * Creates a LIROp0 instruction. - * - * @param opcode the opcode of the new instruction - * @param result the result operand to the new instruction - */ - public LIROp0(LIROpcode opcode, CiValue result) { - this(opcode, result, null); - } - - /** - * Creates a LIROp0 instruction. - * - * @param opcode the opcode of the new instruction - * @param result the result operand to the new instruction - * @param info used to emit debug information associated to this instruction - */ - public LIROp0(LIROpcode opcode, CiValue result, LIRDebugInfo info) { - super(opcode, result, info, false); - assert isInRange(opcode, LIROpcode.BeginOp0, LIROpcode.EndOp0) : "Opcode " + opcode + " is invalid for a LIROP0 instruction"; - } - - /** - * Emit assembly code for this instruction. - * @param masm the target assembler - */ - @Override - public void emitCode(LIRAssembler masm) { - masm.emitOp0(this); - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/LIROp1.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/LIROp1.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,177 +0,0 @@ -/* - * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.compiler.lir; - -import com.oracle.max.graal.compiler.util.*; -import com.sun.cri.ci.*; - -/** - * The {@code LIROp1} class definition. The LIROp1 instruction has only one input operand. - * - * @author Marcelo Cintra - */ -public class LIROp1 extends LIRInstruction { - - public enum LIRMoveKind { - Normal, Volatile, Unaligned - } - - public final CiKind kind; // the operand type - public final LIRMoveKind moveKind; // flag that indicate the kind of move - - /** - * Constructs a new LIROp1 instruction. - * - * @param opcode the instruction's opcode - * @param opr the first input operand - * @param result the operand that holds the result of this instruction - * @param kind the kind of this instruction - * @param info the object holding information needed to emit debug information - */ - public LIROp1(LIROpcode opcode, CiValue opr, CiValue result, CiKind kind, LIRDebugInfo info) { - super(opcode, result, info, false, 0, 0, opr); - this.kind = kind; - this.moveKind = LIRMoveKind.Normal; - assert isInRange(opcode, LIROpcode.BeginOp1, LIROpcode.EndOp1) : "The " + opcode + " is not a valid LIROp1 opcode"; - } - - /** - * Constructs a new LIROp1 instruction. - * - * @param opcode the instruction's opcode - * @param opr the first input operand - * @param result the operand that holds the result of this instruction - * @param kind the kind of this instruction - */ - public LIROp1(LIROpcode opcode, CiValue opr, CiValue result, CiKind kind) { - this(opcode, opr, result, kind, null); - } - - /** - * Constructs a new LIROp1 instruction. - * - * @param opcode the instruction's opcode - * @param opr the first input operand - * @param result the operand that holds the result of this instruction - */ - public LIROp1(LIROpcode opcode, CiValue opr, CiValue result) { - this(opcode, opr, result, CiKind.Illegal); - } - - /** - * Constructs a new LIROp1 instruction. - * - * @param opcode the instruction's opcode - * @param opr the first input operand - */ - public LIROp1(LIROpcode opcode, CiValue opr) { - this(opcode, opr, CiValue.IllegalValue); - } - - /** - * Constructs a new LIROp1 instruction. - * - * @param moveKind the kind of move the instruction represents - * @param operand the single input operand - * @param result the operand that holds the result of this instruction - * @param kind the kind of this instruction - * @param info the object holding information needed to emit debug information - */ - public LIROp1(LIRMoveKind moveKind, CiValue operand, CiValue result, CiKind kind, LIRDebugInfo info) { - super(LIROpcode.Move, result, info, false, 0, 0, operand); - this.kind = kind; - this.moveKind = moveKind; - } - - /** - * Constructs a new LIROp1 instruction. - * - * @param opcode the instruction's opcode - * @param opr the first input operand - * @param info the object holding information needed to emit debug information - */ - public LIROp1(LIROpcode opcode, CiValue opr, LIRDebugInfo info) { - super(opcode, CiValue.IllegalValue, info, false, 0, 0, opr); - this.kind = CiKind.Illegal; - this.moveKind = LIRMoveKind.Normal; - assert isInRange(opcode, LIROpcode.BeginOp1, LIROpcode.EndOp1) : "The " + opcode + " is not a valid LIROp1 opcode"; - } - - /** - * Gets the input operand of this instruction. - * - * @return opr the input operand. - */ - public CiValue operand() { - return operand(0); - } - - /** - * Gets the kind of move of this instruction. - * - * @return flags the constant that represents the move kind. - */ - public LIRMoveKind moveKind() { - assert code == LIROpcode.Move : "The opcode must be of type LIROpcode.Move in LIROp1"; - return moveKind; - } - - @Override - public void emitCode(LIRAssembler masm) { - masm.emitOp1(this); - } - - @Override - public String name() { - if (code == LIROpcode.Move) { - switch (moveKind()) { - case Normal: - return "move"; - case Unaligned: - return "unaligned move"; - case Volatile: - return "volatile_move"; - default: - throw Util.shouldNotReachHere(); - } - } else { - return super.name(); - } - } - - @Override - public boolean verify() { - switch (code) { - case Move: - assert (operand().isLegal()) && (result().isLegal()) : "Operand and result must be valid in a LIROp1 move instruction."; - break; - case NullCheck: - assert operand().isVariableOrRegister() : "Operand must be a register in a LIROp1 null check instruction."; - break; - case Return: - assert operand().isVariableOrRegister() || operand().isIllegal() : "Operand must be (register | illegal) in a LIROp1 return instruction."; - break; - } - return true; - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/LIROp2.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/LIROp2.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,184 +0,0 @@ -/* - * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.compiler.lir; - -import com.oracle.max.graal.nodes.calc.*; -import com.sun.cri.ci.*; - -/** - * The {@code LIROp2} class represents a LIR instruction that performs an operation on two operands. - * - * @author Marcelo Cintra - * @author Thomas Wuerthinger - * @author Ben L. Titzer - */ -public class LIROp2 extends LIRInstruction { - - final Condition condition; - - /** - * Constructs a new LIROp2 instruction. - * - * @param opcode the instruction's opcode - * @param condition the instruction's condition - * @param opr1 the first input operand - * @param opr2 the second input operand - * @param info the object holding information needed to emit debug information - */ - public LIROp2(LIROpcode opcode, Condition condition, CiValue opr1, CiValue opr2, LIRDebugInfo info) { - super(opcode, CiValue.IllegalValue, info, false, 0, 0, opr1, opr2); - this.condition = condition; - assert opcode == LIROpcode.Cmp : "Instruction opcode should be of type LIROpcode.Cmp"; - } - - /** - * Constructs a new LIROp2 instruction. - * - * @param opcode the instruction's opcode - * @param condition the instruction's condition - * @param opr1 the first input operand - * @param opr2 the second input operand - * @param result the operand that holds the result of this instruction - */ - public LIROp2(LIROpcode opcode, Condition condition, CiValue opr1, CiValue opr2, CiValue result) { - super(opcode, result, null, false, 0, 0, opr1, opr2); - this.condition = condition; - assert opcode == LIROpcode.Cmove || opcode == LIROpcode.FCmove || opcode == LIROpcode.UFCmove : "Instruction opcode should be of type LIROpcode.Cmove"; - } - - /** - * Constructs a new LIROp2 instruction. - * - * @param opcode the instruction's opcode - * @param opr1 the first input operand - * @param opr2 the second input operand - * @param result the operand that holds the result of this instruction - * @param info the object holding information needed to emit debug information - * @param kind the kind of this instruction - */ - public LIROp2(LIROpcode opcode, CiValue opr1, CiValue opr2, CiValue result, LIRDebugInfo info, CiKind kind, boolean hasCall) { - super(opcode, result, info, hasCall, 0, 0, opr1, opr2); - this.condition = null; - assert opcode != LIROpcode.Cmp && isInRange(opcode, LIROpcode.BeginOp2, LIROpcode.EndOp2) : "The " + opcode + " is not a valid LIROp2 opcode"; - } - - /** - * Constructs a new LIROp2 instruction. - * - * @param opcode the instruction's opcode - * @param opr1 the instruction's first operand - * @param opr2 the instruction's second operand - * @param result the operand that holds the result of this instruction - * @param info the object holding information needed to emit debug information - */ - public LIROp2(LIROpcode opcode, CiValue opr1, CiValue opr2, CiValue result, LIRDebugInfo info) { - this(opcode, opr1, opr2, result, info, CiKind.Illegal, false); - } - - /** - * Constructs a new LIROp2 instruction. - * - * @param opcode the instruction's opcode - * @param opr1 the instruction's first operand - * @param opr2 the instruction's second operand - * @param result the operand that holds the result of this instruction - */ - public LIROp2(LIROpcode opcode, CiValue opr1, CiValue opr2, CiValue result) { - this(opcode, opr1, opr2, result, (LIRDebugInfo) null); - } - - /** - * Constructs a new LIROp2 instruction. - * - * @param opcode the instruction's opcode - * @param opr1 the first input operand - * @param opr2 the second input operand - * @param result the operand that holds the result of this instruction - * @param tmp the temporary operand used by this instruction - */ - public LIROp2(LIROpcode opcode, CiValue opr1, CiValue opr2, CiValue result, CiValue tmp) { - super(opcode, result, null, false, 0, 1, opr1, opr2, tmp); - this.condition = null; - assert opcode != LIROpcode.Cmp && isInRange(opcode, LIROpcode.BeginOp2, LIROpcode.EndOp2) : "The " + opcode + " is not a valid LIROp2 opcode"; - } - - /** - * Gets the first input operand. - * - * @return opr1 the first input operand - */ - public CiValue operand1() { - return operand(0); - } - - /** - * Gets the second input operand. - * - * @return opr2 the second input operand - */ - public CiValue operand2() { - return operand(1); - } - - /** - * Gets the temporary operand of this instruction. - * - * @return tmp the temporary operand of this instruction - * - */ - public CiValue tmp() { - return operand(2); - } - - /** - * Gets the condition of this instruction, if it is a Cmp or Cmove LIR instruction. - * - * @return condition the condition of this instruction - */ - public Condition condition() { - assert code == LIROpcode.Cmp || code == LIROpcode.Cmove || code == LIROpcode.FCmove || code == LIROpcode.UFCmove : "Field access only valid for cmp and cmove"; - return condition; - } - - /** - * Emit target assembly code for this instruction. - * - * @param masm the target assembler - */ - @Override - public void emitCode(LIRAssembler masm) { - masm.emitOp2(this); - } - - /** - * Prints this instruction. - */ - @Override - public String operationString(OperandFormatter operandFmt) { - if (code == LIROpcode.Cmove) { - return condition.toString() + " " + super.operationString(operandFmt); - } - return super.operationString(operandFmt); - } -} - diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/LIROp3.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/LIROp3.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,78 +0,0 @@ -/* - * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.compiler.lir; - -import com.sun.cri.ci.*; - -/** - * The {@code LIROp3} class definition. - * - * @author Marcelo Cintra - * - */ -public class LIROp3 extends LIRInstruction { - - /** - * Creates a new LIROp3 instruction. A LIROp3 instruction represents a LIR instruction - * that has three input operands. - * - * @param opcode the instruction's opcode - * @param opr1 the first input operand - * @param opr2 the second input operand - * @param opr3 the third input operand - * @param result the result operand - * @param info the debug information, used for deoptimization, associated to this instruction - */ - public LIROp3(LIROpcode opcode, CiValue opr1, CiValue opr2, CiValue opr3, CiValue result, LIRDebugInfo info) { - super(opcode, result, info, false, 1, 1, opr1, opr2, opr3); - assert isInRange(opcode, LIROpcode.BeginOp3, LIROpcode.EndOp3) : "The " + opcode + " is not a valid LIROp3 opcode"; - } - - /** - * Gets the opr1 of this class. - * - * @return the opr1 - */ - public CiValue opr1() { - return operand(0); - } - - /** - * Gets the opr2 of this class. - * - * @return the opr2 - */ - public CiValue opr2() { - return operand(1); - } - - /** - * Emits assembly code for this instruction. - * - * @param masm the target assembler - */ - @Override - public void emitCode(LIRAssembler masm) { - masm.emitOp3(this); - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/LIROpcode.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/LIROpcode.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,109 +0,0 @@ -/* - * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.compiler.lir; - -/** - * The {@code LirOpcode} enum represents the Operation code of each LIR instruction. - * - * @author Marcelo Cintra - * @author Thomas Wuerthinger - */ -public enum LIROpcode { - // Checkstyle: stop - // @formatter:off - BeginOp0, - Label, - Breakpoint, - RuntimeCall, - Membar, - Branch, - CondFloatBranch, - EndOp0, - BeginOp1, - NullCheck, - Return, - Lea, - Neg, - TableSwitch, - Move, - Prefetchr, - Prefetchw, - Convert, - Lsb, - Msb, - MonitorAddress, - EndOp1, - BeginOp2, - Cmp, - Cmpl2i, - Ucmpfd2i, - Cmpfd2i, - Cmove, - FCmove, - UFCmove, - Add, - Sub, - Mul, - Div, - Rem, - Sqrt, - Abs, - Sin, - Cos, - Tan, - Log, - Log10, - LogicAnd, - LogicOr, - LogicXor, - Shl, - Shr, - Ushr, - CompareTo, - EndOp2, - BeginOp3, - Idiv, - Irem, - Ldiv, - Lrem, - Wdiv, - Wdivi, - Wrem, - Wremi, - EndOp3, - NativeCall, - DirectCall, - ConstDirectCall, - IndirectCall, - TemplateCall, - InstanceOf, - CheckCast, - StoreCheck, - CasLong, - CasWord, - CasObj, - CasInt, - Xir, - // @formatter:on - // Checkstyle: resume -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/LIROperand.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/LIROperand.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,134 +0,0 @@ -/* - * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.compiler.lir; - -import com.sun.cri.ci.*; - -/** - * An instruction operand. If the register allocator can modify this operand (e.g. to replace a - * variable with a register), then it will have a corresponding entry in the {@link LIRInstruction#allocatorOperands} - * list of an instruction. - * - * @author Doug Simon - */ -public class LIROperand { - - /** - * The value of the operand. - */ - CiValue value; - - LIROperand(CiValue value) { - this.value = value; - } - - /** - * Gets the value of this operand. This may still be a {@linkplain CiVariable} - * if the register allocator has not yet assigned a register or stack address to the operand. - * - * @param inst the instruction containing this operand - */ - public CiValue value(LIRInstruction inst) { - return value; - } - - @Override - public String toString() { - return value.toString(); - } - - static class LIRVariableOperand extends LIROperand { - /** - * Index into an instruction's {@linkplain LIRInstruction#allocatorOperands allocator operands}. - */ - final int index; - - LIRVariableOperand(int index) { - super(null); - this.index = index; - } - - @Override - public CiValue value(LIRInstruction inst) { - if (value == null) { - CiValue value = inst.allocatorOperands.get(index); - if (value.isVariable()) { - return value; - } - this.value = value; - } - return value; - } - - @Override - public String toString() { - if (value == null) { - return "operands[" + index + "]"; - } - return value.toString(); - } - } - - /** - * An address operand with at least one {@linkplain CiVariable variable} constituent. - */ - static class LIRAddressOperand extends LIROperand { - int base; - int index; - - LIRAddressOperand(int base, int index, CiAddress address) { - super(address); - assert base != -1 || index != -1 : "address should have at least one variable part"; - this.base = base; - this.index = index; - } - - @Override - public CiValue value(LIRInstruction inst) { - if (base != -1 || index != -1) { - CiAddress address = (CiAddress) value; - CiValue baseOperand = base == -1 ? address.base : inst.allocatorOperands.get(base); - CiValue indexOperand = index == -1 ? address.index : inst.allocatorOperands.get(index); - if (address.index.isLegal()) { - assert indexOperand.isVariableOrRegister(); - if (baseOperand.isVariable() || indexOperand.isVariable()) { - return address; - } - } else { - if (baseOperand.isVariable()) { - return address; - } - } - value = new CiAddress(address.kind, baseOperand, indexOperand, address.scale, address.displacement); - base = -1; - index = -1; - } - return value; - } - - @Override - public String toString() { - return value.toString(); - } - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/LIRSignificantBit.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/LIRSignificantBit.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,43 +0,0 @@ -/* - * Copyright (c) 2010, 2010, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.compiler.lir; - -import com.sun.cri.bytecode.*; -import com.sun.cri.ci.*; - -/** - * LIR instruction used in translating {@link Bytecodes#LSB} and {@link Bytecodes#MSB}. - * - * @author Doug Simon - */ -public class LIRSignificantBit extends LIRInstruction { - - public LIRSignificantBit(LIROpcode opcode, CiValue operand, CiValue result) { - super(opcode, result, null, false, 1, 0, operand); - } - - @Override - public void emitCode(LIRAssembler masm) { - masm.emitSignificantBitOp(code == LIROpcode.Msb, operand(0), result()); - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/LIRTableSwitch.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/LIRTableSwitch.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,89 +0,0 @@ -/* - * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.compiler.lir; - -import com.sun.cri.ci.*; - -/** - * @author Doug Simon - */ -public class LIRTableSwitch extends LIRInstruction { - - public LIRBlock defaultTarget; - - public final LIRBlock[] targets; - - public final int lowKey; - - public LIRTableSwitch(CiValue value, int lowKey, LIRBlock defaultTarget, LIRBlock[] targets) { - super(LIROpcode.TableSwitch, CiValue.IllegalValue, null, false, 1, 0, value); - this.lowKey = lowKey; - this.targets = targets; - this.defaultTarget = defaultTarget; - } - - @Override - public void emitCode(LIRAssembler masm) { - masm.emitTableSwitch(this); - } - - /** - * @return the input value to this switch - */ - public CiValue value() { - return operand(0); - } - - @Override - public String operationString(OperandFormatter operandFmt) { - StringBuilder buf = new StringBuilder(super.operationString(operandFmt)); - buf.append("\ndefault: [B").append(defaultTarget.blockID()).append(']'); - int key = lowKey; - for (LIRBlock b : targets) { - buf.append("\ncase ").append(key).append(": [B").append(b.blockID()).append(']'); - key++; - } - return buf.toString(); - } - - - private LIRBlock substitute(LIRBlock block, LIRBlock oldBlock, LIRBlock newBlock) { - if (block == oldBlock) { - LIRInstruction instr = newBlock.lir().instructionsList().get(0); - assert instr instanceof LIRLabel : "first instruction of block must be label"; - return newBlock; - } - return oldBlock; - } - - public void substitute(LIRBlock oldBlock, LIRBlock newBlock) { - if (substitute(defaultTarget, oldBlock, newBlock) == newBlock) { - defaultTarget = newBlock; - } - for (int i = 0; i < targets.length; i++) { - if (substitute(targets[i], oldBlock, newBlock) == newBlock) { - targets[i] = newBlock; - } - } - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/LIRXirInstruction.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/LIRXirInstruction.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,197 +0,0 @@ -/* - * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.compiler.lir; - -import java.util.*; - -import com.oracle.max.graal.compiler.*; -import com.oracle.max.graal.compiler.gen.*; -import com.sun.cri.ci.*; -import com.sun.cri.ri.*; -import com.sun.cri.xir.*; - -public class LIRXirInstruction extends LIRInstruction { - - public final CiValue[] originalOperands; - public final int outputOperandIndex; - public final int[] operandIndices; - public final XirSnippet snippet; - public final RiMethod method; - public final int inputTempCount; - public final int tempCount; - public final int inputCount; - public final List pointerSlots; - public final LIRDebugInfo infoAfter; - private LIRBlock trueSuccessor; - private LIRBlock falseSuccessor; - - public LIRXirInstruction(XirSnippet snippet, - CiValue[] originalOperands, - CiValue outputOperand, - int inputTempCount, - int tempCount, - CiValue[] operands, - int[] operandIndices, - int outputOperandIndex, - LIRDebugInfo info, - LIRDebugInfo infoAfter, - RiMethod method, - List pointerSlots) { - super(LIROpcode.Xir, outputOperand, info, false, inputTempCount, tempCount, operands); - this.infoAfter = infoAfter; - this.pointerSlots = pointerSlots; - assert this.pointerSlots == null || this.pointerSlots.size() >= 0; - this.method = method; - this.snippet = snippet; - this.operandIndices = operandIndices; - this.outputOperandIndex = outputOperandIndex; - this.originalOperands = originalOperands; - this.inputTempCount = inputTempCount; - this.tempCount = tempCount; - this.inputCount = operands.length - inputTempCount - tempCount; - - GraalMetrics.LIRXIRInstructions++; - } - - - public void setFalseSuccessor(LIRBlock falseSuccessor) { - this.falseSuccessor = falseSuccessor; - } - - - public void setTrueSuccessor(LIRBlock trueSuccessor) { - this.trueSuccessor = trueSuccessor; - } - - public LIRBlock falseSuccessor() { - return falseSuccessor; - } - - public LIRBlock trueSuccessor() { - return trueSuccessor; - } - - public CiValue[] getOperands() { - for (int i = 0; i < operandIndices.length; i++) { - originalOperands[operandIndices[i]] = operand(i); - } - if (outputOperandIndex != -1) { - originalOperands[outputOperandIndex] = result(); - } - return originalOperands; - } - - /** - * Emits target assembly code for this instruction. - * - * @param masm the target assembler - */ - @Override - public void emitCode(LIRAssembler masm) { - masm.emitXir(this); - } - - /** - * Prints this instruction. - */ - @Override - public String operationString(OperandFormatter operandFmt) { - return toString(operandFmt); - } - - @Override - public String toString(OperandFormatter operandFmt) { - StringBuilder sb = new StringBuilder(); - sb.append("XIR: "); - - if (result().isLegal()) { - sb.append(operandFmt.format(result()) + " = "); - } - - sb.append(snippet.template); - sb.append("("); - for (int i = 0; i < snippet.arguments.length; i++) { - XirArgument a = snippet.arguments[i]; - if (i > 0) { - sb.append(", "); - } - if (a.constant != null) { - sb.append(operandFmt.format(a.constant)); - } else { - Object o = a.object; - if (o instanceof LIRItem) { - sb.append(operandFmt.format(((LIRItem) o).result())); - } else if (o instanceof CiValue) { - sb.append(operandFmt.format((CiValue) o)); - } else { - sb.append(o); - } - } - } - sb.append(')'); - - if (method != null) { - sb.append(" method="); - sb.append(method.toString()); - } - - - for (LIRInstruction.OperandMode mode : LIRInstruction.OPERAND_MODES) { - int n = operandCount(mode); - if (mode == OperandMode.Output && n <= 1) { - // Already printed single output (i.e. result()) - continue; - } - if (n != 0) { - sb.append(' ').append(mode.name().toLowerCase()).append("=("); - HashSet operands = new HashSet(); - for (int i = 0; i < n; i++) { - String operand = operandFmt.format(operandAt(mode, i)); - if (!operands.contains(operand)) { - if (!operands.isEmpty()) { - sb.append(", "); - } - operands.add(operand); - sb.append(operand); - } - } - sb.append(')'); - } - } - - appendDebugInfo(sb, operandFmt, info); - - return sb.toString(); - } - - - public void substitute(LIRBlock block, LIRBlock newTarget) { - if (trueSuccessor == block) { - trueSuccessor = newTarget; - } - - if (falseSuccessor == block) { - falseSuccessor = newTarget; - } - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/package-info.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/package-info.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,30 +0,0 @@ -/* - * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -/** - * @author Marcelo Cintra - * @author Thomas Wuerthinger - * - * Port of the backend (LIR) of the client compiler to Java. - */ -package com.oracle.max.graal.compiler.lir; diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/observer/CompilationEvent.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/observer/CompilationEvent.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,166 +0,0 @@ -/* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.compiler.observer; - -import java.util.*; - -import com.oracle.max.graal.compiler.*; -import com.oracle.max.graal.compiler.alloc.*; -import com.oracle.max.graal.compiler.graph.*; -import com.oracle.max.graal.graph.*; -import com.sun.cri.ci.*; -import com.sun.cri.ri.*; - -/** - * An event that occurred during compilation. Instances of this class provide information about the event and the state - * of the compilation when the event was raised. {@link #getCompilation()} and {@link #getMethod()} are guaranteed to - * always return a non-{@code null} value. Other objects provided by getter methods may be {@code null}, - * depending on the available information when and where the event was triggered. - * - * @author Peter Hofer - */ -public class CompilationEvent { - - private final GraalCompilation compilation; - private final String label; - private Graph graph; - - private BlockMap blockMap; - private int codeSize = -1; - - private LinearScan allocator; - private CiTargetMethod targetMethod; - private boolean hirValid = false; - private boolean lirValid = false; - private boolean errorEvent; - private Map debugObjects; - - private Interval[] intervals; - private int intervalsSize; - private Interval[] intervalsCopy = null; - - public CompilationEvent(GraalCompilation compilation) { - this(compilation, null); - } - - private CompilationEvent(GraalCompilation compilation, String label) { - assert compilation != null; - this.label = label; - this.compilation = compilation; - } - - public CompilationEvent(GraalCompilation compilation, String label, Graph graph, boolean hirValid, boolean lirValid) { - this(compilation, label, graph, hirValid, lirValid, false, (Map) null); - } - public CompilationEvent(GraalCompilation compilation, String label, Graph graph, boolean hirValid, boolean lirValid, boolean error) { - this(compilation, label, graph, hirValid, lirValid, error, (Map) null); - } - - public CompilationEvent(GraalCompilation compilation, String label, Graph graph, boolean hirValid, boolean lirValid, Map debugObjects) { - this(compilation, label, graph, hirValid, lirValid, false, debugObjects); - } - - public CompilationEvent(GraalCompilation compilation, String label, Graph graph, boolean hirValid, boolean lirValid, boolean error, Map debugObjects) { - this(compilation, label); - this.graph = graph; - this.hirValid = hirValid; - this.lirValid = lirValid; - this.debugObjects = debugObjects; - this.errorEvent = error; - } - - public CompilationEvent(GraalCompilation compilation, String label, Graph graph, boolean hirValid, boolean lirValid, CiTargetMethod targetMethod) { - this(compilation, label, graph, hirValid, lirValid); - this.targetMethod = targetMethod; - } - - public CompilationEvent(GraalCompilation compilation, String label, BlockMap blockMap, int codeSize) { - this(compilation, label); - this.blockMap = blockMap; - this.codeSize = codeSize; - } - - public CompilationEvent(GraalCompilation compilation, String label, LinearScan allocator, Interval[] intervals, int intervalsSize) { - this(compilation, label); - this.allocator = allocator; - this.intervals = intervals; - this.intervalsSize = intervalsSize; - } - - public GraalCompilation getCompilation() { - return compilation; - } - - public String getLabel() { - return label; - } - - public RiMethod getMethod() { - return compilation.method; - } - - public BlockMap getBlockMap() { - return blockMap; - } - - public Graph getGraph() { - return graph; - } - - public LinearScan getAllocator() { - return allocator; - } - - public CiTargetMethod getTargetMethod() { - return targetMethod; - } - - public boolean isHIRValid() { - return hirValid; - } - - public boolean isLIRValid() { - return lirValid; - } - - public boolean isErrorEvent() { - return errorEvent; - } - - public Interval[] getIntervals() { - if (intervalsCopy == null && intervals != null) { - // deferred copy of the valid range of the intervals array - intervalsCopy = Arrays.copyOf(intervals, intervalsSize); - } - return intervalsCopy; - } - - public int getCodeSize() { - return codeSize; - } - - - public Map getDebugObjects() { - return debugObjects; - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/observer/CompilationObserver.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/observer/CompilationObserver.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,57 +0,0 @@ -/* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.compiler.observer; - -import com.oracle.max.graal.compiler.*; - -/** - * Interface for classes that observe events of an {@link ObservableCompiler}. - * - * @author Peter Hofer - */ -public interface CompilationObserver { - - /** - * Called when compilation of a method has started. This is always the first event raised for a particular - * {@link GraalCompilation}. - * - * @param event Information associated with the event and current state of the compilation. - */ - void compilationStarted(CompilationEvent event); - - /** - * Called when an event has occurred, for example that a particular phase in the compilation has been entered. - * - * @param event Information associated with the event and current state of the compilation. - */ - void compilationEvent(CompilationEvent event); - - /** - * Called when compilation of a method has completed (successfully or not). This is always the last event raised for - * a particular {@link GraalCompilation}. - * - * @param event Information associated with the event and current state of the compilation. - */ - void compilationFinished(CompilationEvent event); - -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/observer/ObservableCompiler.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/observer/ObservableCompiler.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,99 +0,0 @@ -/* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.compiler.observer; - -import java.util.*; - -import com.oracle.max.graal.compiler.debug.*; - -/** - * Base class for compilers that notify subscribed {@link CompilationObserver CompilationObservers} of - * {@link CompilationEvent CompilationEvents} that occur during their compilations. - * - * @author Peter Hofer - */ -public class ObservableCompiler { - - private List observers; - - /** - * @return {@code true} if one or more observers are subscribed to receive notifications from this compiler, - * {@code false} otherwise. - */ - public boolean isObserved() { - return observers != null && !TTY.isSuppressed(); - } - - /** - * Add the specified observer to receive events from this compiler. - * - * @param observer The observer to add. - */ - public void addCompilationObserver(CompilationObserver observer) { - assert observer != null; - - if (observers == null) { - observers = new LinkedList(); - } - observers.add(observer); - } - - public void fireCompilationStarted(CompilationEvent event) { - if (isObserved()) { - for (CompilationObserver observer : observers) { - observer.compilationStarted(event); - } - } - } - - public void fireCompilationEvent(CompilationEvent event) { - if (isObserved()) { - for (CompilationObserver observer : observers) { - observer.compilationEvent(event); - } - } - } - - public void fireCompilationFinished(CompilationEvent event) { - if (isObserved()) { - for (CompilationObserver observer : observers) { - observer.compilationFinished(event); - } - } - } - - /** - * Remove the specified observer so that it no longer receives events from this compiler. - * - * @param observer The observer to remove. - */ - public void removeCompilationObserver(CompilationObserver observer) { - if (observers != null) { - observers.remove(observer); - if (observers.size() == 0) { - observers = null; - } - } - } - -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/observer/package-info.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/observer/package-info.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,29 +0,0 @@ -/* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -/** - * Classes and interfaces for observing compilations. - * - * @author Peter Hofer - */ -package com.oracle.max.graal.compiler.observer; diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/package-info.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/package-info.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,186 +0,0 @@ -/* - * Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -/** - * The top-level package in Graal containing options, metrics, timers and the main compiler class - * {@link com.oracle.max.graal.compiler.GraalCompiler}. - * - *

{@code GraalCompiler} Overview

- * - * Graal is intended to be used with multiple JVM's so makes no use of or reference to classes for a specific JVM, for - * example Maxine. - * - * The compiler is represented by the class {@code GraalCompiler}. {@code GraalCompiler} binds a specific target - * architecture and JVM interface to produce a usable compiler object. There are - * two variants of {@code compileMethod}, one of which is used when doing on stack replacement (OSR), discussed - * later. The main variant takes {@link com.sun.cri.ri.RiMethod} and {@link com.sun.cri.xir.RiXirGenerator} arguments. - * {@code RiMethod} is Graal's representation of a Java method and {@code RiXirGenerator} represents the interface through - * which the compiler requests the XIR for a given bytecode from the runtime system. - * - *

The Graal Compilation Process

- * - * {@link com.oracle.max.graal.compiler.GraalCompiler#compileMethod} creates a {@link GraalCompilation} instance and then returns the result of calling its - * {@link com.oracle.max.graal.compiler.GraalCompilation#compile} method. The {@code GraalCompilation} instance records whether {@code compileMethod} was invoked with - * the OSR variant, which is used later in the IR generation. - *

- * While there is only one {@code GraalCompiler} instance, there may be several compilations proceeding concurrently, each of - * which is represented by a unique {@code GraalCompilation} instance. The static method {@link com.oracle.max.graal.compiler.GraalCompilation#current}} returns the - * {@code GraalCompilation} instance associated with the current thread, and is managed using a {@link java.lang.ThreadLocal} variable. It - * is used when assigning the unique id that is used for tracing output to an HIR node. Each {@code GraalCompilation} instance - * has an associated {@link com.sun.cri.ci.CiStatistics} object that accumulates information about the compilation process, but is also - * used as a generator of, for example, basic block identifiers. - *

- * The compilation begins by calling {@link com.oracle.max.graal.compiler.GraalCompilation#emitHIR}, which creates the high-level intermediate representation (HIR) from the - * bytecodes of the method. The HIR is managed by the {@link com.oracle.max.graal.compiler.graph.IR} class, an instance of which is created by - * {@code emitHR}, which then calls the {{@link com.oracle.max.graal.compiler.graph.IR#build}} method and returns the result. The {@code GraalCompilation} and {@code IR} - * instances are are bi-directionally linked. - * - *

Supported backends

- * - *
    - *
  • AMD64/x64 with SSE2
  • - *
- * - *

Notes and Todos

This is a collection of notes about the Graal compiler, including future directions, - * refactorings, missing features, broken features, etc. - * - * - *

Anticipated Refactorings

- * - *
    - *
  • - * The HIR nodes {@link com.oracle.max.graal.compiler.ir.UnsafePrefetch}, {@link com.oracle.max.graal.compiler.ir.UnsafePutObject}, etc should be replaced by uses of the newer - * {@link com.oracle.max.graal.compiler.ir.LoadPointer} and {@link com.oracle.max.graal.compiler.ir.StorePointer} nodes. Currently, the unsafe nodes are only generated by - * the creation of an OSR entry. Benefit: reduce the number of different IR nodes.
  • - * - *
  • - * Add a field to optionally store an {@link com.oracle.max.graal.compiler.ir.Info} object for each HIR node, and remove the - * {@link com.oracle.max.graal.nodes.FixedWithNextNode#exceptionHandlers} field, the {@link com.oracle.max.graal.nodes.FixedWithNextNode#bci} field, and any fields to store the Java - * frame state in subclasses. Benefit: saves space if most HIR nodes do not have exception handlers, a bci or Java frame - * state. Removes virtual dispatch on accessing debug information for nodes. Allows any node, regardless of its type, to - * have info attached.
  • - * - *
  • - * Migrate all HIR nodes to use the immutable {@link com.oracle.max.graal.compiler.value.FrameStateInfo} for debugging information. The {@link com.oracle.max.graal.compiler.value.FrameState} - * class is mutable and used throughout graph building. Benefit: {@code FrameStateInfo} would save both total space in - * the IR graph prevent many bugs due to the mutability of {@code FrameState}.
  • - * - *
  • - * Move the {@code FrameState} class to an inner class, or combine entirely, with the {@link com.oracle.max.graal.compiler.phases.GraphBuilderPhase} class. After - * the introduction of the {@code FrameStateInfo} into HIR nodes, the mutable value stack should only need to be - * accessed from the graph builder.
  • - * - *
- * - *

Missing or incomplete features

- * - * There are some features of C1 that were not ported forward or finished given the time constraints for the Graal port. A - * list appears below. - * - *
    - *
  • - * Deoptimization metadata. The locations of all local variables and stack values are not communicated back to the - * runtime system through the {@link com.sun.cri.ci.CiDebugInfo} class yet. Such values are known to the register allocator, and there - * vestigial logic to compute them still there in the - * {@link com.oracle.max.graal.compiler.alloc.LinearScan#computeDebugInfo} method. To complete this metadata, the - * {@link com.oracle.max.graal.compiler.alloc.LinearScan} class must implement the {@link ValueLocator} interface and pass it to the - * {@link com.oracle.max.graal.compiler.lir.LIRDebugInfo#createFrame} method after register allocation. The - * resulting debug info will be fed back to the runtime system by the existing logic that calls - * {@link com.sun.cri.ci.CiTargetMethod#recordCall(int, Object, CiDebugInfo, boolean)} and other methods. Obviously the runtime - * system will need to encode this metadata in a dense format, because it is huge.
  • - * - * - *
  • - * Tiered compilation support. C1 supported the ability to add instrumentation to branches, invocations, and checkcasts - * in order to feed profile information to the C2 compiler in a tiered compilation setup. It relied on adding some - * information to the HIR nodes that represent these operations ({@link InvokeNode}, {@link CheckCastNode}, etc). All of this - * logic was removed to simplify both the front end and back end in anticipation of designing a future instrumentation - * API. XIR should be general enough to allow instrumentation code to be added to invocation and checkcast sites, but - * currently has no support for adding code at branches. - * - *
  • - * - *
  • - * SPARC and other architecture support. There pretty well-delineated separation between the architecture-independent - * part of LIR backend and the architecture-dependent, but the only implementation that current exists is the X86 - * backend ({@link com.oracle.max.graal.compiler.target.amd64.AMD64Backend}, {@link com.oracle.max.graal.compiler.target.amd64.AMD64LIRGenerator}, {@link com.oracle.max.graal.compiler.target.amd64.AMD64LIRAssembler}, etc).
  • - * - *
  • - * XIR for safepoints. The Graal backend should use XIR to get the code for safepoints, but currently it still uses the - * handwritten logic (currently only compatible with Maxine).
  • - * - *
- * - *

Untested features

- * - *
    - * - *
  • - * Reference map for outgoing overflow arguments. If a Graal method calls another method that has overflow arguments, it - * is not clear if the outgoing overflow argument area, which may contain references, has the appropriate bits set in - * the reference map for the Graal method's frame. Such arguments may be live in the called method.
  • - * - *
  • - * Although it should work, inlining synchronized methods or methods with exception handlers hasn't been tested.
  • - *
  • - * On-stack replacement. Graal retains all of the special logic for performing an OSR compilation. This is basically a - * compilation with a second entrypoint for entry from the interpreter. However, the generation of a runtime-specific - * entry sequence was never tested.
  • - * - *
  • - * {@link com.oracle.max.graal.compiler.GraalIntrinsic Intrinsification} is the mechanism by which the compiler recognizes calls to special JDK or - * runtime methods and replaces them with custom code. It is enabled by the {@link com.oracle.max.graal.compiler.GraalOptions#OptIntrinsify} compiler - * option. The Graal backend has never been tested with intrinsified arithmetic or floating point operations. For best - * performance, it should generate specialized machine code for arithmetic and floating point, perhaps using global - * stubs for complex floating point operations.
    - * Note: Folding of special intrinsified methods is supported, tested, and working. The runtime system may - * register methods to be folded by using the - * {@link com.oracle.max.graal.compiler.GraalIntrinsic#registerFoldableMethod(RiMethod, java.lang.reflect.Method)} call. When the compiler encounters a - * call to such a registered method where the parameters are all constants, it invokes the supplied method with - * reflection. If the reflective call produces a value and does not throw an exception, Graal replaces the call to the - * method with the result.
  • - *
- * - *

Broken features

- * - *
    - *
  • - * {@link com.oracle.max.graal.compiler.opt.LoopPeeler Loop peeling} was written by Marcelo Cintra near the end of his internship. It was never completed - * and should be considered broken. It only remains as a sketch of how loop peeling would be implemented in Graal, or in - * case he would finish the implementation and test it.
  • - * - *
  • - * Calls to global stubs should allocate space on the caller's stack. On AMD64 currently, calls to global stubs poke the - * arguments onto the stack below the RSP (i.e. in the callee's stack). While normally this code sequence is - * uninterruptible and works fine in the VM, signal handlers triggered when debugging or inspecting this code sequence - * may destroy these values when the OS calls the signal handler. This requires knowing which global stubs are called - * before finalizing the frame size; currently only the calls to - * {@link com.oracle.max.graal.compiler.target.amd64.AMD64MacroAssembler#callRuntimeCalleeSaved} - * do not fit this pattern. This needs to be fixed so that all global stubs that are called by the assembled code are - * known before beginning assembling. The {@link com.oracle.max.graal.compiler.target.amd64.AMD64GlobalStubEmitter} controls how the global stubs accept their - * parameters. See {@link com.oracle.max.graal.compiler.target.amd64.AMD64GlobalStubEmitter#callerFrameContainsArguments} and its usages. - * - *
  • - *
- */ -package com.oracle.max.graal.compiler; diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/CanonicalizerPhase.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/CanonicalizerPhase.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,74 +0,0 @@ -/* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.compiler.phases; - -import com.oracle.max.graal.compiler.*; -import com.oracle.max.graal.compiler.debug.*; -import com.oracle.max.graal.graph.*; -import com.oracle.max.graal.graph.collections.*; -import com.oracle.max.graal.nodes.spi.*; - -public class CanonicalizerPhase extends Phase { - private static final int MAX_ITERATION_PER_NODE = 10; - - private boolean newNodes; - - public CanonicalizerPhase() { - this(false); - } - - public CanonicalizerPhase(boolean newNodes) { - this.newNodes = newNodes; - } - - @Override - protected void run(Graph graph) { - final NodeWorkList nodeWorkList = graph.createNodeWorkList(!newNodes, MAX_ITERATION_PER_NODE); - if (newNodes) { - nodeWorkList.addAll(graph.getNewNodes()); - } - NotifyReProcess reProcess = new NotifyReProcess() { - @Override - public void reProccess(Node n) { - nodeWorkList.addAgain(n); - } - }; - for (Node node : nodeWorkList) { - if (node instanceof Canonicalizable) { - if (GraalOptions.TraceCanonicalizer) { - TTY.println("Canonicalizer: work on " + node); - } - graph.mark(); - Node canonical = ((Canonicalizable) node).canonical(reProcess); - if (canonical != node) { - node.replaceAndDelete(canonical); - for (Node newNode : graph.getNewNodes()) { - nodeWorkList.add(newNode); - } - nodeWorkList.replaced(canonical, node, false, EdgeType.USAGES); - GraalMetrics.NodesCanonicalized++; - } - } - } - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/ComputeProbabilityPhase.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/ComputeProbabilityPhase.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,294 +0,0 @@ -/* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.compiler.phases; - -import java.util.*; - -import com.oracle.max.graal.compiler.*; -import com.oracle.max.graal.compiler.debug.*; -import com.oracle.max.graal.compiler.graph.*; -import com.oracle.max.graal.compiler.observer.*; -import com.oracle.max.graal.graph.*; -import com.oracle.max.graal.nodes.*; - -public class ComputeProbabilityPhase extends Phase { - private static final double EPSILON = 1d / Integer.MAX_VALUE; - - /* - * The computation of absolute probabilities works in three steps: - * - * - The first step, "PropagateProbability", traverses the graph in post order (merges after their ends, ...) and keeps track of the "probability state". - * Whenever it encounters a ControlSplit it uses the splits probability information to divide the probability upon the successors. - * Whenever it encounters an Invoke it assumes that the exception edge is unlikely and propagates the whole probability to the normal successor. - * Whenever it encounters a Merge it sums up the probability of all predecessors. - * It also maintains a set of active loops (whose LoopBegin has been visited) and builds def/use information for the second step. - * - * - The third step propagates the loop frequencies and multiplies each FixedNode's probability with its loop frequency. - * - * TODO: add exception probability information to Invokes - */ - - @Override - protected void run(Graph graph) { - new PropagateProbability((FixedNode) graph.start().next()).apply(); - GraalCompilation compilation = GraalCompilation.compilation(); - if (compilation.compiler.isObserved() && GraalOptions.TraceProbability) { - compilation.compiler.fireCompilationEvent(new CompilationEvent(compilation, "After PropagateProbability", graph, true, false)); - } - computeLoopFactors(); - if (compilation.compiler.isObserved() && GraalOptions.TraceProbability) { - compilation.compiler.fireCompilationEvent(new CompilationEvent(compilation, "After computeLoopFactors", graph, true, false)); - } - new PropagateLoopFrequency((FixedNode) graph.start().next()).apply(); - } - - private void computeLoopFactors() { - if (GraalOptions.TraceProbability) { - for (LoopInfo info : loopInfos) { - TTY.println("\nLoop " + info.loopBegin); - TTY.print(" requires: "); - for (LoopInfo r : info.requires) { - TTY.print(r.loopBegin + " "); - } - TTY.println(); - } - } - for (LoopInfo info : loopInfos) { - double frequency = info.loopFrequency(); - assert frequency != -1; - } - } - - private static boolean isRelativeProbability(double prob) { - // 1.01 to allow for some rounding errors - return prob >= 0 && prob <= 1.01; - } - - public static class LoopInfo { - public final LoopBeginNode loopBegin; - - public final Set requires = new HashSet(4); - - private double loopFrequency = -1; - public boolean ended = false; - - public LoopInfo(LoopBeginNode loopBegin) { - this.loopBegin = loopBegin; - } - - public double loopFrequency() { - if (loopFrequency == -1 && ended) { - double factor = 1; - for (LoopInfo required : requires) { - double t = required.loopFrequency(); - if (t == -1) { - return -1; - } - factor *= t; - } - double d = loopBegin.loopEnd().probability() * factor; - if (d < EPSILON) { - d = EPSILON; - } else if (d > loopBegin.probability() - EPSILON) { - d = loopBegin.probability() - EPSILON; - } - loopFrequency = loopBegin.probability() / (loopBegin.probability() - d); - loopBegin.setLoopFrequency(loopFrequency); -// TTY.println("computed loop Frequency %f for %s", loopFrequency, loopBegin); - } - return loopFrequency; - } - } - - public Set loopInfos = new HashSet(); - public Map> mergeLoops = new HashMap>(); - - private class Probability implements MergeableState { - public double probability; - public HashSet loops; - public LoopInfo loopInfo; - - public Probability(double probability, HashSet loops) { - this.probability = probability; - this.loops = new HashSet(4); - if (loops != null) { - this.loops.addAll(loops); - } - } - - @Override - public Probability clone() { - return new Probability(probability, loops); - } - - @Override - public boolean merge(MergeNode merge, Collection withStates) { - if (merge.endCount() > 1) { - HashSet intersection = new HashSet(loops); - for (Probability other : withStates) { - intersection.retainAll(other.loops); - } - for (LoopInfo info : loops) { - if (!intersection.contains(info)) { - // TTY.println("probability for %s at %s", info.loopBegin, merge); - double loopFrequency = info.loopFrequency(); - if (loopFrequency == -1) { - // TTY.println("re-queued " + merge); - return false; - } - probability *= loopFrequency; - } - } - for (Probability other : withStates) { - double prob = other.probability; - for (LoopInfo info : other.loops) { - if (!intersection.contains(info)) { - // TTY.println("probability for %s at %s", info.loopBegin, merge); - double loopFrequency = info.loopFrequency(); - if (loopFrequency == -1) { - // TTY.println("re-queued " + merge); - return false; - } - prob *= loopFrequency; - } - } - probability += prob; - } - loops = intersection; - // TTY.println("merged " + merge); - mergeLoops.put(merge, new HashSet(intersection)); - assert isRelativeProbability(probability) : probability; - } - return true; - } - - @Override - public void loopBegin(LoopBeginNode loopBegin) { - loopInfo = new LoopInfo(loopBegin); - loopInfos.add(loopInfo); - loops.add(loopInfo); - } - - @Override - public void loopEnd(LoopEndNode loopEnd, Probability loopEndState) { - assert loopInfo != null; - for (LoopInfo innerLoop : loopEndState.loops) { - if (innerLoop != loopInfo && !loops.contains(innerLoop)) { - loopInfo.requires.add(innerLoop); - } - } - loopInfo.ended = true; - } - - @Override - public void afterSplit(FixedNode node) { - assert node.predecessor() != null; - Node pred = node.predecessor(); - if (pred instanceof InvokeNode) { - InvokeNode x = (InvokeNode) pred; - if (x.next() != node) { - probability = 0; - } - } else { - assert pred instanceof ControlSplitNode; - ControlSplitNode x = (ControlSplitNode) pred; - double sum = 0; - for (int i = 0; i < x.blockSuccessorCount(); i++) { - if (x.blockSuccessor(i) == node) { - sum += x.probability(i); - } - } - probability *= sum; - } - } - } - - private class PropagateProbability extends PostOrderNodeIterator { - - public PropagateProbability(FixedNode start) { - super(start, new Probability(1d, null)); - } - - @Override - protected void node(FixedNode node) { -// TTY.println(" -- %7.5f %s", state.probability, node); - node.setProbability(state.probability); - } - } - - private class LoopCount implements MergeableState { - public double count; - - public LoopCount(double count) { - this.count = count; - } - - @Override - public LoopCount clone() { - return new LoopCount(count); - } - - @Override - public boolean merge(MergeNode merge, Collection withStates) { - assert merge.endCount() == withStates.size() + 1; - if (merge.endCount() > 1) { - Set loops = mergeLoops.get(merge); -// TTY.println("merging count for %s: %d ends, %d loops", merge, merge.endCount(), loops.size()); - assert loops != null; - double countProd = 1; - for (LoopInfo loop : loops) { - countProd *= loop.loopFrequency(); - } - count = countProd; - } - return true; - } - - @Override - public void loopBegin(LoopBeginNode loopBegin) { - count *= loopBegin.loopFrequency(); - } - - @Override - public void loopEnd(LoopEndNode loopEnd, LoopCount loopEndState) { - // nothing to do... - } - - @Override - public void afterSplit(FixedNode node) { - // nothing to do... - } - } - - private class PropagateLoopFrequency extends PostOrderNodeIterator { - - public PropagateLoopFrequency(FixedNode start) { - super(start, new LoopCount(1d)); - } - - @Override - protected void node(FixedNode node) { - node.setProbability(node.probability() * state.count); - } - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/DeadCodeEliminationPhase.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/DeadCodeEliminationPhase.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,153 +0,0 @@ -/* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.compiler.phases; - -import com.oracle.max.graal.compiler.*; -import com.oracle.max.graal.compiler.debug.*; -import com.oracle.max.graal.compiler.gen.*; -import com.oracle.max.graal.graph.*; -import com.oracle.max.graal.graph.collections.*; -import com.oracle.max.graal.nodes.*; -import com.oracle.max.graal.nodes.extended.*; - - -public class DeadCodeEliminationPhase extends Phase { - - private NodeFlood flood; - private Graph graph; - - @Override - protected void run(Graph graph) { - this.graph = graph; - this.flood = graph.createNodeFlood(); - - flood.add(graph.start()); - iterateSuccessors(); - disconnectCFGNodes(); - iterateInputs(); - deleteNodes(); - - // remove chained Merges - for (MergeNode merge : graph.getNodes(MergeNode.class)) { - if (merge.endCount() == 1 && !(merge instanceof LoopBeginNode)) { - replacePhis(merge); - EndNode endNode = merge.endAt(0); - FixedNode next = merge.next(); - merge.delete(); - endNode.replaceAndDelete(next); - } - } - - new PhiSimplifier(graph); - } - - private void iterateSuccessors() { - for (Node current : flood) { - if (current instanceof EndNode) { - EndNode end = (EndNode) current; - flood.add(end.merge()); - } else { - for (Node successor : current.successors()) { - flood.add(successor); - } - } - - if (current instanceof AbstractVectorNode) { - for (Node usage : current.usages()) { - flood.add(usage); - } - } - } - } - - private void disconnectCFGNodes() { - for (Node node : graph.getNodes()) { - if (!flood.isMarked(node)) { - if (node instanceof EndNode) { - EndNode end = (EndNode) node; - MergeNode merge = end.merge(); - if (merge != null && flood.isMarked(merge)) { - // We are a dead end node leading to a live merge. - merge.removeEnd(end); - } - } else if (node instanceof LoopEndNode) { - LoopBeginNode loop = ((LoopEndNode) node).loopBegin(); - if (flood.isMarked(loop)) { - if (GraalOptions.TraceDeadCodeElimination) { - TTY.println("Removing loop with unreachable end: " + loop); - } - ((LoopEndNode) node).setLoopBegin(null); - EndNode endNode = loop.endAt(0); - assert endNode.predecessor() != null; - replacePhis(loop); - loop.removeEnd(endNode); - - FixedNode next = loop.next(); - loop.setNext(null); - endNode.replaceAndDelete(next); - loop.delete(); - } - } - } - } - } - - private void replacePhis(MergeNode merge) { - for (Node usage : merge.usages().snapshot()) { - assert usage instanceof PhiNode; - usage.replaceAndDelete(((PhiNode) usage).valueAt(0)); - } - } - - private void deleteNodes() { - for (Node node : graph.getNodes()) { - if (!flood.isMarked(node)) { - node.clearEdges(); - } - } - for (Node node : graph.getNodes()) { - if (!flood.isMarked(node)) { - node.delete(); - } - } - } - - private void iterateInputs() { - for (Node node : graph.getNodes()) { - if (node instanceof LocalNode) { - flood.add(node); - } - if (flood.isMarked(node)) { - for (Node input : node.inputs()) { - flood.add(input); - } - } - } - for (Node current : flood) { - for (Node input : current.inputs()) { - flood.add(input); - } - } - } - -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/DuplicationPhase.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/DuplicationPhase.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,61 +0,0 @@ -/* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.compiler.phases; - -import java.util.*; - -import com.oracle.max.graal.graph.*; -import com.oracle.max.graal.nodes.*; - -/** - * Duplicates every node in the graph to test the implementation of the {@link com.oracle.max.graal.graph.Node#copy()} method in node subclasses. - */ -public class DuplicationPhase extends Phase { - - @Override - protected void run(Graph graph) { - - // Create duplicate graph. - CompilerGraph duplicate = new CompilerGraph(((CompilerGraph) graph).runtime()); - Map replacements = new HashMap(); - replacements.put(graph.start(), duplicate.start()); - duplicate.addDuplicate(graph.getNodes(), replacements); - - // Delete nodes in original graph. - for (Node n : graph.getNodes()) { - if (n != graph.start()) { - n.clearEdges(); - } - } - for (Node n : graph.getNodes()) { - if (n != graph.start()) { - n.delete(); - } - } - - // Copy nodes from duplicate back to original graph. - replacements.clear(); - replacements.put(duplicate.start(), graph.start()); - graph.addDuplicate(duplicate.getNodes(), replacements); - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/EscapeAnalysisPhase.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/EscapeAnalysisPhase.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,312 +0,0 @@ -/* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.compiler.phases; - -import java.util.*; - -import com.oracle.max.graal.compiler.*; -import com.oracle.max.graal.compiler.debug.*; -import com.oracle.max.graal.compiler.gen.*; -import com.oracle.max.graal.compiler.graph.*; -import com.oracle.max.graal.compiler.observer.*; -import com.oracle.max.graal.compiler.schedule.*; -import com.oracle.max.graal.graph.*; -import com.oracle.max.graal.nodes.*; -import com.oracle.max.graal.nodes.PhiNode.PhiType; -import com.oracle.max.graal.nodes.calc.*; -import com.oracle.max.graal.nodes.spi.*; -import com.oracle.max.graal.nodes.virtual.*; -import com.sun.cri.ci.*; - - -public class EscapeAnalysisPhase extends Phase { - - public static class BlockExitState implements MergeableState { - public final ValueNode[] fieldState; - public final VirtualObjectNode virtualObject; - public FloatingNode virtualObjectField; - - public BlockExitState(EscapeField[] fields, VirtualObjectNode virtualObject) { - this.fieldState = new ValueNode[fields.length]; - this.virtualObject = virtualObject; - this.virtualObjectField = null; - for (int i = 0; i < fields.length; i++) { - fieldState[i] = ConstantNode.defaultForKind(fields[i].kind(), virtualObject.graph()); - virtualObjectField = new VirtualObjectFieldNode(virtualObject, virtualObjectField, fieldState[i], i, virtualObject.graph()); - } - } - - public BlockExitState(BlockExitState state) { - this.fieldState = state.fieldState.clone(); - this.virtualObject = state.virtualObject; - this.virtualObjectField = state.virtualObjectField; - } - - public void updateField(int fieldIndex) { - virtualObjectField = new VirtualObjectFieldNode(virtualObject, virtualObjectField, fieldState[fieldIndex], fieldIndex, virtualObject.graph()); - } - - @Override - public BlockExitState clone() { - return new BlockExitState(this); - } - - @Override - public boolean merge(MergeNode merge, Collection withStates) { - PhiNode vobjPhi = null; - PhiNode[] valuePhis = new PhiNode[fieldState.length]; - for (BlockExitState other : withStates) { - if (virtualObjectField != other.virtualObjectField && vobjPhi == null) { - vobjPhi = new PhiNode(CiKind.Illegal, merge, PhiType.Virtual, virtualObject.graph()); - vobjPhi.addInput(virtualObjectField); - virtualObjectField = vobjPhi; - } - for (int i2 = 0; i2 < fieldState.length; i2++) { - if (fieldState[i2] != other.fieldState[i2] && valuePhis[i2] == null) { - valuePhis[i2] = new PhiNode(fieldState[i2].kind, merge, PhiType.Value, virtualObject.graph()); - valuePhis[i2].addInput(fieldState[i2]); - fieldState[i2] = valuePhis[i2]; - } - } - } - for (BlockExitState other : withStates) { - if (vobjPhi != null) { - vobjPhi.addInput(other.virtualObjectField); - } - for (int i2 = 0; i2 < fieldState.length; i2++) { - if (valuePhis[i2] != null) { - valuePhis[i2].addInput(other.fieldState[i2]); - } - } - } - assert vobjPhi == null || vobjPhi.valueCount() == withStates.size() + 1; - for (int i2 = 0; i2 < fieldState.length; i2++) { - if (valuePhis[i2] != null) { - virtualObjectField = new VirtualObjectFieldNode(virtualObject, virtualObjectField, valuePhis[i2], i2, virtualObject.graph()); - assert valuePhis[i2].valueCount() == withStates.size() + 1; - } - } - return true; - } - - @Override - public void loopBegin(LoopBeginNode loopBegin) { - PhiNode vobjPhi = null; - vobjPhi = new PhiNode(CiKind.Illegal, loopBegin, PhiType.Virtual, virtualObject.graph()); - vobjPhi.addInput(virtualObjectField); - virtualObjectField = vobjPhi; - for (int i2 = 0; i2 < fieldState.length; i2++) { - PhiNode valuePhi = new PhiNode(fieldState[i2].kind, loopBegin, PhiType.Value, virtualObject.graph()); - valuePhi.addInput(fieldState[i2]); - fieldState[i2] = valuePhi; - updateField(i2); - } - } - - @Override - public void loopEnd(LoopEndNode x, BlockExitState loopEndState) { - while (!(virtualObjectField instanceof PhiNode)) { - virtualObjectField = ((VirtualObjectFieldNode) virtualObjectField).lastState(); - } - ((PhiNode) virtualObjectField).addInput(loopEndState.virtualObjectField); - assert ((PhiNode) virtualObjectField).valueCount() == 2; - for (int i2 = 0; i2 < fieldState.length; i2++) { - ((PhiNode) fieldState[i2]).addInput(loopEndState.fieldState[i2]); - assert ((PhiNode) fieldState[i2]).valueCount() == 2; - } - } - - @Override - public void afterSplit(FixedNode node) { - // nothing to do... - } - } - - - public class EscapementFixup { - - private List blocks; - private final Map fields = new HashMap(); - private final Map exitStates = new HashMap(); - - private final EscapeOp op; - private final Graph graph; - private final Node node; - private EscapeField[] escapeFields; - - public EscapementFixup(EscapeOp op, Graph graph, Node node) { - this.op = op; - this.graph = graph; - this.node = node; - } - - public void apply() { - process(); - removeAllocation(); - } - - public void removeAllocation() { - assert node instanceof FixedWithNextNode; - - escapeFields = op.fields(node); - for (int i = 0; i < escapeFields.length; i++) { - fields.put(escapeFields[i].representation(), i); - } - final VirtualObjectNode virtual = new VirtualObjectNode(((ValueNode) node).exactType(), escapeFields, graph); - if (GraalOptions.TraceEscapeAnalysis || GraalOptions.PrintEscapeAnalysis) { - TTY.println("new virtual object: " + virtual); - } - node.replaceAtUsages(virtual); - final FixedNode next = ((FixedWithNextNode) node).next(); - node.replaceAndDelete(next); - - final BlockExitState startState = new BlockExitState(escapeFields, virtual); - final PostOrderNodeIterator iterator = new PostOrderNodeIterator(next, startState) { - @Override - protected void node(FixedNode node) { - int changedField = op.updateState(virtual, node, fields, state.fieldState); - if (changedField != -1) { - state.updateField(changedField); - } - if (!node.isDeleted() && node instanceof StateSplit && ((StateSplit) node).stateAfter() != null) { - if (state.virtualObjectField != null) { - ((StateSplit) node).stateAfter().addVirtualObjectMapping(state.virtualObjectField); - } - } - } - }; - iterator.apply(); - } - - private void process() { - for (Node usage : node.usages().snapshot()) { - op.beforeUpdate(node, usage); - } - } - } - - private final GraalCompilation compilation; - private final IR ir; - - public EscapeAnalysisPhase(GraalCompilation compilation, IR ir) { - this.compilation = compilation; - this.ir = ir; - } - - @Override - protected void run(Graph graph) { - for (Node node : graph.getNodes()) { - EscapeOp op = node.lookup(EscapeOp.class); - if (op != null && op.canAnalyze(node)) { - Set exits = new HashSet(); - Set invokes = new HashSet(); - int iterations = 0; - - int minimumWeight = GraalOptions.ForcedInlineEscapeWeight; - do { - double weight = analyze(op, node, exits, invokes); - if (exits.size() != 0) { - if (GraalOptions.TraceEscapeAnalysis || GraalOptions.PrintEscapeAnalysis) { - TTY.println("%n####### escaping object: %d %s (%s) in %s", node.id(), node.shortName(), ((ValueNode) node).exactType(), compilation.method); - if (GraalOptions.TraceEscapeAnalysis) { - TTY.print("%d: new value: %d %s, weight %d, escapes at ", iterations, node.id(), node.shortName(), weight); - for (Node n : exits) { - TTY.print("%d %s, ", n.id(), n.shortName()); - } - for (Node n : invokes) { - TTY.print("%d %s, ", n.id(), n.shortName()); - } - TTY.println(); - } - } - break; - } - if (invokes.size() == 0) { - - if (compilation.compiler.isObserved()) { - compilation.compiler.fireCompilationEvent(new CompilationEvent(compilation, "Before escape " + node.id(), graph, true, false)); - } - if (GraalOptions.TraceEscapeAnalysis || GraalOptions.PrintEscapeAnalysis) { - TTY.println("%n!!!!!!!! non-escaping object: %d %s (%s) in %s", node.id(), node.shortName(), ((ValueNode) node).exactType(), compilation.method); - } - new EscapementFixup(op, graph, node).apply(); - if (compilation.compiler.isObserved()) { - compilation.compiler.fireCompilationEvent(new CompilationEvent(compilation, "After escape", graph, true, false)); - } - new PhiSimplifier(graph); - break; - } - if (weight < minimumWeight) { - if (GraalOptions.TraceEscapeAnalysis || GraalOptions.PrintEscapeAnalysis) { - TTY.println("%n####### possibly escaping object: %d in %s (insufficient weight for inlining)", node.id(), compilation.method); - } - break; - } - if (!GraalOptions.Inline) { - break; - } - if (GraalOptions.TraceEscapeAnalysis || GraalOptions.PrintEscapeAnalysis) { - TTY.println("Trying inlining to get a non-escaping object for %d", node.id()); - } - new InliningPhase(compilation, ir, invokes).apply(graph); - new DeadCodeEliminationPhase().apply(graph); - if (node.isDeleted()) { - if (GraalOptions.TraceEscapeAnalysis || GraalOptions.PrintEscapeAnalysis) { - TTY.println("%n!!!!!!!! object died while performing escape analysis: %d %s (%s) in %s", node.id(), node.shortName(), ((ValueNode) node).exactType(), compilation.method); - } - break; - } - exits.clear(); - invokes.clear(); - } while (iterations++ < 3); - } - } - } - - private double analyze(EscapeOp op, Node node, Collection exits, Collection invokes) { - double weight = 0; - for (Node usage : node.usages()) { - boolean escapes = op.escape(node, usage); - if (escapes) { - if (usage instanceof FrameState) { - // nothing to do... - } else if (usage instanceof InvokeNode) { - invokes.add((InvokeNode) usage); - } else { - exits.add(usage); - if (!GraalOptions.TraceEscapeAnalysis) { - break; - } - } - } else { - if (GraalOptions.ProbabilityAnalysis && usage instanceof FixedNode) { - weight += ((FixedNode) usage).probability(); - } else { - weight++; - } - } - } - return weight; - } - -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/GlobalValueNumberingPhase.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/GlobalValueNumberingPhase.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,55 +0,0 @@ -/* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.compiler.phases; - -import com.oracle.max.graal.compiler.*; -import com.oracle.max.graal.compiler.debug.*; -import com.oracle.max.graal.graph.*; -import com.oracle.max.graal.graph.collections.*; - -public class GlobalValueNumberingPhase extends Phase { - - @Override - protected void run(Graph graph) { - NodeBitMap visited = graph.createNodeBitMap(); - for (Node n : graph.getNodes()) { - apply(n, visited); - } - } - - private void apply(Node n, NodeBitMap visited) { - if (n != null && !visited.isMarked(n)) { - visited.mark(n); - for (Node input : n.inputs()) { - apply(input, visited); - } - Node newNode = n.graph().value(n); - if (newNode != n) { - GraalMetrics.GlobalValueNumberingHits++; - if (GraalOptions.TraceGVN) { - TTY.println("GVN applied and new node is " + newNode); - } - } - } - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/GraphBuilderPhase.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/GraphBuilderPhase.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1703 +0,0 @@ -/* - * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.compiler.phases; - -import static com.sun.cri.bytecode.Bytecodes.*; -import static java.lang.reflect.Modifier.*; - -import java.lang.reflect.*; -import java.util.*; - -import com.oracle.max.graal.compiler.*; -import com.oracle.max.graal.compiler.debug.*; -import com.oracle.max.graal.compiler.graph.*; -import com.oracle.max.graal.compiler.graph.BlockMap.Block; -import com.oracle.max.graal.compiler.graph.BlockMap.BranchOverride; -import com.oracle.max.graal.compiler.graph.BlockMap.DeoptBlock; -import com.oracle.max.graal.compiler.graph.BlockMap.ExceptionBlock; -import com.oracle.max.graal.compiler.schedule.*; -import com.oracle.max.graal.compiler.util.*; -import com.oracle.max.graal.compiler.util.LoopUtil.Loop; -import com.oracle.max.graal.compiler.value.*; -import com.oracle.max.graal.graph.*; -import com.oracle.max.graal.graph.collections.*; -import com.oracle.max.graal.nodes.*; -import com.oracle.max.graal.nodes.DeoptimizeNode.DeoptAction; -import com.oracle.max.graal.nodes.calc.*; -import com.oracle.max.graal.nodes.extended.*; -import com.oracle.max.graal.nodes.java.*; -import com.oracle.max.graal.nodes.spi.*; -import com.sun.cri.bytecode.*; -import com.sun.cri.ci.*; -import com.sun.cri.ri.*; -import com.sun.cri.ri.RiType.Representation; - -/** - * The {@code GraphBuilder} class parses the bytecode of a method and builds the IR graph. - * A number of optimizations may be performed during parsing of the bytecode, including value - * numbering, inlining, constant folding, strength reduction, etc. - */ -public final class GraphBuilderPhase extends Phase { - - /** - * The minimum value to which {@link GraalOptions#TraceBytecodeParserLevel} must be set to trace - * the bytecode instructions as they are parsed. - */ - public static final int TRACELEVEL_INSTRUCTIONS = 1; - - /** - * The minimum value to which {@link GraalOptions#TraceBytecodeParserLevel} must be set to trace - * the frame state before each bytecode instruction as it is parsed. - */ - public static final int TRACELEVEL_STATE = 2; - - private final GraalCompilation compilation; - private CompilerGraph graph; - - private final CiStatistics stats; - private final RiRuntime runtime; - private final RiMethod method; - private final RiConstantPool constantPool; - private RiExceptionHandler[] exceptionHandlers; - - private final BytecodeStream stream; // the bytecode stream - private final LogStream log; - private FrameStateBuilder frameState; // the current execution state - - // bci-to-block mapping - private Block[] blockFromBci; - private ArrayList blockList; - private HashMap branchOverride; - - private int nextBlockNumber; - - private ValueNode methodSynchronizedObject; - private CiExceptionHandler unwindHandler; - - private ExceptionBlock unwindBlock; - private Block returnBlock; - - private boolean storeResultGraph; - - // the worklist of blocks, sorted by depth first number - private final PriorityQueue workList = new PriorityQueue(10, new Comparator() { - public int compare(Block o1, Block o2) { - return o1.blockID - o2.blockID; - } - }); - - private FixedWithNextNode lastInstr; // the last instruction added - - private final Set blocksOnWorklist = new HashSet(); - private final Set blocksVisited = new HashSet(); - - public static final Map cachedGraphs = new WeakHashMap(); - - /** - * Creates a new, initialized, {@code GraphBuilder} instance for a given compilation. - * - * @param compilation the compilation - * @param ir the IR to build the graph into - * @param graph - */ - public GraphBuilderPhase(GraalCompilation compilation, RiMethod method, boolean inline) { - super(inline ? "BuildInlineGraph" : "BuildGraph"); - this.compilation = compilation; - - this.runtime = compilation.runtime; - this.method = method; - this.stats = compilation.stats; - this.log = GraalOptions.TraceBytecodeParserLevel > 0 ? new LogStream(TTY.out()) : null; - this.stream = new BytecodeStream(method.code()); - - this.constantPool = runtime.getConstantPool(method); - this.storeResultGraph = GraalOptions.CacheGraphs; - } - - @Override - protected void run(Graph graph) { - assert graph != null; - this.graph = (CompilerGraph) graph; - this.frameState = new FrameStateBuilder(method, graph); - build(); - } - - @Override - protected String getDetailedName() { - return getName() + " " + method.holder().name() + "." + method.name() + method.signature().asString(); - } - - /** - * Builds the graph for a the specified {@code IRScope}. - * - * @param createUnwind setting this to true will always generate an unwind block, even if there is no exception - * handler and the method is not synchronized - */ - private void build() { - if (log != null) { - log.println(); - log.println("Compiling " + method); - } - - // 2. compute the block map, setup exception handlers and get the entrypoint(s) - BlockMap blockMap = compilation.getBlockMap(method); - this.branchOverride = blockMap.branchOverride; - - exceptionHandlers = blockMap.exceptionHandlers(); - blockList = new ArrayList(blockMap.blocks); - blockFromBci = new Block[method.codeSize()]; - for (int i = 0; i < blockList.size(); i++) { - int blockID = nextBlockNumber(); - assert blockID == i; - Block block = blockList.get(i); - if (block.startBci >= 0 && !(block instanceof BlockMap.DeoptBlock)) { - blockFromBci[block.startBci] = block; - } - } - - // 1. create the start block - Block startBlock = nextBlock(FixedWithNextNode.SYNCHRONIZATION_ENTRY_BCI); - markOnWorkList(startBlock); - lastInstr = (FixedWithNextNode) createTarget(startBlock, frameState); - graph.start().setNext(lastInstr); - - if (isSynchronized(method.accessFlags())) { - // 4A.1 add a monitor enter to the start block - methodSynchronizedObject = synchronizedObject(frameState, method); - genMonitorEnter(methodSynchronizedObject, FixedWithNextNode.SYNCHRONIZATION_ENTRY_BCI); - } - - // 4B.1 simply finish the start block - finishStartBlock(startBlock); - unwindHandler = new CiExceptionHandler(0, method.code().length, FixedWithNextNode.SYNCHRONIZATION_ENTRY_BCI, 0, null); - - // 5. SKIPPED: look for intrinsics - - // 6B.1 do the normal parsing - addToWorkList(blockFromBci[0]); - iterateAllBlocks(); - - List loops = LoopUtil.computeLoops(graph); - NodeBitMap loopExits = graph.createNodeBitMap(); - for (Loop loop : loops) { - loopExits.setUnion(loop.exits()); - } - - // remove Placeholders - for (Node n : graph.getNodes()) { - if (n instanceof PlaceholderNode && !loopExits.isMarked(n)) { - PlaceholderNode p = (PlaceholderNode) n; - p.replaceAndDelete(p.next()); - } - } - - // remove FrameStates - for (Node n : graph.getNodes()) { - if (n instanceof FrameState) { - if (n.usages().size() == 0 && n.predecessor() == null) { - n.delete(); - } - } - } - - if (storeResultGraph) { - // Create duplicate graph. - CompilerGraph duplicate = new CompilerGraph(null); - Map replacements = new HashMap(); - replacements.put(graph.start(), duplicate.start()); - duplicate.addDuplicate(graph.getNodes(), replacements); - - cachedGraphs.put(method, duplicate); - } - } - - private int nextBlockNumber() { - stats.blockCount++; - return nextBlockNumber++; - } - - private Block nextBlock(int bci) { - Block block = new Block(); - block.startBci = bci; - block.endBci = bci; - block.blockID = nextBlockNumber(); - return block; - } - - private Block unwindBlock(int bci) { - if (unwindBlock == null) { - unwindBlock = new ExceptionBlock(); - unwindBlock.startBci = -1; - unwindBlock.endBci = -1; - unwindBlock.deoptBci = bci; - unwindBlock.blockID = nextBlockNumber(); - addToWorkList(unwindBlock); - } - return unwindBlock; - } - - private Block returnBlock(int bci) { - if (returnBlock == null) { - returnBlock = new Block(); - returnBlock.startBci = bci; - returnBlock.endBci = bci; - returnBlock.blockID = nextBlockNumber(); - addToWorkList(returnBlock); - } - return returnBlock; - } - - private void markOnWorkList(Block block) { - blocksOnWorklist.add(block); - } - - private boolean isOnWorkList(Block block) { - return blocksOnWorklist.contains(block); - } - - private void markVisited(Block block) { - blocksVisited.add(block); - } - - private boolean isVisited(Block block) { - return blocksVisited.contains(block); - } - - private void finishStartBlock(Block startBlock) { - assert bci() == 0; - appendGoto(createTargetAt(0, frameState)); - } - - public void mergeOrClone(Block target, FrameStateAccess newState) { - StateSplit first = (StateSplit) target.firstInstruction; - - if (target.isLoopHeader && isVisited(target)) { - first = (StateSplit) loopBegin(target).loopEnd().predecessor(); - } - - int bci = target.startBci; - if (target instanceof ExceptionBlock) { - bci = ((ExceptionBlock) target).deoptBci; - } - - FrameState existingState = first.stateAfter(); - - if (existingState == null) { - // copy state because it is modified - first.setStateAfter(newState.duplicate(bci)); - } else { - if (!GraalOptions.AssumeVerifiedBytecode && !existingState.isCompatibleWith(newState)) { - // stacks or locks do not match--bytecodes would not verify - TTY.println(existingState.toString()); - TTY.println(newState.duplicate(0).toString()); - throw new CiBailout("stack or locks do not match"); - } - assert existingState.localsSize() == newState.localsSize(); - assert existingState.stackSize() == newState.stackSize(); - - if (first instanceof PlaceholderNode) { - PlaceholderNode p = (PlaceholderNode) first; - if (p.predecessor() == null) { - p.setStateAfter(newState.duplicate(bci)); - return; - } else { - MergeNode merge = new MergeNode(graph); - FixedNode next = p.next(); - EndNode end = new EndNode(graph); - p.setNext(end); - merge.setNext(next); - merge.addEnd(end); - merge.setStateAfter(existingState); - p.setStateAfter(existingState.duplicate(bci)); - if (!(next instanceof LoopEndNode)) { - target.firstInstruction = merge; - } - first = merge; - } - } - - existingState.merge((MergeNode) first, newState); - } - } - - private void insertLoopPhis(LoopBeginNode loopBegin, FrameState newState) { - int stackSize = newState.stackSize(); - for (int i = 0; i < stackSize; i++) { - // always insert phis for the stack - ValueNode x = newState.stackAt(i); - if (x != null) { - newState.setupPhiForStack(loopBegin, i).addInput(x); - } - } - int localsSize = newState.localsSize(); - for (int i = 0; i < localsSize; i++) { - ValueNode x = newState.localAt(i); - if (x != null) { - newState.setupPhiForLocal(loopBegin, i).addInput(x); - } - } - } - - public BytecodeStream stream() { - return stream; - } - - public int bci() { - return stream.currentBCI(); - } - - private void loadLocal(int index, CiKind kind) { - frameState.push(kind, frameState.loadLocal(index)); - } - - private void storeLocal(CiKind kind, int index) { - frameState.storeLocal(index, frameState.pop(kind)); - } - - public boolean covers(RiExceptionHandler handler, int bci) { - return handler.startBCI() <= bci && bci < handler.endBCI(); - } - - public boolean isCatchAll(RiExceptionHandler handler) { - return handler.catchTypeCPI() == 0; - } - - private FixedNode handleException(ValueNode exceptionObject, int bci) { - assert bci == FixedWithNextNode.SYNCHRONIZATION_ENTRY_BCI || bci == bci() : "invalid bci"; - - if (GraalOptions.UseExceptionProbability && method.invocationCount() > GraalOptions.MatureInvocationCount) { - if (exceptionObject == null && method.exceptionProbability(bci) == 0) { - return null; - } - } - - RiExceptionHandler firstHandler = null; - // join with all potential exception handlers - if (exceptionHandlers != null) { - for (RiExceptionHandler handler : exceptionHandlers) { - // if the handler covers this bytecode index, add it to the list - if (covers(handler, bci)) { - firstHandler = handler; - break; - } - } - } - - if (firstHandler == null) { - firstHandler = unwindHandler; - } - - if (firstHandler != null) { - compilation.setHasExceptionHandlers(); - - Block dispatchBlock = null; - for (Block block : blockList) { - if (block instanceof ExceptionBlock) { - ExceptionBlock excBlock = (ExceptionBlock) block; - if (excBlock.handler == firstHandler) { - dispatchBlock = block; - break; - } - } - } - // if there's no dispatch block then the catch block needs to be a catch all - if (dispatchBlock == null) { - assert isCatchAll(firstHandler); - int handlerBCI = firstHandler.handlerBCI(); - if (handlerBCI == FixedWithNextNode.SYNCHRONIZATION_ENTRY_BCI) { - dispatchBlock = unwindBlock(bci); - } else { - dispatchBlock = blockFromBci[handlerBCI]; - } - } - PlaceholderNode p = new PlaceholderNode(graph); - p.setStateAfter(frameState.duplicateWithoutStack(bci)); - - ValueNode currentExceptionObject; - ExceptionObjectNode newObj = null; - if (exceptionObject == null) { - newObj = new ExceptionObjectNode(graph); - currentExceptionObject = newObj; - } else { - currentExceptionObject = exceptionObject; - } - FrameState stateWithException = frameState.duplicateWithException(bci, currentExceptionObject); - if (newObj != null) { - newObj.setStateAfter(stateWithException); - } - FixedNode target = createTarget(dispatchBlock, stateWithException); - if (exceptionObject == null) { - ExceptionObjectNode eObj = (ExceptionObjectNode) currentExceptionObject; - eObj.setNext(target); - p.setNext(eObj); - } else { - p.setNext(target); - } - return p; - } - return null; - } - - private void genLoadConstant(int cpi) { - Object con = constantPool.lookupConstant(cpi); - - if (con instanceof RiType) { - // this is a load of class constant which might be unresolved - RiType riType = (RiType) con; - if (!riType.isResolved()) { - storeResultGraph = false; - append(new DeoptimizeNode(DeoptAction.InvalidateRecompile, graph)); - frameState.push(CiKind.Object, append(ConstantNode.forObject(null, graph))); - } else { - frameState.push(CiKind.Object, append(new ConstantNode(riType.getEncoding(Representation.JavaClass), graph))); - } - } else if (con instanceof CiConstant) { - CiConstant constant = (CiConstant) con; - frameState.push(constant.kind.stackKind(), appendConstant(constant)); - } else { - throw new Error("lookupConstant returned an object of incorrect type"); - } - } - - private void genLoadIndexed(CiKind kind) { - ValueNode index = frameState.ipop(); - ValueNode array = frameState.apop(); - ValueNode length = append(new ArrayLengthNode(array, graph)); - ValueNode v = append(new LoadIndexedNode(array, index, length, kind, graph)); - frameState.push(kind.stackKind(), v); - } - - private void genStoreIndexed(CiKind kind) { - ValueNode value = frameState.pop(kind.stackKind()); - ValueNode index = frameState.ipop(); - ValueNode array = frameState.apop(); - ValueNode length = append(new ArrayLengthNode(array, graph)); - StoreIndexedNode result = new StoreIndexedNode(array, index, length, kind, value, graph); - append(result); - } - - private void stackOp(int opcode) { - switch (opcode) { - case POP: { - frameState.xpop(); - break; - } - case POP2: { - frameState.xpop(); - frameState.xpop(); - break; - } - case DUP: { - ValueNode w = frameState.xpop(); - frameState.xpush(w); - frameState.xpush(w); - break; - } - case DUP_X1: { - ValueNode w1 = frameState.xpop(); - ValueNode w2 = frameState.xpop(); - frameState.xpush(w1); - frameState.xpush(w2); - frameState.xpush(w1); - break; - } - case DUP_X2: { - ValueNode w1 = frameState.xpop(); - ValueNode w2 = frameState.xpop(); - ValueNode w3 = frameState.xpop(); - frameState.xpush(w1); - frameState.xpush(w3); - frameState.xpush(w2); - frameState.xpush(w1); - break; - } - case DUP2: { - ValueNode w1 = frameState.xpop(); - ValueNode w2 = frameState.xpop(); - frameState.xpush(w2); - frameState.xpush(w1); - frameState.xpush(w2); - frameState.xpush(w1); - break; - } - case DUP2_X1: { - ValueNode w1 = frameState.xpop(); - ValueNode w2 = frameState.xpop(); - ValueNode w3 = frameState.xpop(); - frameState.xpush(w2); - frameState.xpush(w1); - frameState.xpush(w3); - frameState.xpush(w2); - frameState.xpush(w1); - break; - } - case DUP2_X2: { - ValueNode w1 = frameState.xpop(); - ValueNode w2 = frameState.xpop(); - ValueNode w3 = frameState.xpop(); - ValueNode w4 = frameState.xpop(); - frameState.xpush(w2); - frameState.xpush(w1); - frameState.xpush(w4); - frameState.xpush(w3); - frameState.xpush(w2); - frameState.xpush(w1); - break; - } - case SWAP: { - ValueNode w1 = frameState.xpop(); - ValueNode w2 = frameState.xpop(); - frameState.xpush(w1); - frameState.xpush(w2); - break; - } - default: - throw Util.shouldNotReachHere(); - } - - } - - private void genArithmeticOp(CiKind kind, int opcode) { - genArithmeticOp(kind, opcode, false); - } - - private void genArithmeticOp(CiKind result, int opcode, boolean canTrap) { - ValueNode y = frameState.pop(result); - ValueNode x = frameState.pop(result); - boolean isStrictFP = isStrict(method.accessFlags()); - ArithmeticNode v; - switch(opcode){ - case IADD: - case LADD: v = new IntegerAddNode(result, x, y, graph); break; - case FADD: - case DADD: v = new FloatAddNode(result, x, y, isStrictFP, graph); break; - case ISUB: - case LSUB: v = new IntegerSubNode(result, x, y, graph); break; - case FSUB: - case DSUB: v = new FloatSubNode(result, x, y, isStrictFP, graph); break; - case IMUL: - case LMUL: v = new IntegerMulNode(result, x, y, graph); break; - case FMUL: - case DMUL: v = new FloatMulNode(result, x, y, isStrictFP, graph); break; - case IDIV: - case LDIV: v = new IntegerDivNode(result, x, y, graph); break; - case FDIV: - case DDIV: v = new FloatDivNode(result, x, y, isStrictFP, graph); break; - case IREM: - case LREM: v = new IntegerRemNode(result, x, y, graph); break; - case FREM: - case DREM: v = new FloatRemNode(result, x, y, isStrictFP, graph); break; - default: - throw new CiBailout("should not reach"); - } - ValueNode result1 = append(v); - if (canTrap) { - append(new ValueAnchorNode(result1, graph)); - } - frameState.push(result, result1); - } - - private void genNegateOp(CiKind kind) { - frameState.push(kind, append(new NegateNode(frameState.pop(kind), graph))); - } - - private void genShiftOp(CiKind kind, int opcode) { - ValueNode s = frameState.ipop(); - ValueNode x = frameState.pop(kind); - ShiftNode v; - switch(opcode){ - case ISHL: - case LSHL: v = new LeftShiftNode(kind, x, s, graph); break; - case ISHR: - case LSHR: v = new RightShiftNode(kind, x, s, graph); break; - case IUSHR: - case LUSHR: v = new UnsignedRightShiftNode(kind, x, s, graph); break; - default: - throw new CiBailout("should not reach"); - } - frameState.push(kind, append(v)); - } - - private void genLogicOp(CiKind kind, int opcode) { - ValueNode y = frameState.pop(kind); - ValueNode x = frameState.pop(kind); - LogicNode v; - switch(opcode){ - case IAND: - case LAND: v = new AndNode(kind, x, y, graph); break; - case IOR: - case LOR: v = new OrNode(kind, x, y, graph); break; - case IXOR: - case LXOR: v = new XorNode(kind, x, y, graph); break; - default: - throw new CiBailout("should not reach"); - } - frameState.push(kind, append(v)); - } - - private void genCompareOp(CiKind kind, int opcode, CiKind resultKind) { - ValueNode y = frameState.pop(kind); - ValueNode x = frameState.pop(kind); - ValueNode value = append(new NormalizeCompareNode(opcode, resultKind, x, y, graph)); - if (!resultKind.isVoid()) { - frameState.ipush(value); - } - } - - private void genConvert(int opcode, CiKind from, CiKind to) { - CiKind tt = to.stackKind(); - frameState.push(tt, append(new ConvertNode(opcode, frameState.pop(from.stackKind()), tt, graph))); - } - - private void genIncrement() { - int index = stream().readLocalIndex(); - int delta = stream().readIncrement(); - ValueNode x = frameState.localAt(index); - ValueNode y = append(ConstantNode.forInt(delta, graph)); - frameState.storeLocal(index, append(new IntegerAddNode(CiKind.Int, x, y, graph))); - } - - private void genGoto(int fromBCI, int toBCI) { - appendGoto(createTargetAt(toBCI, frameState)); - } - - private void ifNode(ValueNode x, Condition cond, ValueNode y) { - assert !x.isDeleted() && !y.isDeleted(); - double probability = method.branchProbability(bci()); - if (probability < 0) { - if (GraalOptions.TraceProbability) { - TTY.println("missing probability in " + method + " at bci " + bci()); - } - probability = 0.5; - } - - IfNode ifNode = new IfNode(new CompareNode(x, cond, y, graph), probability, graph); - append(ifNode); - BlockMap.BranchOverride override = branchOverride.get(bci()); - FixedNode tsucc; - if (override == null || override.taken == false) { - tsucc = createTargetAt(stream().readBranchDest(), frameState); - } else { - tsucc = createTarget(override.block, frameState); - } - ifNode.setBlockSuccessor(0, tsucc); - FixedNode fsucc; - if (override == null || override.taken == true) { - fsucc = createTargetAt(stream().nextBCI(), frameState); - } else { - fsucc = createTarget(override.block, frameState); - } - ifNode.setBlockSuccessor(1, fsucc); - } - - private void genIfZero(Condition cond) { - ValueNode y = appendConstant(CiConstant.INT_0); - ValueNode x = frameState.ipop(); - ifNode(x, cond, y); - } - - private void genIfNull(Condition cond) { - ValueNode y = appendConstant(CiConstant.NULL_OBJECT); - ValueNode x = frameState.apop(); - ifNode(x, cond, y); - } - - private void genIfSame(CiKind kind, Condition cond) { - ValueNode y = frameState.pop(kind); - ValueNode x = frameState.pop(kind); - assert !x.isDeleted() && !y.isDeleted(); - ifNode(x, cond, y); - } - - private void genThrow(int bci) { - ValueNode exception = frameState.apop(); - FixedGuardNode node = new FixedGuardNode(new IsNonNullNode(exception, graph), graph); - append(node); - - FixedNode entry = handleException(exception, bci); - if (entry != null) { - append(entry); - } else { - appendGoto(createTarget(unwindBlock(bci), frameState.duplicateWithException(bci, exception))); - } - } - - private void genCheckCast() { - int cpi = stream().readCPI(); - RiType type = constantPool.lookupType(cpi, CHECKCAST); - ConstantNode typeInstruction = genTypeOrDeopt(RiType.Representation.ObjectHub, type, type.isResolved()); - ValueNode object = frameState.apop(); - if (typeInstruction != null) { -// InstanceOf instanceOf = new InstanceOf(typeInstruction, object, true, graph); -// FixedGuard fixedGuard = new FixedGuard(instanceOf, graph); -// append(fixedGuard); -// CastNode castNode = new CastNode(object.kind, object, graph); -// castNode.inputs().add(fixedGuard); -// frameState.apush(castNode); - frameState.apush(new CheckCastNode(typeInstruction, object, graph)); - } else { - frameState.apush(appendConstant(CiConstant.NULL_OBJECT)); - } - } - - private void genInstanceOf() { - int cpi = stream().readCPI(); - RiType type = constantPool.lookupType(cpi, INSTANCEOF); - ConstantNode typeInstruction = genTypeOrDeopt(RiType.Representation.ObjectHub, type, type.isResolved()); - ValueNode object = frameState.apop(); - if (typeInstruction != null) { - frameState.ipush(append(new MaterializeNode(new InstanceOfNode(typeInstruction, object, false, graph), graph))); - } else { - frameState.ipush(appendConstant(CiConstant.INT_0)); - } - } - - void genNewInstance(int cpi) { - RiType type = constantPool.lookupType(cpi, NEW); - if (type.isResolved()) { - NewInstanceNode n = new NewInstanceNode(type, cpi, constantPool, graph); - frameState.apush(append(n)); - } else { - storeResultGraph = false; - append(new DeoptimizeNode(DeoptAction.InvalidateRecompile, graph)); - frameState.apush(appendConstant(CiConstant.NULL_OBJECT)); - } - } - - private void genNewTypeArray(int typeCode) { - CiKind kind = CiKind.fromArrayTypeCode(typeCode); - RiType elementType = runtime.asRiType(kind); - NewTypeArrayNode nta = new NewTypeArrayNode(frameState.ipop(), elementType, graph); - frameState.apush(append(nta)); - } - - private void genNewObjectArray(int cpi) { - RiType type = constantPool.lookupType(cpi, ANEWARRAY); - ValueNode length = frameState.ipop(); - if (type.isResolved()) { - NewArrayNode n = new NewObjectArrayNode(type, length, graph); - frameState.apush(append(n)); - } else { - storeResultGraph = false; - append(new DeoptimizeNode(DeoptAction.InvalidateRecompile, graph)); - frameState.apush(appendConstant(CiConstant.NULL_OBJECT)); - } - - } - - private void genNewMultiArray(int cpi) { - RiType type = constantPool.lookupType(cpi, MULTIANEWARRAY); - int rank = stream().readUByte(bci() + 3); - ValueNode[] dims = new ValueNode[rank]; - for (int i = rank - 1; i >= 0; i--) { - dims[i] = frameState.ipop(); - } - if (type.isResolved()) { - NewArrayNode n = new NewMultiArrayNode(type, dims, cpi, constantPool, graph); - frameState.apush(append(n)); - } else { - storeResultGraph = false; - append(new DeoptimizeNode(DeoptAction.InvalidateRecompile, graph)); - frameState.apush(appendConstant(CiConstant.NULL_OBJECT)); - } - } - - private void genGetField(int cpi, RiField field) { - CiKind kind = field.kind(); - ValueNode receiver = frameState.apop(); - if (field.isResolved() && field.holder().isInitialized()) { - LoadFieldNode load = new LoadFieldNode(receiver, field, graph); - appendOptimizedLoadField(kind, load); - } else { - storeResultGraph = false; - append(new DeoptimizeNode(DeoptAction.InvalidateRecompile, graph)); - frameState.push(kind.stackKind(), append(ConstantNode.defaultForKind(kind, graph))); - } - } - - private void genPutField(int cpi, RiField field) { - ValueNode value = frameState.pop(field.kind().stackKind()); - ValueNode receiver = frameState.apop(); - if (field.isResolved() && field.holder().isInitialized()) { - StoreFieldNode store = new StoreFieldNode(receiver, field, value, graph); - appendOptimizedStoreField(store); - } else { - storeResultGraph = false; - append(new DeoptimizeNode(DeoptAction.InvalidateRecompile, graph)); - } - } - - private void genGetStatic(int cpi, RiField field) { - RiType holder = field.holder(); - boolean isInitialized = field.isResolved() && holder.isInitialized(); - CiConstant constantValue = null; - if (isInitialized) { - constantValue = field.constantValue(null); - } - if (constantValue != null) { - frameState.push(constantValue.kind.stackKind(), appendConstant(constantValue)); - } else { - ValueNode container = genTypeOrDeopt(RiType.Representation.StaticFields, holder, isInitialized); - CiKind kind = field.kind(); - if (container != null) { - LoadFieldNode load = new LoadFieldNode(container, field, graph); - appendOptimizedLoadField(kind, load); - } else { - // deopt will be generated by genTypeOrDeopt, not needed here - frameState.push(kind.stackKind(), append(ConstantNode.defaultForKind(kind, graph))); - } - } - } - - private void genPutStatic(int cpi, RiField field) { - RiType holder = field.holder(); - ValueNode container = genTypeOrDeopt(RiType.Representation.StaticFields, holder, field.isResolved() && holder.isInitialized()); - ValueNode value = frameState.pop(field.kind().stackKind()); - if (container != null) { - StoreFieldNode store = new StoreFieldNode(container, field, value, graph); - appendOptimizedStoreField(store); - } else { - // deopt will be generated by genTypeOrDeopt, not needed here - } - } - - private ConstantNode genTypeOrDeopt(RiType.Representation representation, RiType holder, boolean initialized) { - if (initialized) { - return appendConstant(holder.getEncoding(representation)); - } else { - storeResultGraph = false; - append(new DeoptimizeNode(DeoptAction.InvalidateRecompile, graph)); - return null; - } - } - - private void appendOptimizedStoreField(StoreFieldNode store) { - append(store); - } - - private void appendOptimizedLoadField(CiKind kind, LoadFieldNode load) { - // append the load to the instruction - ValueNode optimized = append(load); - frameState.push(kind.stackKind(), optimized); - } - - private void genInvokeStatic(RiMethod target, int cpi, RiConstantPool constantPool) { - RiType holder = target.holder(); - boolean isInitialized = target.isResolved() && holder.isInitialized(); - if (!isInitialized && GraalOptions.ResolveClassBeforeStaticInvoke) { - // Re-use the same resolution code as for accessing a static field. Even though - // the result of resolution is not used by the invocation (only the side effect - // of initialization is required), it can be commoned with static field accesses. - genTypeOrDeopt(RiType.Representation.StaticFields, holder, isInitialized); - } - ValueNode[] args = frameState.popArguments(target.signature().argumentSlots(false)); - appendInvoke(INVOKESTATIC, target, args, cpi, constantPool); - } - - private void genInvokeInterface(RiMethod target, int cpi, RiConstantPool constantPool) { - ValueNode[] args = frameState.popArguments(target.signature().argumentSlots(true)); - genInvokeIndirect(INVOKEINTERFACE, target, args, cpi, constantPool); - - } - - private void genInvokeVirtual(RiMethod target, int cpi, RiConstantPool constantPool) { - ValueNode[] args = frameState.popArguments(target.signature().argumentSlots(true)); - genInvokeIndirect(INVOKEVIRTUAL, target, args, cpi, constantPool); - - } - - private void genInvokeSpecial(RiMethod target, RiType knownHolder, int cpi, RiConstantPool constantPool) { - assert target != null; - assert target.signature() != null; - ValueNode[] args = frameState.popArguments(target.signature().argumentSlots(true)); - invokeDirect(target, args, knownHolder, cpi, constantPool); - - } - - private void genInvokeIndirect(int opcode, RiMethod target, ValueNode[] args, int cpi, RiConstantPool constantPool) { - ValueNode receiver = args[0]; - // attempt to devirtualize the call - if (target.isResolved()) { - RiType klass = target.holder(); - - // 0. check for trivial cases - if (target.canBeStaticallyBound() && !isAbstract(target.accessFlags())) { - // check for trivial cases (e.g. final methods, nonvirtual methods) - invokeDirect(target, args, target.holder(), cpi, constantPool); - return; - } - // 1. check if the exact type of the receiver can be determined - RiType exact = getExactType(klass, receiver); - if (exact != null && exact.isResolved()) { - // either the holder class is exact, or the receiver object has an exact type - invokeDirect(exact.resolveMethodImpl(target), args, exact, cpi, constantPool); - return; - } - } - // devirtualization failed, produce an actual invokevirtual - appendInvoke(opcode, target, args, cpi, constantPool); - } - - private CiKind returnKind(RiMethod target) { - return target.signature().returnKind(); - } - - private void invokeDirect(RiMethod target, ValueNode[] args, RiType knownHolder, int cpi, RiConstantPool constantPool) { - appendInvoke(INVOKESPECIAL, target, args, cpi, constantPool); - } - - private void appendInvoke(int opcode, RiMethod target, ValueNode[] args, int cpi, RiConstantPool constantPool) { - CiKind resultType = returnKind(target); - if (GraalOptions.DeoptALot) { - storeResultGraph = false; - DeoptimizeNode deoptimize = new DeoptimizeNode(DeoptAction.None, graph); - deoptimize.setMessage("invoke " + target.name()); - append(deoptimize); - frameState.pushReturn(resultType, ConstantNode.defaultForKind(resultType, graph)); - } else { - InvokeNode invoke = new InvokeNode(bci(), opcode, resultType.stackKind(), args, target, target.signature().returnType(method.holder()), graph); - ValueNode result = appendWithBCI(invoke); - invoke.setExceptionEdge(handleException(null, bci())); -// if (invoke.exceptionEdge() == null) { -// TTY.println("no exception edge" + unwindHandler); -// } - frameState.pushReturn(resultType, result); - } - } - - private RiType getExactType(RiType staticType, ValueNode receiver) { - RiType exact = staticType.exactType(); - if (exact == null) { - exact = receiver.exactType(); - if (exact == null) { - if (receiver.isConstant()) { - exact = runtime.getTypeOf(receiver.asConstant()); - } - if (exact == null) { - RiType declared = receiver.declaredType(); - exact = declared == null || !declared.isResolved() ? null : declared.exactType(); - } - } - } - return exact; - } - - private void callRegisterFinalizer() { - // append a call to the finalizer registration - append(new RegisterFinalizerNode(frameState.loadLocal(0), graph)); - } - - private void genReturn(ValueNode x) { - frameState.clearStack(); - if (x != null) { - frameState.push(x.kind, x); - } - appendGoto(createTarget(returnBlock(bci()), frameState)); - } - - private void genMonitorEnter(ValueNode x, int bci) { - int lockNumber = frameState.locksSize(); - MonitorAddressNode lockAddress = null; - if (runtime.sizeOfBasicObjectLock() != 0) { - lockAddress = new MonitorAddressNode(lockNumber, graph); - append(lockAddress); - } - MonitorEnterNode monitorEnter = new MonitorEnterNode(x, lockAddress, lockNumber, graph); - appendWithBCI(monitorEnter); - frameState.lock(x); - if (bci == FixedWithNextNode.SYNCHRONIZATION_ENTRY_BCI) { - monitorEnter.setStateAfter(frameState.create(0)); - } - } - - private void genMonitorExit(ValueNode x) { - int lockNumber = frameState.locksSize() - 1; - if (lockNumber < 0) { - throw new CiBailout("monitor stack underflow"); - } - MonitorAddressNode lockAddress = null; - if (runtime.sizeOfBasicObjectLock() != 0) { - lockAddress = new MonitorAddressNode(lockNumber, graph); - append(lockAddress); - } - appendWithBCI(new MonitorExitNode(x, lockAddress, lockNumber, graph)); - frameState.unlock(); - } - - private void genJsr(int dest) { - throw new JSRNotSupportedBailout(); - } - - private void genRet(int localIndex) { - throw new JSRNotSupportedBailout(); - } - - private void genTableswitch() { - int bci = bci(); - ValueNode value = frameState.ipop(); - BytecodeTableSwitch ts = new BytecodeTableSwitch(stream(), bci); - int max = ts.numberOfCases(); - List list = new ArrayList(max + 1); - List offsetList = new ArrayList(max + 1); - for (int i = 0; i < max; i++) { - // add all successors to the successor list - int offset = ts.offsetAt(i); - list.add(null); - offsetList.add(offset); - } - int offset = ts.defaultOffset(); - list.add(null); - offsetList.add(offset); - TableSwitchNode tableSwitch = new TableSwitchNode(value, list, ts.lowKey(), switchProbability(list.size(), bci), graph); - for (int i = 0; i < offsetList.size(); ++i) { - tableSwitch.setBlockSuccessor(i, createTargetAt(bci + offsetList.get(i), frameState)); - } - append(tableSwitch); - } - - private double[] switchProbability(int numberOfCases, int bci) { - double[] prob = method.switchProbability(bci); - if (prob != null) { - assert prob.length == numberOfCases; - } else { - if (GraalOptions.TraceProbability) { - TTY.println("Missing probability (switch) in " + method + " at bci " + bci); - } - prob = new double[numberOfCases]; - for (int i = 0; i < numberOfCases; i++) { - prob[i] = 1.0d / numberOfCases; - } - } - return prob; - } - - private void genLookupswitch() { - int bci = bci(); - ValueNode value = frameState.ipop(); - BytecodeLookupSwitch ls = new BytecodeLookupSwitch(stream(), bci); - int max = ls.numberOfCases(); - List list = new ArrayList(max + 1); - List offsetList = new ArrayList(max + 1); - int[] keys = new int[max]; - for (int i = 0; i < max; i++) { - // add all successors to the successor list - int offset = ls.offsetAt(i); - list.add(null); - offsetList.add(offset); - keys[i] = ls.keyAt(i); - } - int offset = ls.defaultOffset(); - list.add(null); - offsetList.add(offset); - LookupSwitchNode lookupSwitch = new LookupSwitchNode(value, list, keys, switchProbability(list.size(), bci), graph); - for (int i = 0; i < offsetList.size(); ++i) { - lookupSwitch.setBlockSuccessor(i, createTargetAt(bci + offsetList.get(i), frameState)); - } - append(lookupSwitch); - } - - private ConstantNode appendConstant(CiConstant constant) { - return new ConstantNode(constant, graph); - } - - private ValueNode append(FixedNode fixed) { - if (fixed instanceof DeoptimizeNode && lastInstr.predecessor() != null) { - Node cur = lastInstr; - Node prev = cur; - while (cur != cur.graph().start() && !(cur instanceof ControlSplitNode)) { - assert cur.predecessor() != null; - prev = cur; - cur = cur.predecessor(); - if (cur.predecessor() == null) { - break; - } - - if (cur instanceof ExceptionObjectNode) { - break; - } - } - - if (cur instanceof IfNode) { - IfNode ifNode = (IfNode) cur; - if (ifNode.falseSuccessor() == prev) { - FixedNode successor = ifNode.trueSuccessor(); - ifNode.setTrueSuccessor(null); - BooleanNode condition = ifNode.compare(); - FixedGuardNode fixedGuard = new FixedGuardNode(condition, graph); - fixedGuard.setNext(successor); - ifNode.replaceAndDelete(fixedGuard); - lastInstr = null; - return fixed; - } - } else if (prev != cur) { - prev.replaceAtPredecessors(fixed); - lastInstr = null; - return fixed; - } - } - lastInstr.setNext(fixed); - lastInstr = null; - return fixed; - } - - private ValueNode append(FixedWithNextNode x) { - return appendWithBCI(x); - } - - private ValueNode append(ValueNode v) { - return v; - } - - private ValueNode appendWithBCI(FixedWithNextNode x) { - assert x.predecessor() == null : "instruction should not have been appended yet"; - assert lastInstr.next() == null : "cannot append instruction to instruction which isn't end (" + lastInstr + "->" + lastInstr.next() + ")"; - lastInstr.setNext(x); - lastInstr = x; - return x; - } - - private FixedNode createTargetAt(int bci, FrameStateAccess stateAfter) { - return createTarget(blockFromBci[bci], stateAfter); - } - - private FixedNode createTarget(Block block, FrameStateAccess stateAfter) { - assert block != null && stateAfter != null; - assert block.isLoopHeader || block.firstInstruction == null || block.firstInstruction.next() == null : - "non-loop block must be iterated after all its predecessors. startBci=" + block.startBci + ", " + block.getClass().getSimpleName() + ", " + block.firstInstruction.next(); - - if (block.isExceptionEntry) { - assert stateAfter.stackSize() == 1; - } - - if (block.firstInstruction == null) { - if (block.isLoopHeader) { - LoopBeginNode loopBegin = new LoopBeginNode(graph); - loopBegin.addEnd(new EndNode(graph)); - LoopEndNode loopEnd = new LoopEndNode(graph); - loopEnd.setLoopBegin(loopBegin); - PlaceholderNode pBegin = new PlaceholderNode(graph); - pBegin.setNext(loopBegin.forwardEdge()); - PlaceholderNode pEnd = new PlaceholderNode(graph); - pEnd.setNext(loopEnd); - loopBegin.setStateAfter(stateAfter.duplicate(block.startBci)); - block.firstInstruction = pBegin; - } else { - block.firstInstruction = new PlaceholderNode(graph); - } - } - mergeOrClone(block, stateAfter); - addToWorkList(block); - - FixedNode result = null; - if (block.isLoopHeader && isVisited(block)) { - result = (StateSplit) loopBegin(block).loopEnd().predecessor(); - } else { - result = block.firstInstruction; - } - - assert result instanceof MergeNode || result instanceof PlaceholderNode : result; - - if (result instanceof MergeNode) { - if (result instanceof LoopBeginNode) { - result = ((LoopBeginNode) result).forwardEdge(); - } else { - EndNode end = new EndNode(graph); - ((MergeNode) result).addEnd(end); - PlaceholderNode p = new PlaceholderNode(graph); - int bci = block.startBci; - if (block instanceof ExceptionBlock) { - bci = ((ExceptionBlock) block).deoptBci; - } - p.setStateAfter(stateAfter.duplicate(bci)); - p.setNext(end); - result = p; - } - } - assert !(result instanceof LoopBeginNode || result instanceof MergeNode); - return result; - } - - private ValueNode synchronizedObject(FrameStateAccess state, RiMethod target) { - if (isStatic(target.accessFlags())) { - ConstantNode classConstant = new ConstantNode(target.holder().getEncoding(Representation.JavaClass), graph); - return append(classConstant); - } else { - return state.localAt(0); - } - } - - private void iterateAllBlocks() { - Block block; - while ((block = removeFromWorkList()) != null) { - - // remove blocks that have no predecessors by the time it their bytecodes are parsed - if (block.firstInstruction == null) { - markVisited(block); - continue; - } - - if (!isVisited(block)) { - markVisited(block); - // now parse the block - if (block.isLoopHeader) { - LoopBeginNode begin = loopBegin(block); - FrameState preLoopState = ((StateSplit) block.firstInstruction).stateAfter(); - assert preLoopState != null; - FrameState duplicate = preLoopState.duplicate(preLoopState.bci); - begin.setStateAfter(duplicate); - insertLoopPhis(begin, duplicate); - lastInstr = begin; - } else { - lastInstr = block.firstInstruction; - } - frameState.initializeFrom(((StateSplit) lastInstr).stateAfter()); - assert lastInstr.next() == null : "instructions already appended at block " + block.blockID; - - if (block == returnBlock) { - createReturnBlock(block); - } else if (block == unwindBlock) { - createUnwindBlock(block); - } else if (block instanceof ExceptionBlock) { - createExceptionDispatch((ExceptionBlock) block); - } else if (block instanceof DeoptBlock) { - createDeoptBlock((DeoptBlock) block); - } else { - frameState.setRethrowException(false); - iterateBytecodesForBlock(block); - } - } - } - for (Block b : blocksVisited) { - if (b.isLoopHeader) { - LoopBeginNode begin = loopBegin(b); - LoopEndNode loopEnd = begin.loopEnd(); - StateSplit loopEndPred = (StateSplit) loopEnd.predecessor(); - -// This can happen with degenerated loops like this one: -// for (;;) { -// try { -// break; -// } catch (UnresolvedException iioe) { -// } -// } - if (loopEndPred.stateAfter() != null) { - //loopHeaderMerge.stateBefore().merge(begin, end.stateBefore()); - //assert loopHeaderMerge.equals(end.stateBefore()); - begin.stateAfter().merge(begin, loopEndPred.stateAfter()); - } else { - loopEndPred.delete(); - loopEnd.delete(); - MergeNode merge = new MergeNode(graph); - merge.addEnd(begin.forwardEdge()); - FixedNode next = begin.next(); - begin.setNext(null); - merge.setNext(next); - merge.setStateAfter(begin.stateAfter()); - begin.replaceAndDelete(merge); - } - } - } - } - - private static LoopBeginNode loopBegin(Block block) { - EndNode endNode = (EndNode) block.firstInstruction.next(); - LoopBeginNode loopBegin = (LoopBeginNode) endNode.merge(); - return loopBegin; - } - - private void createDeoptBlock(DeoptBlock block) { - storeResultGraph = false; - append(new DeoptimizeNode(DeoptAction.InvalidateReprofile, graph)); - } - - private void createUnwindBlock(Block block) { - if (Modifier.isSynchronized(method.accessFlags())) { - genMonitorExit(methodSynchronizedObject); - } - UnwindNode unwindNode = new UnwindNode(frameState.apop(), graph); - graph.setUnwind(unwindNode); - append(unwindNode); - } - - private void createReturnBlock(Block block) { - if (method.isConstructor() && method.holder().superType() == null) { - callRegisterFinalizer(); - } - CiKind returnKind = method.signature().returnKind().stackKind(); - ValueNode x = returnKind == CiKind.Void ? null : frameState.pop(returnKind); - assert frameState.stackSize() == 0; - - if (Modifier.isSynchronized(method.accessFlags())) { - genMonitorExit(methodSynchronizedObject); - } - ReturnNode returnNode = new ReturnNode(x, graph); - graph.setReturn(returnNode); - append(returnNode); - } - - private void createExceptionDispatch(ExceptionBlock block) { - if (block.handler == null) { - assert frameState.stackSize() == 1 : "only exception object expected on stack, actual size: " + frameState.stackSize(); - createUnwindBlock(block); - } else { - assert frameState.stackSize() == 1 : frameState; - - Block nextBlock = block.next == null ? unwindBlock(block.deoptBci) : block.next; - - - RiType catchType = block.handler.catchType(); - ConstantNode typeInstruction = genTypeOrDeopt(RiType.Representation.ObjectHub, catchType, catchType.isResolved()); - if (typeInstruction != null) { - FixedNode catchSuccessor = createTarget(blockFromBci[block.handler.handlerBCI()], frameState); - FixedNode nextDispatch = createTarget(nextBlock, frameState); - ValueNode exception = frameState.stackAt(0); - IfNode ifNode = new IfNode(new InstanceOfNode(typeInstruction, exception, false, graph), 0.5, graph); - append(ifNode); - ifNode.setTrueSuccessor(catchSuccessor); - ifNode.setFalseSuccessor(nextDispatch); - } - } - } - - private void appendGoto(FixedNode target) { - if (lastInstr != null) { - lastInstr.setNext(target); - } - } - - private void iterateBytecodesForBlock(Block block) { - assert frameState != null; - - stream.setBCI(block.startBci); - - int endBCI = stream.endBCI(); - - int bci = block.startBci; - while (bci < endBCI) { - Block nextBlock = blockFromBci[bci]; - if (nextBlock != null && nextBlock != block) { - assert !nextBlock.isExceptionEntry; - // we fell through to the next block, add a goto and break - appendGoto(createTarget(nextBlock, frameState)); - break; - } - // read the opcode - int opcode = stream.currentBC(); - traceState(); - traceInstruction(bci, opcode, bci == block.startBci); - processBytecode(bci, opcode); - - if (lastInstr == null || IdentifyBlocksPhase.isBlockEnd(lastInstr) || lastInstr.next() != null) { - break; - } - - stream.next(); - bci = stream.currentBCI(); - if (lastInstr instanceof StateSplit) { - StateSplit stateSplit = (StateSplit) lastInstr; - if (stateSplit.stateAfter() == null && stateSplit.needsStateAfter()) { - stateSplit.setStateAfter(frameState.create(bci)); - } - } - } - } - - private void traceState() { - if (GraalOptions.TraceBytecodeParserLevel >= TRACELEVEL_STATE && !TTY.isSuppressed()) { - log.println(String.format("| state [nr locals = %d, stack depth = %d, method = %s]", frameState.localsSize(), frameState.stackSize(), method)); - for (int i = 0; i < frameState.localsSize(); ++i) { - ValueNode value = frameState.localAt(i); - log.println(String.format("| local[%d] = %-8s : %s", i, value == null ? "bogus" : value.kind.javaName, value)); - } - for (int i = 0; i < frameState.stackSize(); ++i) { - ValueNode value = frameState.stackAt(i); - log.println(String.format("| stack[%d] = %-8s : %s", i, value == null ? "bogus" : value.kind.javaName, value)); - } - for (int i = 0; i < frameState.locksSize(); ++i) { - ValueNode value = frameState.lockAt(i); - log.println(String.format("| lock[%d] = %-8s : %s", i, value == null ? "bogus" : value.kind.javaName, value)); - } - } - } - - private void processBytecode(int bci, int opcode) { - int cpi; - - // Checkstyle: stop - switch (opcode) { - case NOP : /* nothing to do */ break; - case ACONST_NULL : frameState.apush(appendConstant(CiConstant.NULL_OBJECT)); break; - case ICONST_M1 : frameState.ipush(appendConstant(CiConstant.INT_MINUS_1)); break; - case ICONST_0 : frameState.ipush(appendConstant(CiConstant.INT_0)); break; - case ICONST_1 : frameState.ipush(appendConstant(CiConstant.INT_1)); break; - case ICONST_2 : frameState.ipush(appendConstant(CiConstant.INT_2)); break; - case ICONST_3 : frameState.ipush(appendConstant(CiConstant.INT_3)); break; - case ICONST_4 : frameState.ipush(appendConstant(CiConstant.INT_4)); break; - case ICONST_5 : frameState.ipush(appendConstant(CiConstant.INT_5)); break; - case LCONST_0 : frameState.lpush(appendConstant(CiConstant.LONG_0)); break; - case LCONST_1 : frameState.lpush(appendConstant(CiConstant.LONG_1)); break; - case FCONST_0 : frameState.fpush(appendConstant(CiConstant.FLOAT_0)); break; - case FCONST_1 : frameState.fpush(appendConstant(CiConstant.FLOAT_1)); break; - case FCONST_2 : frameState.fpush(appendConstant(CiConstant.FLOAT_2)); break; - case DCONST_0 : frameState.dpush(appendConstant(CiConstant.DOUBLE_0)); break; - case DCONST_1 : frameState.dpush(appendConstant(CiConstant.DOUBLE_1)); break; - case BIPUSH : frameState.ipush(appendConstant(CiConstant.forInt(stream.readByte()))); break; - case SIPUSH : frameState.ipush(appendConstant(CiConstant.forInt(stream.readShort()))); break; - case LDC : // fall through - case LDC_W : // fall through - case LDC2_W : genLoadConstant(stream.readCPI()); break; - case ILOAD : loadLocal(stream.readLocalIndex(), CiKind.Int); break; - case LLOAD : loadLocal(stream.readLocalIndex(), CiKind.Long); break; - case FLOAD : loadLocal(stream.readLocalIndex(), CiKind.Float); break; - case DLOAD : loadLocal(stream.readLocalIndex(), CiKind.Double); break; - case ALOAD : loadLocal(stream.readLocalIndex(), CiKind.Object); break; - case ILOAD_0 : // fall through - case ILOAD_1 : // fall through - case ILOAD_2 : // fall through - case ILOAD_3 : loadLocal(opcode - ILOAD_0, CiKind.Int); break; - case LLOAD_0 : // fall through - case LLOAD_1 : // fall through - case LLOAD_2 : // fall through - case LLOAD_3 : loadLocal(opcode - LLOAD_0, CiKind.Long); break; - case FLOAD_0 : // fall through - case FLOAD_1 : // fall through - case FLOAD_2 : // fall through - case FLOAD_3 : loadLocal(opcode - FLOAD_0, CiKind.Float); break; - case DLOAD_0 : // fall through - case DLOAD_1 : // fall through - case DLOAD_2 : // fall through - case DLOAD_3 : loadLocal(opcode - DLOAD_0, CiKind.Double); break; - case ALOAD_0 : // fall through - case ALOAD_1 : // fall through - case ALOAD_2 : // fall through - case ALOAD_3 : loadLocal(opcode - ALOAD_0, CiKind.Object); break; - case IALOAD : genLoadIndexed(CiKind.Int ); break; - case LALOAD : genLoadIndexed(CiKind.Long ); break; - case FALOAD : genLoadIndexed(CiKind.Float ); break; - case DALOAD : genLoadIndexed(CiKind.Double); break; - case AALOAD : genLoadIndexed(CiKind.Object); break; - case BALOAD : genLoadIndexed(CiKind.Byte ); break; - case CALOAD : genLoadIndexed(CiKind.Char ); break; - case SALOAD : genLoadIndexed(CiKind.Short ); break; - case ISTORE : storeLocal(CiKind.Int, stream.readLocalIndex()); break; - case LSTORE : storeLocal(CiKind.Long, stream.readLocalIndex()); break; - case FSTORE : storeLocal(CiKind.Float, stream.readLocalIndex()); break; - case DSTORE : storeLocal(CiKind.Double, stream.readLocalIndex()); break; - case ASTORE : storeLocal(CiKind.Object, stream.readLocalIndex()); break; - case ISTORE_0 : // fall through - case ISTORE_1 : // fall through - case ISTORE_2 : // fall through - case ISTORE_3 : storeLocal(CiKind.Int, opcode - ISTORE_0); break; - case LSTORE_0 : // fall through - case LSTORE_1 : // fall through - case LSTORE_2 : // fall through - case LSTORE_3 : storeLocal(CiKind.Long, opcode - LSTORE_0); break; - case FSTORE_0 : // fall through - case FSTORE_1 : // fall through - case FSTORE_2 : // fall through - case FSTORE_3 : storeLocal(CiKind.Float, opcode - FSTORE_0); break; - case DSTORE_0 : // fall through - case DSTORE_1 : // fall through - case DSTORE_2 : // fall through - case DSTORE_3 : storeLocal(CiKind.Double, opcode - DSTORE_0); break; - case ASTORE_0 : // fall through - case ASTORE_1 : // fall through - case ASTORE_2 : // fall through - case ASTORE_3 : storeLocal(CiKind.Object, opcode - ASTORE_0); break; - case IASTORE : genStoreIndexed(CiKind.Int ); break; - case LASTORE : genStoreIndexed(CiKind.Long ); break; - case FASTORE : genStoreIndexed(CiKind.Float ); break; - case DASTORE : genStoreIndexed(CiKind.Double); break; - case AASTORE : genStoreIndexed(CiKind.Object); break; - case BASTORE : genStoreIndexed(CiKind.Byte ); break; - case CASTORE : genStoreIndexed(CiKind.Char ); break; - case SASTORE : genStoreIndexed(CiKind.Short ); break; - case POP : // fall through - case POP2 : // fall through - case DUP : // fall through - case DUP_X1 : // fall through - case DUP_X2 : // fall through - case DUP2 : // fall through - case DUP2_X1 : // fall through - case DUP2_X2 : // fall through - case SWAP : stackOp(opcode); break; - case IADD : // fall through - case ISUB : // fall through - case IMUL : genArithmeticOp(CiKind.Int, opcode); break; - case IDIV : // fall through - case IREM : genArithmeticOp(CiKind.Int, opcode, true); break; - case LADD : // fall through - case LSUB : // fall through - case LMUL : genArithmeticOp(CiKind.Long, opcode); break; - case LDIV : // fall through - case LREM : genArithmeticOp(CiKind.Long, opcode, true); break; - case FADD : // fall through - case FSUB : // fall through - case FMUL : // fall through - case FDIV : // fall through - case FREM : genArithmeticOp(CiKind.Float, opcode); break; - case DADD : // fall through - case DSUB : // fall through - case DMUL : // fall through - case DDIV : // fall through - case DREM : genArithmeticOp(CiKind.Double, opcode); break; - case INEG : genNegateOp(CiKind.Int); break; - case LNEG : genNegateOp(CiKind.Long); break; - case FNEG : genNegateOp(CiKind.Float); break; - case DNEG : genNegateOp(CiKind.Double); break; - case ISHL : // fall through - case ISHR : // fall through - case IUSHR : genShiftOp(CiKind.Int, opcode); break; - case IAND : // fall through - case IOR : // fall through - case IXOR : genLogicOp(CiKind.Int, opcode); break; - case LSHL : // fall through - case LSHR : // fall through - case LUSHR : genShiftOp(CiKind.Long, opcode); break; - case LAND : // fall through - case LOR : // fall through - case LXOR : genLogicOp(CiKind.Long, opcode); break; - case IINC : genIncrement(); break; - case I2L : genConvert(opcode, CiKind.Int , CiKind.Long ); break; - case I2F : genConvert(opcode, CiKind.Int , CiKind.Float ); break; - case I2D : genConvert(opcode, CiKind.Int , CiKind.Double); break; - case L2I : genConvert(opcode, CiKind.Long , CiKind.Int ); break; - case L2F : genConvert(opcode, CiKind.Long , CiKind.Float ); break; - case L2D : genConvert(opcode, CiKind.Long , CiKind.Double); break; - case F2I : genConvert(opcode, CiKind.Float , CiKind.Int ); break; - case F2L : genConvert(opcode, CiKind.Float , CiKind.Long ); break; - case F2D : genConvert(opcode, CiKind.Float , CiKind.Double); break; - case D2I : genConvert(opcode, CiKind.Double, CiKind.Int ); break; - case D2L : genConvert(opcode, CiKind.Double, CiKind.Long ); break; - case D2F : genConvert(opcode, CiKind.Double, CiKind.Float ); break; - case I2B : genConvert(opcode, CiKind.Int , CiKind.Byte ); break; - case I2C : genConvert(opcode, CiKind.Int , CiKind.Char ); break; - case I2S : genConvert(opcode, CiKind.Int , CiKind.Short ); break; - case LCMP : genCompareOp(CiKind.Long, opcode, CiKind.Int); break; - case FCMPL : genCompareOp(CiKind.Float, opcode, CiKind.Int); break; - case FCMPG : genCompareOp(CiKind.Float, opcode, CiKind.Int); break; - case DCMPL : genCompareOp(CiKind.Double, opcode, CiKind.Int); break; - case DCMPG : genCompareOp(CiKind.Double, opcode, CiKind.Int); break; - case IFEQ : genIfZero(Condition.EQ); break; - case IFNE : genIfZero(Condition.NE); break; - case IFLT : genIfZero(Condition.LT); break; - case IFGE : genIfZero(Condition.GE); break; - case IFGT : genIfZero(Condition.GT); break; - case IFLE : genIfZero(Condition.LE); break; - case IF_ICMPEQ : genIfSame(CiKind.Int, Condition.EQ); break; - case IF_ICMPNE : genIfSame(CiKind.Int, Condition.NE); break; - case IF_ICMPLT : genIfSame(CiKind.Int, Condition.LT); break; - case IF_ICMPGE : genIfSame(CiKind.Int, Condition.GE); break; - case IF_ICMPGT : genIfSame(CiKind.Int, Condition.GT); break; - case IF_ICMPLE : genIfSame(CiKind.Int, Condition.LE); break; - case IF_ACMPEQ : genIfSame(frameState.peekKind(), Condition.EQ); break; - case IF_ACMPNE : genIfSame(frameState.peekKind(), Condition.NE); break; - case GOTO : genGoto(stream.currentBCI(), stream.readBranchDest()); break; - case JSR : genJsr(stream.readBranchDest()); break; - case RET : genRet(stream.readLocalIndex()); break; - case TABLESWITCH : genTableswitch(); break; - case LOOKUPSWITCH : genLookupswitch(); break; - case IRETURN : genReturn(frameState.ipop()); break; - case LRETURN : genReturn(frameState.lpop()); break; - case FRETURN : genReturn(frameState.fpop()); break; - case DRETURN : genReturn(frameState.dpop()); break; - case ARETURN : genReturn(frameState.apop()); break; - case RETURN : genReturn(null ); break; - case GETSTATIC : cpi = stream.readCPI(); genGetStatic(cpi, constantPool.lookupField(cpi, opcode)); break; - case PUTSTATIC : cpi = stream.readCPI(); genPutStatic(cpi, constantPool.lookupField(cpi, opcode)); break; - case GETFIELD : cpi = stream.readCPI(); genGetField(cpi, constantPool.lookupField(cpi, opcode)); break; - case PUTFIELD : cpi = stream.readCPI(); genPutField(cpi, constantPool.lookupField(cpi, opcode)); break; - case INVOKEVIRTUAL : cpi = stream.readCPI(); genInvokeVirtual(constantPool.lookupMethod(cpi, opcode), cpi, constantPool); break; - case INVOKESPECIAL : cpi = stream.readCPI(); genInvokeSpecial(constantPool.lookupMethod(cpi, opcode), null, cpi, constantPool); break; - case INVOKESTATIC : cpi = stream.readCPI(); genInvokeStatic(constantPool.lookupMethod(cpi, opcode), cpi, constantPool); break; - case INVOKEINTERFACE: cpi = stream.readCPI(); genInvokeInterface(constantPool.lookupMethod(cpi, opcode), cpi, constantPool); break; - case NEW : genNewInstance(stream.readCPI()); break; - case NEWARRAY : genNewTypeArray(stream.readLocalIndex()); break; - case ANEWARRAY : genNewObjectArray(stream.readCPI()); break; - case ARRAYLENGTH : genArrayLength(); break; - case ATHROW : genThrow(stream.currentBCI()); break; - case CHECKCAST : genCheckCast(); break; - case INSTANCEOF : genInstanceOf(); break; - case MONITORENTER : genMonitorEnter(frameState.apop(), stream.currentBCI()); break; - case MONITOREXIT : genMonitorExit(frameState.apop()); break; - case MULTIANEWARRAY : genNewMultiArray(stream.readCPI()); break; - case IFNULL : genIfNull(Condition.EQ); break; - case IFNONNULL : genIfNull(Condition.NE); break; - case GOTO_W : genGoto(stream.currentBCI(), stream.readFarBranchDest()); break; - case JSR_W : genJsr(stream.readFarBranchDest()); break; - case BREAKPOINT: - throw new CiBailout("concurrent setting of breakpoint"); - default: - throw new CiBailout("Unsupported opcode " + opcode + " (" + nameOf(opcode) + ") [bci=" + bci + "]"); - } - // Checkstyle: resume - } - - private void traceInstruction(int bci, int opcode, boolean blockStart) { - if (GraalOptions.TraceBytecodeParserLevel >= TRACELEVEL_INSTRUCTIONS && !TTY.isSuppressed()) { - StringBuilder sb = new StringBuilder(40); - sb.append(blockStart ? '+' : '|'); - if (bci < 10) { - sb.append(" "); - } else if (bci < 100) { - sb.append(' '); - } - sb.append(bci).append(": ").append(Bytecodes.nameOf(opcode)); - for (int i = bci + 1; i < stream.nextBCI(); ++i) { - sb.append(' ').append(stream.readUByte(i)); - } - log.println(sb.toString()); - } - } - - private void genArrayLength() { - frameState.ipush(append(new ArrayLengthNode(frameState.apop(), graph))); - } - - /** - * Adds a block to the worklist, if it is not already in the worklist. - * This method will keep the worklist topologically stored (i.e. the lower - * DFNs are earlier in the list). - * @param block the block to add to the work list - */ - private void addToWorkList(Block block) { - if (!isOnWorkList(block)) { - markOnWorkList(block); - sortIntoWorkList(block); - } - } - - private void sortIntoWorkList(Block top) { - workList.offer(top); - } - - /** - * Removes the next block from the worklist. The list is sorted topologically, so the - * block with the lowest depth first number in the list will be removed and returned. - * @return the next block from the worklist; {@code null} if there are no blocks - * in the worklist - */ - private Block removeFromWorkList() { - return workList.poll(); - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/InliningPhase.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/InliningPhase.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,616 +0,0 @@ -/* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.compiler.phases; - -import java.lang.reflect.*; -import java.util.*; - -import com.oracle.max.graal.compiler.*; -import com.oracle.max.graal.compiler.debug.*; -import com.oracle.max.graal.compiler.graph.*; -import com.oracle.max.graal.extensions.*; -import com.oracle.max.graal.graph.*; -import com.oracle.max.graal.nodes.*; -import com.oracle.max.graal.nodes.DeoptimizeNode.DeoptAction; -import com.oracle.max.graal.nodes.calc.*; -import com.oracle.max.graal.nodes.java.*; -import com.sun.cri.bytecode.*; -import com.sun.cri.ci.*; -import com.sun.cri.ri.*; - - -public class InliningPhase extends Phase { - /* - * - Detect method which only call another method with some parameters set to constants: void foo(a) -> void foo(a, b) -> void foo(a, b, c) ... - * These should not be taken into account when determining inlining depth. - */ - - public static final HashMap methodCount = new HashMap(); - - private static final int MAX_ITERATIONS = 1000; - - private final GraalCompilation compilation; - private final IR ir; - - private int inliningSize; - private final Collection hints; - - public InliningPhase(GraalCompilation compilation, IR ir, Collection hints) { - this.compilation = compilation; - this.ir = ir; - this.hints = hints; - } - - private Queue newInvokes = new ArrayDeque(); - private CompilerGraph graph; - - @Override - protected void run(Graph graph) { - this.graph = (CompilerGraph) graph; - - float ratio = GraalOptions.MaximumInlineRatio; - inliningSize = compilation.method.codeSize(); - - if (hints != null) { - newInvokes.addAll(hints); - } else { - for (InvokeNode invoke : graph.getNodes(InvokeNode.class)) { - newInvokes.add(invoke); - } - } - - for (int iterations = 0; iterations < MAX_ITERATIONS; iterations++) { - Queue queue = newInvokes; - newInvokes = new ArrayDeque(); - for (InvokeNode invoke : queue) { - if (!invoke.isDeleted()) { - if (GraalOptions.Meter) { - GraalMetrics.InlineConsidered++; - if (!invoke.target.hasCompiledCode()) { - GraalMetrics.InlineUncompiledConsidered++; - } - } - - RiMethod code = inlineInvoke(invoke, iterations, ratio); - if (code != null) { - if (graph.getNodeCount() > GraalOptions.MaximumInstructionCount) { - break; - } - - inlineMethod(invoke, code); - if (GraalOptions.TraceInlining) { - if (methodCount.get(code) == null) { - methodCount.put(code, 1); - } else { - methodCount.put(code, methodCount.get(code) + 1); - } - } - if (GraalOptions.Meter) { - GraalMetrics.InlinePerformed++; - if (!invoke.target.hasCompiledCode()) { - GraalMetrics.InlineUncompiledPerformed++; - } - } - } - } - } - if (newInvokes.isEmpty()) { - break; - } - -// new DeadCodeEliminationPhase().apply(graph); - - ratio *= GraalOptions.MaximumInlineRatio; - } - - if (GraalOptions.TraceInlining) { - int inlined = 0; - int duplicate = 0; - for (Map.Entry entry : methodCount.entrySet()) { - inlined += entry.getValue(); - duplicate += entry.getValue() - 1; - } - if (inlined > 0) { - TTY.println("overhead: %d (%5.3f %%)", duplicate, duplicate * 100.0 / inlined); - } - } - } - - private RiMethod inlineInvoke(InvokeNode invoke, int iterations, float ratio) { - RiMethod parent = invoke.stateAfter().method(); - RiTypeProfile profile = parent.typeProfile(invoke.bci); - if (GraalOptions.Intrinsify) { - if (GraalOptions.Extend && intrinsicGraph(parent, invoke.bci, invoke.target, invoke.arguments()) != null) { - return invoke.target; - } - if (compilation.runtime.intrinsicGraph(parent, invoke.bci, invoke.target, invoke.arguments()) != null) { - // Always intrinsify. - return invoke.target; - } - } - if (!checkInvokeConditions(invoke)) { - return null; - } - if (invoke.opcode() == Bytecodes.INVOKESPECIAL || invoke.target.canBeStaticallyBound()) { - if (checkTargetConditions(invoke.target, iterations) && checkSizeConditions(parent, iterations, invoke.target, invoke, profile, ratio)) { - return invoke.target; - } - return null; - } - if (invoke.receiver().exactType() != null) { - RiType exact = invoke.receiver().exactType(); - assert exact.isSubtypeOf(invoke.target().holder()) : exact + " subtype of " + invoke.target().holder(); - RiMethod resolved = exact.resolveMethodImpl(invoke.target()); - if (checkTargetConditions(resolved, iterations) && checkSizeConditions(parent, iterations, resolved, invoke, profile, ratio)) { - return resolved; - } - return null; - } - RiType holder = invoke.target().holder(); - - if (invoke.receiver().declaredType() != null) { - RiType declared = invoke.receiver().declaredType(); - // the invoke target might be more specific than the holder (happens after inlining: locals lose their declared type...) - // TODO (ls) fix this - if (declared.isResolved() && declared.isSubtypeOf(invoke.target().holder())) { - holder = declared; - } - } - - RiMethod concrete = holder.uniqueConcreteMethod(invoke.target); - if (concrete != null) { - if (checkTargetConditions(concrete, iterations) && checkSizeConditions(parent, iterations, concrete, invoke, profile, ratio)) { - if (GraalOptions.TraceInlining) { - String targetName = CiUtil.format("%H.%n(%p):%r", invoke.target, false); - String concreteName = CiUtil.format("%H.%n(%p):%r", concrete, false); - TTY.println("recording concrete method assumption: %s -> %s", targetName, concreteName); - } - graph.assumptions().recordConcreteMethod(invoke.target, concrete); - return concrete; - } - return null; - } - if (profile != null && profile.probabilities != null && profile.probabilities.length > 0 && profile.morphism == 1) { - if (GraalOptions.InlineWithTypeCheck) { - // type check and inlining... - concrete = profile.types[0].resolveMethodImpl(invoke.target); - if (concrete != null && checkTargetConditions(concrete, iterations) && checkSizeConditions(parent, iterations, concrete, invoke, profile, ratio)) { - IsTypeNode isType = new IsTypeNode(invoke.receiver(), profile.types[0], compilation.graph); - FixedGuardNode guard = new FixedGuardNode(isType, graph); - assert invoke.predecessor() != null; - invoke.predecessor().replaceFirstSuccessor(invoke, guard); - guard.setNext(invoke); - - if (GraalOptions.TraceInlining) { - TTY.println("inlining with type check, type probability: %5.3f", profile.probabilities[0]); - } - return concrete; - } - return null; - } else { - if (GraalOptions.TraceInlining) { - TTY.println("not inlining %s because GraalOptions.InlineWithTypeCheck == false", methodName(invoke.target, invoke)); - } - return null; - } - } else { - if (GraalOptions.TraceInlining) { - TTY.println("not inlining %s because no monomorphic receiver could be found", methodName(invoke.target, invoke)); - } - return null; - } - } - - private String methodName(RiMethod method) { - return CiUtil.format("%H.%n(%p):%r", method, false) + " (" + method.codeSize() + " bytes)"; - } - - private String methodName(RiMethod method, InvokeNode invoke) { - if (invoke != null) { - RiMethod parent = invoke.stateAfter().method(); - return parent.name() + "@" + invoke.bci + ": " + CiUtil.format("%H.%n(%p):%r", method, false) + " (" + method.codeSize() + " bytes)"; - } else { - return CiUtil.format("%H.%n(%p):%r", method, false) + " (" + method.codeSize() + " bytes)"; - } - } - - private boolean checkInvokeConditions(InvokeNode invoke) { - if (!invoke.canInline()) { - if (GraalOptions.TraceInlining) { - TTY.println("not inlining %s because the invoke is manually set to be non-inlinable", methodName(invoke.target, invoke)); - } - return false; - } - if (invoke.stateAfter() == null) { - if (GraalOptions.TraceInlining) { - TTY.println("not inlining %s because the invoke has no after state", methodName(invoke.target, invoke)); - } - return false; - } - if (invoke.stateAfter().locksSize() > 0) { - if (GraalOptions.TraceInlining) { - TTY.println("not inlining %s because of locks", methodName(invoke.target, invoke)); - } - return false; - } - if (!invoke.target.isResolved()) { - if (GraalOptions.TraceInlining) { - TTY.println("not inlining %s because the invoke target is unresolved", methodName(invoke.target, invoke)); - } - return false; - } - if (invoke.predecessor() == null) { - if (GraalOptions.TraceInlining) { - TTY.println("not inlining %s because the invoke is dead code", methodName(invoke.target, invoke)); - } - return false; - } - if (invoke.stateAfter() == null) { - if (GraalOptions.TraceInlining) { - TTY.println("not inlining %s because of missing frame state", methodName(invoke.target, invoke)); - } - } - return true; - } - - private boolean checkTargetConditions(RiMethod method, int iterations) { - if (!method.isResolved()) { - if (GraalOptions.TraceInlining) { - TTY.println("not inlining %s because it is unresolved", methodName(method)); - } - return false; - } - if (Modifier.isNative(method.accessFlags())) { - if (GraalOptions.TraceInlining) { - TTY.println("not inlining %s because it is a native method", methodName(method)); - } - return false; - } - if (Modifier.isAbstract(method.accessFlags())) { - if (GraalOptions.TraceInlining) { - TTY.println("not inlining %s because it is an abstract method", methodName(method)); - } - return false; - } - if (!method.holder().isInitialized()) { - if (GraalOptions.TraceInlining) { - TTY.println("not inlining %s because of non-initialized class", methodName(method)); - } - return false; - } - return true; - } - - private boolean checkStaticSizeConditions(RiMethod method, InvokeNode invoke) { - int maximumSize = GraalOptions.MaximumInlineSize; - if (hints != null && hints.contains(invoke)) { - maximumSize = GraalOptions.MaximumFreqInlineSize; - } - if (method.codeSize() > maximumSize) { - if (GraalOptions.TraceInlining) { - TTY.println("not inlining %s because of code size (size: %d, max size: %d)", methodName(method, invoke), method.codeSize(), GraalOptions.MaximumInlineSize); - } - return false; - } - return true; - } - - private boolean checkSizeConditions(RiMethod caller, int iterations, RiMethod method, InvokeNode invoke, RiTypeProfile profile, float adjustedRatio) { - int maximumSize = GraalOptions.MaximumTrivialSize; - int maximumCompiledSize = GraalOptions.MaximumTrivialCompSize; - double ratio = 0; - if (profile != null && profile.count > 0) { - RiMethod parent = invoke.stateAfter().method(); - if (GraalOptions.ProbabilityAnalysis) { - ratio = invoke.probability(); - } else { - ratio = profile.count / (float) parent.invocationCount(); - } - if (ratio >= GraalOptions.FreqInlineRatio) { - maximumSize = GraalOptions.MaximumFreqInlineSize; - maximumCompiledSize = GraalOptions.MaximumFreqInlineCompSize; - } else if (ratio >= 1 * (1 - adjustedRatio)) { - maximumSize = GraalOptions.MaximumInlineSize; - maximumCompiledSize = GraalOptions.MaximumInlineCompSize; - } - } - if (hints != null && hints.contains(invoke)) { - maximumSize = GraalOptions.MaximumFreqInlineSize; - maximumCompiledSize = GraalOptions.MaximumFreqInlineCompSize; - } - boolean oversize; - int compiledSize = method.compiledCodeSize(); - if (compiledSize < 0) { - oversize = (method.codeSize() > maximumSize); - } else { - oversize = (compiledSize > maximumCompiledSize); - } - if (oversize || iterations >= GraalOptions.MaximumInlineLevel || (method == compilation.method && iterations > GraalOptions.MaximumRecursiveInlineLevel)) { - if (GraalOptions.TraceInlining) { - TTY.println("not inlining %s because of size (bytecode: %d, bytecode max: %d, compiled: %d, compiled max: %d, ratio %5.3f, %s) or inlining level", - methodName(method, invoke), method.codeSize(), maximumSize, compiledSize, maximumCompiledSize, ratio, profile); - } - if (GraalOptions.Extend) { - boolean newResult = overrideInliningDecision(iterations, caller, invoke.bci, method, false); - if (GraalOptions.TraceInlining && newResult) { - TTY.println("overridden inlining decision"); - } - return newResult; - } - return false; - } - if (GraalOptions.TraceInlining) { - TTY.println("inlining %s (size: %d, max size: %d, ratio %5.3f, %s)", methodName(method, invoke), method.codeSize(), maximumSize, ratio, profile); - } - if (GraalOptions.Extend) { - boolean newResult = overrideInliningDecision(iterations, caller, invoke.bci, method, true); - if (GraalOptions.TraceInlining && !newResult) { - TTY.println("overridden inlining decision"); - } - return newResult; - } - return true; - } - - public static ThreadLocal> guideLoader = new ThreadLocal>(); - - private boolean overrideInliningDecision(int iteration, RiMethod caller, int bci, RiMethod target, boolean previousDecision) { - ServiceLoader serviceLoader = guideLoader.get(); - if (serviceLoader == null) { - serviceLoader = ServiceLoader.load(InliningGuide.class); - guideLoader.set(serviceLoader); - } - - boolean neverInline = false; - boolean alwaysInline = false; - for (InliningGuide guide : serviceLoader) { - InliningHint hint = guide.getHint(iteration, caller, bci, target); - - if (hint == InliningHint.ALWAYS) { - alwaysInline = true; - } else if (hint == InliningHint.NEVER) { - neverInline = true; - } - } - - if (neverInline && alwaysInline) { - if (GraalOptions.TraceInlining) { - TTY.println("conflicting inlining hints"); - } - } else if (neverInline) { - return false; - } else if (alwaysInline) { - return true; - } - return previousDecision; - } - - - public static ThreadLocal> intrinsicLoader = new ThreadLocal>(); - - private Graph intrinsicGraph(RiMethod parent, int bci, RiMethod target, List arguments) { - ServiceLoader serviceLoader = intrinsicLoader.get(); - if (serviceLoader == null) { - serviceLoader = ServiceLoader.load(Intrinsifier.class); - intrinsicLoader.set(serviceLoader); - } - - for (Intrinsifier intrinsifier : serviceLoader) { - Graph result = intrinsifier.intrinsicGraph(compilation.runtime, parent, bci, target, arguments); - if (result != null) { - return result; - } - } - return null; - } - - private void inlineMethod(InvokeNode invoke, RiMethod method) { - RiMethod parent = invoke.stateAfter().method(); - FrameState stateAfter = invoke.stateAfter(); - FixedNode exceptionEdge = invoke.exceptionEdge(); - if (exceptionEdge instanceof PlaceholderNode) { - exceptionEdge = ((PlaceholderNode) exceptionEdge).next(); - } - - boolean withReceiver = !invoke.isStatic(); - - int argumentCount = method.signature().argumentCount(false); - ValueNode[] parameters = new ValueNode[argumentCount + (withReceiver ? 1 : 0)]; - int slot = withReceiver ? 1 : 0; - int param = withReceiver ? 1 : 0; - for (int i = 0; i < argumentCount; i++) { - parameters[param++] = invoke.arguments().get(slot); - slot += method.signature().argumentKindAt(i).sizeInSlots(); - } - if (withReceiver) { - parameters[0] = invoke.arguments().get(0); - } - - CompilerGraph graph = null; - if (GraalOptions.Intrinsify) { - if (GraalOptions.Extend) { - graph = (CompilerGraph) intrinsicGraph(parent, invoke.bci, method, invoke.arguments()); - } - if (graph == null) { - graph = (CompilerGraph) compilation.runtime.intrinsicGraph(parent, invoke.bci, method, invoke.arguments()); - } - } - if (graph != null) { - if (GraalOptions.TraceInlining) { - TTY.println("Using intrinsic graph"); - } - } else { - graph = GraphBuilderPhase.cachedGraphs.get(method); - } - - if (graph != null) { - if (GraalOptions.TraceInlining) { - TTY.println("Reusing graph for %s", methodName(method, invoke)); - } - } else { - if (GraalOptions.TraceInlining) { - TTY.println("Building graph for %s, locals: %d, stack: %d", methodName(method, invoke), method.maxLocals(), method.maxStackSize()); - } - graph = new CompilerGraph(null); - new GraphBuilderPhase(compilation, method, true).apply(graph, true, false); - if (GraalOptions.ProbabilityAnalysis) { - new DeadCodeEliminationPhase().apply(graph, true, false); - new ComputeProbabilityPhase().apply(graph, true, false); - } - } - - invoke.clearInputs(); - - HashMap replacements = new HashMap(); - ArrayList nodes = new ArrayList(); - ArrayList frameStates = new ArrayList(); - ReturnNode returnNode = null; - UnwindNode unwindNode = null; - StartNode startNode = graph.start(); - for (Node node : graph.getNodes()) { - if (node instanceof StartNode) { - assert startNode == node; - } else if (node instanceof LocalNode) { - replacements.put(node, parameters[((LocalNode) node).index()]); - } else { - nodes.add(node); - if (node instanceof ReturnNode) { - returnNode = (ReturnNode) node; - } else if (node instanceof UnwindNode) { - unwindNode = (UnwindNode) node; - } else if (node instanceof FrameState) { - frameStates.add(node); - } - } - } - - if (GraalOptions.TraceInlining) { - TTY.println("inlining %s: %d frame states, %d nodes", methodName(method), frameStates.size(), nodes.size()); - } - - assert invoke.successors().first() != null : invoke; - assert invoke.predecessor() != null; - FixedWithNextNode pred; - if (withReceiver) { - pred = new FixedGuardNode(new IsNonNullNode(parameters[0], compilation.graph), compilation.graph); - } else { - pred = new PlaceholderNode(compilation.graph); - } - invoke.replaceAtPredecessors(pred); - replacements.put(startNode, pred); - - Map duplicates = compilation.graph.addDuplicate(nodes, replacements); - - FrameState stateBefore = null; - double invokeProbability = invoke.probability(); - for (Node node : duplicates.values()) { - if (GraalOptions.ProbabilityAnalysis) { - if (node instanceof FixedNode) { - FixedNode fixed = (FixedNode) node; - fixed.setProbability(fixed.probability() * invokeProbability); - } - } - if (node instanceof InvokeNode && ((InvokeNode) node).canInline()) { - newInvokes.add((InvokeNode) node); - } else if (node instanceof FrameState) { - FrameState frameState = (FrameState) node; - if (frameState.bci == FrameState.BEFORE_BCI) { - if (stateBefore == null) { - stateBefore = stateAfter.duplicateModified(invoke.bci, false, invoke.kind, parameters); - } - frameState.replaceAndDelete(stateBefore); - } else if (frameState.bci == FrameState.AFTER_BCI) { - frameState.replaceAndDelete(stateAfter); - } - } - } - - int monitorIndexDelta = stateAfter.locksSize(); - if (monitorIndexDelta > 0) { - for (Map.Entry entry : duplicates.entrySet()) { - if (entry.getValue() instanceof MonitorAddressNode) { - MonitorAddressNode address = (MonitorAddressNode) entry.getValue(); - address.setMonitorIndex(address.monitorIndex() + monitorIndexDelta); - } - } - } - - if (pred instanceof PlaceholderNode) { - FixedNode next = ((PlaceholderNode) pred).next(); - ((PlaceholderNode) pred).setNext(null); - pred.replaceAndDelete(next); - } - - if (returnNode != null) { - for (Node usage : invoke.usages().snapshot()) { - if (returnNode.result() instanceof LocalNode) { - usage.replaceFirstInput(invoke, replacements.get(returnNode.result())); - } else { - usage.replaceFirstInput(invoke, duplicates.get(returnNode.result())); - } - } - Node returnDuplicate = duplicates.get(returnNode); - returnDuplicate.clearInputs(); - Node n = invoke.next(); - invoke.setNext(null); - returnDuplicate.replaceAndDelete(n); - } - - if (exceptionEdge != null) { - if (unwindNode != null) { - assert unwindNode.predecessor() != null; - assert exceptionEdge.successors().explicitCount() == 1; - ExceptionObjectNode obj = (ExceptionObjectNode) exceptionEdge; - - UnwindNode unwindDuplicate = (UnwindNode) duplicates.get(unwindNode); - for (Node usage : obj.usages().snapshot()) { - usage.replaceFirstInput(obj, unwindDuplicate.exception()); - } - unwindDuplicate.clearInputs(); - Node n = obj.next(); - obj.setNext(null); - unwindDuplicate.replaceAndDelete(n); - } - } else { - if (unwindNode != null) { - UnwindNode unwindDuplicate = (UnwindNode) duplicates.get(unwindNode); - unwindDuplicate.replaceAndDelete(new DeoptimizeNode(DeoptAction.InvalidateRecompile, compilation.graph)); - } - } - - // adjust all frame states that were copied - if (frameStates.size() > 0) { - FrameState outerFrameState = stateAfter.duplicateModified(invoke.bci, stateAfter.rethrowException(), invoke.kind); - for (Node node : frameStates) { - FrameState frameState = (FrameState) duplicates.get(node); - if (!frameState.isDeleted()) { - frameState.setOuterFrameState(outerFrameState); - } - } - } - - if (GraalOptions.TraceInlining) { - ir.printGraph("After inlining " + CiUtil.format("%H.%n(%p):%r", method, false), compilation.graph); - } - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/LoopPhase.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/LoopPhase.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,197 +0,0 @@ -/* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.compiler.phases; - -import java.util.*; - -import com.oracle.max.graal.compiler.*; -import com.oracle.max.graal.compiler.observer.*; -import com.oracle.max.graal.compiler.util.*; -import com.oracle.max.graal.compiler.util.LoopUtil.Loop; -import com.oracle.max.graal.graph.*; -import com.oracle.max.graal.graph.collections.*; -import com.oracle.max.graal.nodes.*; -import com.oracle.max.graal.nodes.calc.*; -import com.oracle.max.graal.nodes.loop.*; -import com.sun.cri.ci.*; - - -public class LoopPhase extends Phase { - - @Override - protected void run(Graph graph) { - List loops = LoopUtil.computeLoops(graph); - - if (GraalOptions.LoopPeeling || GraalOptions.LoopInversion) { - for (Loop loop : loops) { - boolean hasBadExit = false; - for (Node exit : loop.exits()) { - if (!(exit instanceof StateSplit) || ((StateSplit) exit).stateAfter() == null) { - // TODO (gd) can not do loop peeling if an exit has no state. see LoopUtil.findNearestMergableExitPoint - hasBadExit = true; - break; - } - } - if (hasBadExit) { - continue; - } - boolean canInvert = false; - if (GraalOptions.LoopInversion && loop.loopBegin().next() instanceof IfNode) { - IfNode ifNode = (IfNode) loop.loopBegin().next(); - if (loop.exits().isMarked(ifNode.trueSuccessor()) || loop.exits().isMarked(ifNode.falseSuccessor())) { - canInvert = true; - } - } - if (canInvert) { - LoopUtil.inverseLoop(loop, (IfNode) loop.loopBegin().next()); - } else if (GraalOptions.LoopPeeling) { - GraalCompilation compilation = GraalCompilation.compilation(); - if (compilation.compiler.isObserved()) { - Map debug = new HashMap(); - debug.put("loopExits", loop.exits()); - debug.put("inOrBefore", loop.inOrBefore()); - debug.put("inOrAfter", loop.inOrAfter()); - debug.put("nodes", loop.nodes()); - compilation.compiler.fireCompilationEvent(new CompilationEvent(compilation, "Loop #" + loop.loopBegin().id(), graph, true, false, debug)); - } - LoopUtil.peelLoop(loop); - } - } - } - - for (Loop loop : loops) { - findInductionVariables(loop); - } - } - - private void findInductionVariables(Loop loop) { - LoopBeginNode loopBegin = loop.loopBegin(); - NodeBitMap loopNodes = loop.nodes(); - List phis = new ArrayList(loopBegin.phis()); - int backIndex = loopBegin.phiPredecessorIndex(loopBegin.loopEnd()); - int initIndex = loopBegin.phiPredecessorIndex(loopBegin.forwardEdge()); - for (PhiNode phi : phis) { - ValueNode init = phi.valueAt(initIndex); - ValueNode backEdge = phi.valueAt(backIndex); - if (loopNodes.isNew(init) || loopNodes.isNew(backEdge)) { - continue; - } - if (loopNodes.isMarked(backEdge)) { - BinaryNode binary; - if (backEdge instanceof IntegerAddNode || backEdge instanceof IntegerSubNode) { - binary = (BinaryNode) backEdge; - } else { - continue; - } - ValueNode stride; - if (binary.x() == phi) { - stride = binary.y(); - } else if (binary.y() == phi) { - stride = binary.x(); - } else { - continue; - } - if (loopNodes.isNotNewNotMarked(stride)) { - Graph graph = loopBegin.graph(); - if (backEdge instanceof IntegerSubNode) { - stride = new NegateNode(stride, graph); - } - CiKind kind = phi.kind; - LoopCounterNode counter = loopBegin.loopCounter(kind); - BasicInductionVariableNode biv1 = null; - BasicInductionVariableNode biv2 = null; - if (phi.usages().size() > 1) { - biv1 = new BasicInductionVariableNode(kind, init, stride, counter, graph); - phi.replaceAndDelete(biv1); - } else { - phi.replaceFirstInput(binary, null); - phi.delete(); - } - if (backEdge.usages().size() > 0) { - biv2 = new BasicInductionVariableNode(kind, IntegerArithmeticNode.add(init, stride), stride, counter, graph); - backEdge.replaceAndDelete(biv2); - } else { - backEdge.delete(); - } - if (biv1 != null) { - findDerivedInductionVariable(biv1, kind, loopNodes); - } - if (biv2 != null) { - findDerivedInductionVariable(biv2, kind, loopNodes); - } - } - } - } - } - private void findDerivedInductionVariable(BasicInductionVariableNode biv, CiKind kind, NodeBitMap loopNodes) { - for (Node usage : biv.usages().snapshot()) { - ValueNode scale = scale(usage, biv, loopNodes); - ValueNode offset = null; - Node node = null; - if (scale == null) { - if (usage instanceof IntegerAddNode) { - IntegerAddNode add = (IntegerAddNode) usage; - if (add.x() == biv || (scale = scale(add.x(), biv, loopNodes)) != null) { - offset = add.y(); - } else if (add.y() == biv || (scale = scale(add.y(), biv, loopNodes)) != null) { - offset = add.x(); - } - if (offset != null) { - if (loopNodes.isNotNewNotMarked(offset)) { - node = add; - } else { - offset = null; - } - } - } - } else { - node = usage; - } - if (scale != null || offset != null) { - if (scale == null) { - scale = ConstantNode.forInt(1, biv.graph()); - } else if (offset == null) { - offset = ConstantNode.forInt(0, biv.graph()); - } - DerivedInductionVariableNode div = new DerivedInductionVariableNode(kind, offset, scale, biv, biv.graph()); - node.replaceAndDelete(div); - } - } - } - - private ValueNode scale(Node n, BasicInductionVariableNode biv, NodeBitMap loopNodes) { - if (n instanceof IntegerMulNode) { - IntegerMulNode mul = (IntegerMulNode) n; - ValueNode scale = null; - if (mul.x() == biv) { - scale = mul.y(); - } else if (mul.y() == biv) { - scale = mul.x(); - } - if (scale != null && loopNodes.isNotNewNotMarked(scale)) { - return scale; - } - } - return null; - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/LoweringPhase.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/LoweringPhase.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,113 +0,0 @@ -/* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.compiler.phases; - -import java.util.*; - -import com.oracle.max.graal.compiler.schedule.*; -import com.oracle.max.graal.graph.*; -import com.oracle.max.graal.graph.collections.*; -import com.oracle.max.graal.nodes.*; -import com.oracle.max.graal.nodes.spi.*; -import com.sun.cri.ci.*; -import com.sun.cri.ri.*; - -public class LoweringPhase extends Phase { - - - - private final RiRuntime runtime; - - public LoweringPhase(RiRuntime runtime) { - this.runtime = runtime; - } - - @Override - protected void run(final Graph graph) { - final IdentifyBlocksPhase s = new IdentifyBlocksPhase(false); - s.apply(graph); - - NodeBitMap processed = graph.createNodeBitMap(); - List blocks = s.getBlocks(); - for (final Block b : blocks) { - process(b, processed); - } - - processed.negate(); - final CiLoweringTool loweringTool = new CiLoweringTool() { - @Override - public Node getGuardAnchor() { - throw new UnsupportedOperationException(); - } - @Override - public RiRuntime getRuntime() { - return runtime; - } - @Override - public Node createGuard(Node condition) { - throw new UnsupportedOperationException(); - } - }; - for (Node node : processed) { - LoweringOp op = node.lookup(LoweringOp.class); - if (op != null) { - op.lower(node, loweringTool); - } - } - } - - private void process(final Block b, NodeBitMap processed) { - - final Node anchor = b.javaBlock().createAnchor(); - final CiLoweringTool loweringTool = new CiLoweringTool() { - - @Override - public Node getGuardAnchor() { - return anchor; - } - - @Override - public RiRuntime getRuntime() { - return runtime; - } - - @Override - public Node createGuard(Node condition) { - AnchorNode anchor = (AnchorNode) getGuardAnchor(); - GuardNode newGuard = new GuardNode((BooleanNode) condition, anchor.graph()); - newGuard.setAnchor(anchor); - return newGuard; - } - }; - - - // Lower the instructions of this block. - for (final Node n : b.getInstructions()) { - processed.mark(n); - LoweringOp op = n.lookup(LoweringOp.class); - if (op != null) { - op.lower(n, loweringTool); - } - } - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/MemoryPhase.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/MemoryPhase.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,330 +0,0 @@ -/* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.compiler.phases; - -import java.util.*; -import java.util.Map.Entry; - -import com.oracle.max.graal.compiler.*; -import com.oracle.max.graal.compiler.debug.*; -import com.oracle.max.graal.compiler.schedule.*; -import com.oracle.max.graal.graph.*; -import com.oracle.max.graal.graph.collections.*; -import com.oracle.max.graal.nodes.*; -import com.oracle.max.graal.nodes.PhiNode.PhiType; -import com.oracle.max.graal.nodes.extended.*; -import com.sun.cri.ci.*; - -public class MemoryPhase extends Phase { - - public static class MemoryMap { - - private final Block block; - private HashMap locationForWrite; - private HashMap locationForRead; - private Node mergeForWrite; - private Node mergeForRead; - private int mergeOperationCount; - private Node loopCheckPoint; - private MemoryMap loopEntryMap; - - public MemoryMap(Block b, MemoryMap memoryMap) { - this(b); - if (b.firstNode() instanceof LoopBeginNode) { - loopCheckPoint = new WriteMemoryCheckpointNode(b.firstNode().graph()); - mergeForWrite = loopCheckPoint; - mergeForRead = loopCheckPoint; - this.loopEntryMap = memoryMap; - } else { - memoryMap.locationForWrite.putAll(memoryMap.locationForWrite); - memoryMap.locationForRead.putAll(memoryMap.locationForRead); - mergeForWrite = memoryMap.mergeForWrite; - mergeForRead = memoryMap.mergeForRead; - } - } - - public MemoryMap(Block b) { - if (GraalOptions.TraceMemoryMaps) { - TTY.println("Creating new memory map for block B" + b.blockID()); - } - - block = b; - locationForWrite = new HashMap(); - locationForRead = new HashMap(); - StartNode startNode = b.firstNode().graph().start(); - if (b.firstNode() == startNode) { - WriteMemoryCheckpointNode checkpoint = new WriteMemoryCheckpointNode(startNode.graph()); - FixedNode next = (FixedNode) startNode.next(); - startNode.setNext(checkpoint); - checkpoint.setNext(next); - mergeForWrite = checkpoint; - mergeForRead = checkpoint; - } - } - - public Node getLoopCheckPoint() { - return loopCheckPoint; - } - - public MemoryMap getLoopEntryMap() { - return loopEntryMap; - } - - public void resetMergeOperationCount() { - mergeOperationCount = 0; - } - - public void mergeWith(MemoryMap memoryMap, Block block) { - if (GraalOptions.TraceMemoryMaps) { - TTY.println("Merging with memory map of block B" + memoryMap.block.blockID()); - } - mergeForWrite = mergeNodes(mergeForWrite, memoryMap.mergeForWrite, locationForWrite, memoryMap.locationForWrite, block); - mergeForRead = mergeNodes(mergeForRead, memoryMap.mergeForRead, locationForRead, memoryMap.locationForRead, block); - mergeOperationCount++; - } - - private Node mergeNodes(Node mergeLeft, Node mergeRight, HashMap locationLeft, HashMap locationRight, Block block) { - if (GraalOptions.TraceMemoryMaps) { - TTY.println("Merging main merge nodes: " + mergeLeft.id() + " and " + mergeRight.id()); - } - - for (Entry e : locationRight.entrySet()) { - if (!locationLeft.containsKey(e.getKey())) { - // Only available in right map => create correct node for left map. - if (GraalOptions.TraceMemoryMaps) { - TTY.println("Only right map " + e.getKey()); - } - Node leftNode = mergeLeft; - if (leftNode instanceof PhiNode && ((PhiNode) leftNode).merge() == block.firstNode()) { - leftNode = leftNode.copyWithEdges(); - } - locationLeft.put(e.getKey(), leftNode); - } - } - - for (Entry e : locationLeft.entrySet()) { - if (locationRight.containsKey(e.getKey())) { - // Available in both maps. - if (GraalOptions.TraceMemoryMaps) { - TTY.println("Merging entries for location " + e.getKey()); - } - locationLeft.put(e.getKey(), mergeNodes(e.getValue(), locationRight.get(e.getKey()), block)); - } else { - // Only available in left map. - if (GraalOptions.TraceMemoryMaps) { - TTY.println("Only available in left map " + e.getKey()); - } - locationLeft.put(e.getKey(), mergeNodes(e.getValue(), mergeRight, block)); - } - } - - return mergeNodes(mergeLeft, mergeRight, block); - } - - private Node mergeNodes(Node original, Node newValue, Block block) { - if (original == newValue) { - // Nothing to merge. - if (GraalOptions.TraceMemoryMaps) { - TTY.println("Nothing to merge both nodes are " + original.id()); - } - return original; - } - MergeNode m = (MergeNode) block.firstNode(); - if (original instanceof PhiNode && ((PhiNode) original).merge() == m) { - PhiNode phi = (PhiNode) original; - phi.addInput((ValueNode) newValue); - if (GraalOptions.TraceMemoryMaps) { - TTY.println("Add new input to phi " + original.id()); - } - assert phi.valueCount() <= phi.merge().endCount(); - return original; - } else { - PhiNode phi = new PhiNode(CiKind.Illegal, m, PhiType.Memory, m.graph()); - for (int i = 0; i < mergeOperationCount + 1; ++i) { - phi.addInput((ValueNode) original); - } - phi.addInput((ValueNode) newValue); - if (GraalOptions.TraceMemoryMaps) { - TTY.println("Creating new phi " + phi.id()); - } - assert phi.valueCount() <= phi.merge().endCount() + ((phi.merge() instanceof LoopBeginNode) ? 1 : 0) : phi.merge() + "/" + phi.valueCount() + "/" + phi.merge().endCount() + "/" + mergeOperationCount; - return phi; - } - } - - public void createWriteMemoryMerge(AbstractMemoryCheckpointNode memMerge) { - if (GraalOptions.TraceMemoryMaps) { - TTY.println("Creating write memory checkpoint at node " + memMerge.id()); - } - - // Merge in all writes. - for (Entry writeEntry : locationForWrite.entrySet()) { - memMerge.mergedNodes().add(writeEntry.getValue()); - } - locationForWrite.clear(); - mergeForWrite = memMerge; - } - - public void createReadWriteMemoryCheckpoint(AbstractMemoryCheckpointNode memMerge) { - if (GraalOptions.TraceMemoryMaps) { - TTY.println("Creating readwrite memory checkpoint at node " + memMerge.id()); - } - createWriteMemoryMerge(memMerge); - locationForRead.clear(); - mergeForRead = memMerge; - } - - public void registerWrite(WriteNode node) { - Object location = node.location().locationIdentity(); - if (GraalOptions.TraceMemoryMaps) { - TTY.println("Register write to " + location + " at node " + node.id()); - } - - // Create dependency on previous write to same location. - node.addDependency(getLocationForWrite(node)); - - locationForWrite.put(location, node); - locationForRead.put(location, node); - } - - public Node getLocationForWrite(WriteNode node) { - Object location = node.location().locationIdentity(); - if (locationForWrite.containsKey(location)) { - Node prevWrite = locationForWrite.get(location); - return prevWrite; - } else { - return mergeForWrite; - } - } - - public void registerRead(ReadNode node) { - if (GraalOptions.TraceMemoryMaps) { - TTY.println("Register read to node " + node.id()); - } - - // Create dependency on previous node that creates the memory state for this location. - node.addDependency(getLocationForRead(node)); - } - - public Node getLocationForRead(ReadNode node) { - Object location = node.location().locationIdentity(); - if (locationForRead.containsKey(location)) { - return locationForRead.get(location); - } - return mergeForRead; - } - - public void replaceCheckPoint(Node loopCheckPoint) { - for (Node n : loopCheckPoint.usages().snapshot()) { - replaceCheckPoint(loopCheckPoint, n); - } - } - - private void replaceCheckPoint(Node loopCheckPoint, Node n) { - if (n instanceof ReadNode) { - n.replaceFirstInput(loopCheckPoint, getLocationForRead((ReadNode) n)); - } else if (n instanceof WriteNode) { - n.replaceFirstInput(loopCheckPoint, getLocationForWrite((WriteNode) n)); - } else if (n instanceof WriteMemoryCheckpointNode) { - n.replaceFirstInput(loopCheckPoint, mergeForWrite); - } else { - n.replaceFirstInput(loopCheckPoint, mergeForRead); - } - } - } - - @Override - protected void run(final Graph graph) { - final IdentifyBlocksPhase s = new IdentifyBlocksPhase(false); - s.apply(graph); - - List blocks = s.getBlocks(); - MemoryMap[] memoryMaps = new MemoryMap[blocks.size()]; - for (final Block b : blocks) { - process(b, memoryMaps, s.getNodeToBlock()); - } - } - - private void process(final Block b, MemoryMap[] memoryMaps, NodeMap nodeMap) { - // Visit every block at most once. - if (memoryMaps[b.blockID()] != null) { - return; - } - - // Process predecessors before this block. - for (Block pred : b.getPredecessors()) { - process(pred, memoryMaps, nodeMap); - } - - // Create initial memory map for the block. - MemoryMap map = null; - if (b.getPredecessors().size() == 0) { - map = new MemoryMap(b); - } else { - map = new MemoryMap(b, memoryMaps[b.getPredecessors().get(0).blockID()]); - for (int i = 1; i < b.getPredecessors().size(); ++i) { - assert b.firstNode() instanceof MergeNode : b.firstNode(); - Block block = b.getPredecessors().get(i); - map.mergeWith(memoryMaps[block.blockID()], b); - } - } - - // Create the floating memory checkpoint instructions. - for (final Node n : b.getInstructions()) { - if (n instanceof ReadNode) { - ReadNode readNode = (ReadNode) n; - FixedNode next = readNode.next(); - readNode.setNext(null); - readNode.replaceAtPredecessors(next); - map.registerRead(readNode); - } else if (n instanceof WriteNode) { - WriteNode writeNode = (WriteNode) n; - WriteMemoryCheckpointNode checkpoint = new WriteMemoryCheckpointNode(writeNode.graph()); - checkpoint.setStateAfter(writeNode.stateAfter()); - writeNode.setStateAfter(null); - FixedNode next = writeNode.next(); - writeNode.setNext(null); - checkpoint.setNext(next); - writeNode.replaceAtPredecessors(checkpoint); - map.registerWrite(writeNode); - map.createWriteMemoryMerge(checkpoint); - } else if (n instanceof AbstractMemoryCheckpointNode) { - map.createReadWriteMemoryCheckpoint((AbstractMemoryCheckpointNode) n); - } - } - - memoryMaps[b.blockID()] = map; - if (b.lastNode() instanceof LoopEndNode) { - LoopEndNode end = (LoopEndNode) b.lastNode(); - LoopBeginNode begin = end.loopBegin(); - Block beginBlock = nodeMap.get(begin); - MemoryMap memoryMap = memoryMaps[beginBlock.blockID()]; - assert memoryMap != null : beginBlock.name(); - assert memoryMap.getLoopEntryMap() != null; - memoryMap.getLoopEntryMap().resetMergeOperationCount(); - memoryMap.getLoopEntryMap().mergeWith(map, beginBlock); - Node loopCheckPoint = memoryMap.getLoopCheckPoint(); - memoryMap.getLoopEntryMap().replaceCheckPoint(loopCheckPoint); - } - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/Phase.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/Phase.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,117 +0,0 @@ -/* - * Copyright (c) 2011, 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.compiler.phases; - -import com.oracle.max.graal.compiler.*; -import com.oracle.max.graal.compiler.observer.*; -import com.oracle.max.graal.compiler.schedule.*; -import com.oracle.max.graal.graph.*; - -public abstract class Phase { - - private final String name; - private static final ThreadLocal currentPhase = new ThreadLocal(); - private final boolean shouldVerify; - - protected Phase() { - this.name = this.getClass().getSimpleName(); - this.shouldVerify = GraalOptions.Verify; - } - - protected Phase(String name) { - this(name, true); - } - - protected Phase(String name, boolean shouldVerify) { - this.name = name; - this.shouldVerify = shouldVerify; - } - - protected String getDetailedName() { - return getName(); - } - - public final void apply(Graph graph) { - apply(graph, true, true); - } - - public final void apply(Graph graph, boolean plotOnError, boolean plot) { - assert graph != null && (!shouldVerify || graph.verify()); - - int startDeletedNodeCount = graph.getDeletedNodeCount(); - int startNodeCount = graph.getNodeCount(); - Phase oldCurrentPhase = null; - if (GraalOptions.Time) { - oldCurrentPhase = currentPhase.get(); - currentPhase.set(this); - if (oldCurrentPhase != null) { - GraalTimers.get(oldCurrentPhase.getName()).stop(); - } - GraalTimers.get(getName()).start(); - } - //System.out.println("Starting Phase " + getName()); - try { - run(graph); - } catch (AssertionError t) { - GraalCompilation compilation = GraalCompilation.compilation(); - if (compilation.compiler.isObserved() && plotOnError) { - compilation.compiler.fireCompilationEvent(new CompilationEvent(compilation, "AssertionError in " + getDetailedName(), graph, true, false, true)); - } - throw t; - } catch (RuntimeException t) { - GraalCompilation compilation = GraalCompilation.compilation(); - if (compilation.compiler.isObserved() && plotOnError) { - compilation.compiler.fireCompilationEvent(new CompilationEvent(compilation, "RuntimeException in " + getDetailedName(), graph, true, false, true)); - } - throw t; - } - if (GraalOptions.Time) { - GraalTimers.get(getName()).stop(); - if (oldCurrentPhase != null) { - GraalTimers.get(oldCurrentPhase.getName()).start(); - } - currentPhase.set(oldCurrentPhase); - } - if (GraalOptions.Meter) { - int deletedNodeCount = graph.getDeletedNodeCount() - startDeletedNodeCount; - int createdNodeCount = graph.getNodeCount() - startNodeCount + deletedNodeCount; - GraalMetrics.get(getName().concat(".executed")).increment(); - GraalMetrics.get(getName().concat(".deletedNodes")).increment(deletedNodeCount); - GraalMetrics.get(getName().concat(".createdNodes")).increment(createdNodeCount); - } - GraalCompilation compilation = GraalCompilation.compilation(); - if (compilation.compiler.isObserved() && this.getClass() != IdentifyBlocksPhase.class && (plot || GraalOptions.PlotVerbose)) { - compilation.compiler.fireCompilationEvent(new CompilationEvent(compilation, "After " + getDetailedName(), graph, true, false)); - } - - assert !shouldVerify || graph.verify(); - - // (Item|Graph|Phase|Value) - } - - public final String getName() { - return name; - } - - protected abstract void run(Graph graph); -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/ReadEliminationPhase.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/ReadEliminationPhase.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,49 +0,0 @@ -/* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.compiler.phases; - -import com.oracle.max.graal.compiler.*; -import com.oracle.max.graal.compiler.debug.*; -import com.oracle.max.graal.graph.*; -import com.oracle.max.graal.nodes.extended.*; - -public class ReadEliminationPhase extends Phase { - - @Override - protected void run(Graph graph) { - for (ReadNode n : graph.getNodes(ReadNode.class)) { - if (n.dependencies().size() > 0) { - Node memoryInput = n.dependencies().get(0); - if (memoryInput instanceof WriteNode) { - WriteNode other = (WriteNode) memoryInput; - if (other.object() == n.object() && other.location() == n.location()) { - if (GraalOptions.TraceReadElimination) { - TTY.println("Eliminated memory read " + n + "and replaced with node " + other.value()); - } - n.replaceAndDelete(other.value()); - } - } - } - } - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/schedule/Block.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/schedule/Block.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,276 +0,0 @@ -/* - * Copyright (c) 2011, 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.compiler.schedule; - -import java.util.*; - -import com.oracle.max.graal.graph.*; -import com.oracle.max.graal.nodes.*; -import com.oracle.max.graal.nodes.java.*; - - -public class Block { - - private int blockID; - private final List successors = new ArrayList(); - private final List predecessors = new ArrayList(); - private final List dominated = new ArrayList(); - private List instructions = new ArrayList(); - private Block dominator; - private Block javaBlock; - private AnchorNode anchor; - private EndNode end; - private int loopDepth = 0; - private int loopIndex = -1; - private double probability; - - private Node firstNode; - private Node lastNode; - - public Node firstNode() { - return firstNode; - } - - public void setFirstNode(Node node) { - this.firstNode = node; - this.anchor = null; - } - - public EndNode end() { - return end; - } - - public void setEnd(EndNode end) { - this.end = end; - } - - public Block javaBlock() { - return javaBlock; - } - - public void setJavaBlock(Block javaBlock) { - this.javaBlock = javaBlock; - } - - public Node lastNode() { - return lastNode; - } - - public int loopDepth() { - return loopDepth; - } - - public void setLoopDepth(int i) { - loopDepth = i; - } - - public int loopIndex() { - return loopIndex; - } - - public void setLoopIndex(int i) { - loopIndex = i; - } - - public double probability() { - return probability; - } - - - public void setProbability(double probability) { - if (probability > this.probability) { - this.probability = probability; - } - } - - public AnchorNode createAnchor() { - if (anchor == null) { - if (firstNode instanceof AnchorNode) { - this.anchor = (AnchorNode) firstNode; - } else if (firstNode == firstNode.graph().start()) { - StartNode start = (StartNode) firstNode; - if (start.next() instanceof AnchorNode) { - this.anchor = (AnchorNode) start.next(); - } else { - AnchorNode a = new AnchorNode(firstNode.graph()); - FixedNode oldStart = (FixedNode) firstNode.graph().start().next(); - firstNode.graph().start().setNext(a); - a.setNext(oldStart); - this.anchor = a; - } - } else if (firstNode instanceof MergeNode || firstNode instanceof ExceptionObjectNode) { - FixedWithNextNode fixedNode = (FixedWithNextNode) firstNode; - if (fixedNode.next() instanceof AnchorNode) { - this.anchor = (AnchorNode) fixedNode.next(); - } else { - AnchorNode a = new AnchorNode(firstNode.graph()); - FixedNode next = fixedNode.next(); - fixedNode.setNext(a); - a.setNext(next); - this.anchor = a; - } - } else { - assert !(firstNode instanceof AnchorNode); - AnchorNode a = new AnchorNode(firstNode.graph()); - assert firstNode.predecessor() != null : firstNode; - Node pred = firstNode.predecessor(); - pred.replaceFirstSuccessor(firstNode, a); - a.setNext((FixedNode) firstNode); - this.anchor = a; - } - } - return anchor; - } - - public void setLastNode(Node node) { - this.lastNode = node; - } - - public List getSuccessors() { - return Collections.unmodifiableList(successors); - } - - public void setDominator(Block dominator) { - assert this.dominator == null; - assert dominator != null; - this.dominator = dominator; - dominator.dominated.add(this); - } - - public List getDominated() { - return Collections.unmodifiableList(dominated); - } - - public List getInstructions() { - return instructions; - } - - public List getPredecessors() { - return Collections.unmodifiableList(predecessors); - } - - public Block(int blockID) { - this.blockID = blockID; - } - - public void addSuccessor(Block other) { - successors.add(other); - other.predecessors.add(this); - } - - public int blockID() { - return blockID; - } - - /** - * Iterate over this block, its exception handlers, and its successors, in that order. - * - * @param closure the closure to apply to each block - */ - public void iteratePreOrder(BlockClosure closure) { - // XXX: identity hash map might be too slow, consider a boolean array or a mark field - iterate(new IdentityHashMap(), closure); - } - - private void iterate(IdentityHashMap mark, BlockClosure closure) { - if (!mark.containsKey(this)) { - mark.put(this, this); - closure.apply(this); - - iterateReverse(mark, closure, this.successors); - } - } - - private void iterateReverse(IdentityHashMap mark, BlockClosure closure, List list) { - for (int i = list.size() - 1; i >= 0; i--) { - list.get(i).iterate(mark, closure); - } - } - - @Override - public String toString() { - return "B" + blockID; - } - - public boolean isLoopHeader() { - return firstNode instanceof LoopBeginNode; - } - - public boolean isLoopEnd() { - return lastNode instanceof LoopEndNode; - } - - public Block dominator() { - return dominator; - } - - public void setInstructions(List instructions) { - this.instructions = instructions; - } - - public static void iteratePostOrder(List blocks, BlockClosure closure) { - ArrayList startBlocks = new ArrayList(); - for (Block block : blocks) { - if (block.getPredecessors().size() == 0) { - startBlocks.add(block); - } - } - iteratePostOrder(blocks, closure, startBlocks.toArray(new Block[startBlocks.size()])); - } - - public static void iteratePostOrder(List blocks, BlockClosure closure, Block... startBlocks) { - BitMap visited = new BitMap(blocks.size()); - LinkedList workList = new LinkedList(); - for (Block block : startBlocks) { - workList.add(block); - visited.set(block.blockID()); - } - - while (!workList.isEmpty()) { - Block b = workList.remove(); - - closure.apply(b); - - for (Block succ : b.getSuccessors()) { - if (!visited.get(succ.blockID())) { - boolean delay = false; - for (Block pred : succ.getPredecessors()) { - if (!visited.get(pred.blockID()) && !(pred.lastNode instanceof LoopEndNode)) { - delay = true; - break; - } - } - - if (!delay) { - visited.set(succ.blockID()); - workList.add(succ); - } - } - } - } - } - - public String name() { - return "B" + blockID; - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/schedule/BlockClosure.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/schedule/BlockClosure.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,30 +0,0 @@ -/* - * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.compiler.schedule; - -/** - * The {@code BlockClosure} interface represents a closure for iterating over blocks. - */ -public interface BlockClosure { - void apply(Block block); -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/schedule/BlockList.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/schedule/BlockList.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,150 +0,0 @@ -/* - * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.compiler.schedule; - -import java.util.*; - -import com.oracle.max.graal.nodes.*; - -/** - * The {@code BlockList} class implements a specialized list data structure for representing - * the predecessor and successor lists of basic blocks. - */ -public class BlockList implements Iterable { - - private MergeNode[] array; - private int cursor; - - BlockList(int sizeHint) { - if (sizeHint > 0) { - array = new MergeNode[sizeHint]; - } else { - array = new MergeNode[2]; - } - } - - public void remove(int index) { - if (index < 0 || index >= cursor) { - throw new IndexOutOfBoundsException(); - } - for (int i = index; i < cursor; i++) { - array[i] = array[i + 1]; - } - cursor--; - } - - public void remove(MergeNode block) { - int j = 0; - for (int i = 0; i < cursor; i++) { - if (i != j) { - array[j] = array[i]; - } - if (array[i] != block) { - j++; - } - } - cursor = j; - } - - public void exchange(int index1, int index2) { - if (index1 < 0 || index1 >= cursor) { - throw new IndexOutOfBoundsException(); - } - if (index2 < 0 || index2 >= cursor) { - throw new IndexOutOfBoundsException(); - } - MergeNode t = array[index2]; - array[index2] = array[index1]; - array[index1] = t; - } - - public void insert(int index, MergeNode block) { - if (index < 0 || index >= cursor) { - throw new IndexOutOfBoundsException(); - } - growOne(); - for (int i = cursor; i > index; i--) { - array[i] = array[i - 1]; - } - array[cursor++] = block; - } - - public void append(MergeNode block) { - growOne(); - array[cursor++] = block; - } - - public MergeNode get(int index) { - if (index < 0 || index >= cursor) { - throw new IndexOutOfBoundsException(); - } - return array[index]; - } - - public void replace(MergeNode oldBlock, MergeNode newBlock) { - for (int i = 0; i < cursor; i++) { - if (array[i] == oldBlock) { - array[i] = newBlock; - } - } - } - - public boolean checkForSameBlock() { - if (cursor == 0) { - return true; - } - MergeNode b = array[0]; - for (int i = 1; i < cursor; i++) { - if (array[i] != b) { - return false; - } - } - return true; - } - - public Iterator iterator() { - return new Iter(); - } - - private void growOne() { - if (cursor == array.length) { - array = Arrays.copyOf(array, array.length * 3); - } - } - - private class Iter implements Iterator { - private int pos; - - public boolean hasNext() { - return pos < cursor; - } - - public MergeNode next() { - return array[pos++]; - } - - public void remove() { - BlockList.this.remove(pos); - } - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/schedule/IdentifyBlocksPhase.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/schedule/IdentifyBlocksPhase.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,845 +0,0 @@ -/* - * Copyright (c) 2011, 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.compiler.schedule; - -import java.util.*; - -import com.oracle.max.graal.compiler.*; -import com.oracle.max.graal.compiler.debug.*; -import com.oracle.max.graal.compiler.phases.*; -import com.oracle.max.graal.graph.*; -import com.oracle.max.graal.graph.NodeClass.NodeClassIterator; -import com.oracle.max.graal.graph.NodeClass.Position; -import com.oracle.max.graal.graph.collections.*; -import com.oracle.max.graal.nodes.*; -import com.oracle.max.graal.nodes.extended.*; -import com.oracle.max.graal.nodes.loop.*; -import com.oracle.max.graal.nodes.virtual.*; - - -public class IdentifyBlocksPhase extends Phase { - private static final double LIVE_RANGE_COST_FACTOR = 0.05; - private static final double MATERIALIZATION_COST_FACTOR = 1.0 - LIVE_RANGE_COST_FACTOR; - - private final List blocks = new ArrayList(); - private NodeMap nodeToBlock; - private NodeMap earliestCache; - private Graph graph; - private boolean scheduleAllNodes; - private boolean splitMaterialization; - private int loopCount; - - public IdentifyBlocksPhase(boolean scheduleAllNodes) { - this(scheduleAllNodes, GraalOptions.SplitMaterialization && filter()); - } - - public static boolean filter() { - return true; //GraalCompilation.compilation().method.name().contains("mergeOrClone"); - } - - public IdentifyBlocksPhase(boolean scheduleAllNodes, boolean splitMaterialization) { - super(scheduleAllNodes ? "FullSchedule" : "PartSchedule", false); - this.scheduleAllNodes = scheduleAllNodes; - this.splitMaterialization = splitMaterialization; - } - - - @Override - protected void run(Graph graph) { - this.graph = graph; - nodeToBlock = graph.createNodeMap(); - earliestCache = graph.createNodeMap(); - identifyBlocks(); - } - - public List getBlocks() { - return Collections.unmodifiableList(blocks); - } - - public NodeMap getNodeToBlock() { - return nodeToBlock; - } - - private Block createBlock() { - Block b = new Block(blocks.size()); - blocks.add(b); - return b; - } - - public int loopCount() { - return loopCount; - } - - private Block assignBlockNew(Node n, Block b) { - if (b == null) { - b = createBlock(); - } - - assert nodeToBlock.get(n) == null; - nodeToBlock.set(n, b); - - if (n instanceof MergeNode) { - for (Node usage : n.usages()) { - - if (usage instanceof PhiNode) { - nodeToBlock.set(usage, b); - } - - if (usage instanceof LoopCounterNode) { - nodeToBlock.set(usage, b); - } - - } - } - if (n instanceof EndNode) { - assert b.end() == null || n == b.end(); - b.setEnd((EndNode) n); - } - if (b.lastNode() == null) { - b.setFirstNode(n); - b.setLastNode(n); - b.getInstructions().add(n); - } else { - b.getInstructions().add(0, n); - b.setFirstNode(n); - } - - return b; - } - - public static boolean isFixed(Node n) { - return n != null && ((n instanceof FixedNode) || n == n.graph().start()) && !(n instanceof AccessNode && n.predecessor() == null); - } - - public static boolean isBlockEnd(Node n) { - return trueSuccessorCount(n) > 1 || n instanceof ReturnNode || n instanceof UnwindNode || n instanceof DeoptimizeNode; - } - - private void print() { - Block dominatorRoot = nodeToBlock.get(graph.start()); - System.out.println("Root = " + dominatorRoot); - System.out.println("nodeToBlock :"); - System.out.println(nodeToBlock); - System.out.println("Blocks :"); - for (Block b : blocks) { - System.out.println(b + " [S:" + b.getSuccessors() + ", P:" + b.getPredecessors() + ", D:" + b.getDominated()); - System.out.println(" f " + b.firstNode()); - for (Node n : b.getInstructions()) { - System.out.println(" - " + n); - } - System.out.println(" l " + b.lastNode()); - } - } - - private void identifyBlocks() { - - // Identify blocks. - for (Node n : graph.getNodes()) { - if (n instanceof EndNode || n instanceof ReturnNode || n instanceof UnwindNode || n instanceof LoopEndNode || n instanceof DeoptimizeNode) { - Block block = null; - Node currentNode = n; - while (nodeToBlock.get(currentNode) == null) { - if (block != null && (currentNode instanceof ControlSplitNode || trueSuccessorCount(currentNode) > 1)) { - // We are at a split node => start a new block. - block = null; - } - block = assignBlockNew(currentNode, block); - if (currentNode instanceof FixedNode) { - block.setProbability(((FixedNode) currentNode).probability()); - } - if (currentNode.predecessor() == null) { - // Either dead code or at a merge node => stop iteration. - break; - } - Node prev = currentNode; - currentNode = currentNode.predecessor(); - assert !(currentNode instanceof AccessNode && ((AccessNode) currentNode).next() != prev) : currentNode; - assert !currentNode.isDeleted() : prev + " " + currentNode; - } - } - } - - // Connect blocks. - for (Block block : blocks) { - Node n = block.firstNode(); - if (n instanceof MergeNode) { - MergeNode m = (MergeNode) n; - for (Node pred : m.cfgPredecessors()) { - Block predBlock = nodeToBlock.get(pred); - predBlock.addSuccessor(block); - } - } else { - if (n.predecessor() != null) { - if (isFixed(n.predecessor())) { - Block predBlock = nodeToBlock.get(n.predecessor()); - predBlock.addSuccessor(block); - } - } - } - } - - computeDominators(); - - - if (scheduleAllNodes) { - computeLoopInformation(); // Will make the graph cyclic. - assignBlockToNodes(); - sortNodesWithinBlocks(); - } else { - computeJavaBlocks(); - } - } - - private void computeLoopInformation() { - - // Add successors of loop end nodes. Makes the graph cyclic. - for (Block block : blocks) { - Node n = block.lastNode(); - if (n instanceof LoopEndNode) { - LoopEndNode loopEnd = (LoopEndNode) n; - assert loopEnd.loopBegin() != null; - Block loopBeginBlock = nodeToBlock.get(loopEnd.loopBegin()); - block.addSuccessor(loopBeginBlock); - BitMap map = new BitMap(blocks.size()); - markBlocks(block, loopBeginBlock, map, loopCount++, block.loopDepth()); - assert loopBeginBlock.loopDepth() == block.loopDepth() && loopBeginBlock.loopIndex() == block.loopIndex(); - } - } - -// for (Block block : blocks) { -// TTY.println("Block B" + block.blockID() + " loopIndex=" + block.loopIndex() + ", loopDepth=" + block.loopDepth()); -// } - } - - private void markBlocks(Block block, Block endBlock, BitMap map, int loopIndex, int initialDepth) { - if (map.get(block.blockID())) { - return; - } - - map.set(block.blockID()); - if (block.loopDepth() <= initialDepth) { - assert block.loopDepth() == initialDepth; - block.setLoopIndex(loopIndex); - } - block.setLoopDepth(block.loopDepth() + 1); - - if (block == endBlock) { - return; - } - - for (Block pred : block.getPredecessors()) { - markBlocks(pred, endBlock, map, loopIndex, initialDepth); - } - - if (block.isLoopHeader()) { - markBlocks(nodeToBlock.get(((LoopBeginNode) block.firstNode()).loopEnd()), endBlock, map, loopIndex, initialDepth); - } - } - - private void computeJavaBlocks() { - - for (Block b : blocks) { - computeJavaBlock(b); - } - } - - private Block computeJavaBlock(Block b) { - if (b.javaBlock() == null) { - if (b.getPredecessors().size() == 0) { - b.setJavaBlock(b); - } else if (b.getPredecessors().size() == 1) { - Block pred = b.getPredecessors().get(0); - if (pred.getSuccessors().size() > 1) { - b.setJavaBlock(b); - } else { - b.setJavaBlock(computeJavaBlock(pred)); - } - } else { - Block dominatorBlock = b.getPredecessors().get(0); - for (int i = 1; i < b.getPredecessors().size(); ++i) { - dominatorBlock = getCommonDominator(dominatorBlock, b.getPredecessors().get(i)); - } - BitMap blockMap = new BitMap(blocks.size()); - markPredecessors(b, dominatorBlock, blockMap); - - Block result = dominatorBlock; - L1: for (Block curBlock : blocks) { - if (curBlock != b && blockMap.get(curBlock.blockID())) { - for (Block succ : curBlock.getSuccessors()) { - if (!blockMap.get(succ.blockID())) { - result = b; - break L1; - } - } - } - } - b.setJavaBlock(result); - } - } - return b.javaBlock(); - } - - private void markPredecessors(Block b, Block stopBlock, BitMap blockMap) { - if (blockMap.get(b.blockID())) { - return; - } - blockMap.set(b.blockID()); - if (b != stopBlock) { - for (Block pred : b.getPredecessors()) { - markPredecessors(pred, stopBlock, blockMap); - } - } - } - - private void assignBlockToNodes() { - for (Node n : graph.getNodes()) { - assignBlockToNode(n); - } - } - - public void assignBlockToNode(Node n) { - if (n == null) { - return; - } - - assert !n.isDeleted(); - - Block prevBlock = nodeToBlock.get(n); - if (prevBlock != null) { - return; - } - //TTY.println("Earliest for " + n + " : " + earliest); - // if in CFG, schedule at the latest position possible in the outermost loop possible - // if floating, use rematerialization to place the node, it tries to compute the value only when it will be used, - // in the block with the smallest probability (outside of loops), while minimizing live ranges - if (!splitMaterialization || noRematerialization(n) || n.predecessor() != null || nonNullSuccessorCount(n) > 0) { - Block latestBlock = latestBlock(n); - //TTY.println("Latest for " + n + " : " + latestBlock); - Block block; - if (latestBlock == null) { - block = earliestBlock(n); - } else if (GraalOptions.ScheduleOutOfLoops && !(n instanceof VirtualObjectFieldNode) && !(n instanceof VirtualObjectNode)) { - block = scheduleOutOfLoops(n, latestBlock, earliestBlock(n)); - } else { - block = latestBlock; - } - nodeToBlock.set(n, block); - block.getInstructions().add(n); - } else { - GraalTimers timer = GraalTimers.get("earliest"); - timer.start(); - Block earliest = earliestBlock(n); - timer.stop(); - Map> usages = computeUsages(n, earliest); - if (usages.isEmpty()) { - nodeToBlock.set(n, earliest); - earliest.getInstructions().add(n); - } else { - maybeMaterialize(n, earliest, usages, false); - } - } - } - - private int nonNullSuccessorCount(Node n) { - int suxCount = 0; - for (Node sux : n.successors()) { - if (sux != null) { - suxCount++; - } - } - return suxCount; - } - - - private void maybeMaterialize(Node node, Block block, Map> usages, boolean materializedInDominator) { - Set blockUsages = usages.get(block); - if (blockUsages == null || blockUsages.isEmpty()) { - return; - } - boolean forced = false; - if (!materializedInDominator) { - for (Usage usage : blockUsages) { - if (usage.block == block) { - forced = true; - break; - } - } - } - //TODO (gd) if materializedInDominator, compare cost of materialization to cost of current live range instead - if (forced || materializationCost(block, blockUsages) < materializationCostAtChildren(block, usages)) { - Node n; - if (nodeToBlock.get(node) == null) { - n = node; - } else { - n = node.clone(node.graph()); - for (NodeClassIterator iter = node.inputs().iterator(); iter.hasNext();) { - Position pos = iter.nextPosition(); - n.getNodeClass().set(n, pos, node.getNodeClass().get(node, pos)); - } - for (Usage usage : blockUsages) { - patch(usage, node, n); - } - //TTY.println("> Rematerialized " + node + " (new node id = " + n.id() + ") in " + block); - GraalMetrics.Rematerializations++; - nodeToBlock.grow(n); - } - materializedInDominator = true; - nodeToBlock.set(n, block); - block.getInstructions().add(n); - } - if (!materializedInDominator || GraalOptions.Rematerialize) { - for (Block child : block.getDominated()) { - maybeMaterialize(node, child, usages, materializedInDominator); - } - } - } - - private double materializationCostAtChildren(Block block, Map> usages) { - double cost = 0.0; - for (Block child : block.getDominated()) { - Set blockUsages = usages.get(child); - if (blockUsages != null && !blockUsages.isEmpty()) { // XXX should never be empty if not null - cost += materializationCost(child, blockUsages); - } - } - return cost; - } - - private double materializationCost(Block block, Set usages) { - //TODO node cost - return /*LIVE_RANGE_COST_FACTOR * liveRange(block, usages) + MATERIALIZATION_COST_FACTOR **/ block.probability() * 1.0; - } - - - private Block latestBlock(Node n) { - Block block = null; - for (Node succ : n.successors()) { - if (succ == null) { - continue; - } - assignBlockToNode(succ); - block = getCommonDominator(block, nodeToBlock.get(succ)); - } - ensureScheduledUsages(n); - CommonDominatorBlockClosure cdbc = new CommonDominatorBlockClosure(block); - for (Node usage : n.usages()) { - blocksForUsage(n, usage, cdbc); - } - return cdbc.block; - } - - private class CommonDominatorBlockClosure implements BlockClosure { - public Block block; - public CommonDominatorBlockClosure(Block block) { - this.block = block; - } - @Override - public void apply(Block block) { - this.block = getCommonDominator(this.block, block); - } - } - - private Block earliestBlock(Node n) { - Block earliest = nodeToBlock.get(n); - if (earliest != null) { - return earliest; - } - earliest = earliestCache.get(n); - if (earliest != null) { - return earliest; - } - BitMap bits = new BitMap(blocks.size()); - ArrayList before = new ArrayList(); - if (n.predecessor() != null) { - before.add(n.predecessor()); - } - for (Node input : n.inputs()) { - before.add(input); - } - for (Node pred : before) { - if (pred == null) { - continue; - } - Block b = earliestBlock(pred); - if (!bits.get(b.blockID())) { - earliest = b; - do { - bits.set(b.blockID()); - b = b.dominator(); - } while(b != null && !bits.get(b.blockID())); - } - } - if (earliest == null) { - Block start = nodeToBlock.get(graph.start()); - assert start != null; - return start; - } - earliestCache.set(n, earliest); - return earliest; - } - - - private Block scheduleOutOfLoops(Node n, Block latestBlock, Block earliest) { - assert latestBlock != null : "no latest : " + n; - Block cur = latestBlock; - Block prevDepth = latestBlock; - while (cur.loopDepth() != 0 && cur != earliest && cur.dominator() != null && cur.dominator().loopDepth() <= cur.loopDepth()) { - Block dom = cur.dominator(); - if (dom.loopDepth() < prevDepth.loopDepth()) { - prevDepth = dom; - } - cur = dom; - } - return prevDepth; - } - - private void blocksForUsage(Node node, Node usage, BlockClosure closure) { - if (usage instanceof PhiNode) { - PhiNode phi = (PhiNode) usage; - MergeNode merge = phi.merge(); - Block mergeBlock = nodeToBlock.get(merge); - assert mergeBlock != null : "no block for merge " + merge.id(); - for (int i = 0; i < phi.valueCount(); ++i) { - if (phi.valueAt(i) == node) { - if (mergeBlock.getPredecessors().size() <= i) { - TTY.println(merge.toString()); - TTY.println(phi.toString()); - TTY.println(merge.cfgPredecessors().toString()); - TTY.println(phi.inputs().toString()); - TTY.println("value count: " + phi.valueCount()); - } - closure.apply(mergeBlock.getPredecessors().get(i)); - } - } - } else if (usage instanceof FrameState && ((FrameState) usage).block() != null) { - MergeNode merge = ((FrameState) usage).block(); - Block block = null; - for (Node pred : merge.cfgPredecessors()) { - block = getCommonDominator(block, nodeToBlock.get(pred)); - } - closure.apply(block); - } else if (usage instanceof LinearInductionVariableNode) { - LinearInductionVariableNode liv = (LinearInductionVariableNode) usage; - if (liv.isLinearInductionVariableInput(node)) { - LoopBeginNode loopBegin = liv.loopBegin(); - Block mergeBlock = nodeToBlock.get(loopBegin); - closure.apply(mergeBlock.dominator()); - } - } else { - assignBlockToNode(usage); - closure.apply(nodeToBlock.get(usage)); - } - } - - private void patch(Usage usage, Node original, Node patch) { - if (usage.node instanceof PhiNode) { - PhiNode phi = (PhiNode) usage.node; - Node pred; - Block phiBlock = nodeToBlock.get(phi); - if (phiBlock.isLoopHeader()) { - LoopBeginNode loopBegin = (LoopBeginNode) phiBlock.firstNode(); - if (usage.block == phiBlock.dominator()) { - pred = loopBegin.forwardEdge(); - } else { - assert usage.block == nodeToBlock.get(loopBegin.loopEnd()); - pred = loopBegin.loopEnd(); - } - } else { - pred = usage.block.end(); - } - int index = phi.merge().phiPredecessorIndex(pred); - phi.setValueAt(index, (ValueNode) patch); - } else { - usage.node.replaceFirstInput(original, patch); - } - } - - private void ensureScheduledUsages(Node node) { - // assign block to all usages to ensure that any splitting/rematerialization is done on them - for (Node usage : node.usages().snapshot()) { - assignBlockToNode(usage); - } - // now true usages are ready - } - - private Map> computeUsages(Node node, final Block from) { //TODO use a List instead of a Set here ? - final Map> blockUsages = new HashMap>(); - ensureScheduledUsages(node); - for (final Node usage : node.dataUsages()) { - blocksForUsage(node, usage, new BlockClosure() { - @Override - public void apply(Block block) { - addUsageToTree(usage, block, from, blockUsages); - } - }); - } - /*TTY.println("Usages for " + node + " from " + from); - for (Entry> entry : blockUsages.entrySet()) { - TTY.println(" - " + entry.getKey() + " :"); - for (Usage usage : entry.getValue()) { - TTY.println(" + " + usage.node + " in " + usage.block); - } - }*/ - return blockUsages; - } - - private void addUsageToTree(Node usage, Block usageBlock, Block from, Map> blockUsages) { - Block current = usageBlock; - while (current != null) { - Set usages = blockUsages.get(current); - if (usages == null) { - usages = new HashSet(); - blockUsages.put(current, usages); - } - usages.add(new Usage(usageBlock, usage)); - if (current == from) { - current = null; - } else { - current = current.dominator(); - } - } - } - - private static class Usage { - public final Block block; - public final Node node; - public Usage(Block block, Node node) { - this.block = block; - this.node = node; - } - } - - private boolean noRematerialization(Node n) { - return n instanceof LocalNode || n instanceof LocationNode || n instanceof ConstantNode || n instanceof StateSplit || n instanceof FrameState || n instanceof VirtualObjectNode || - n instanceof VirtualObjectFieldNode; - } - - private double liveRange(Block from, Set usages) { - BitMap subTree = new BitMap(blocks.size()); - markSubTree(from, subTree); - double range = 0.0; - for (Usage usage : usages) { - range += markRangeUp(usage.block, subTree); - } - return range; - } - - private void markSubTree(Block from, BitMap subTree) { - subTree.set(from.blockID()); - for (Block b : from.getDominated()) { - markSubTree(b, subTree); - } - } - - private double markRangeUp(Block from, BitMap subTree) { - int blockID = from.blockID(); - if (!subTree.get(blockID)) { - return 0.0; - } - subTree.clear(blockID); - double range = from.probability() * (from.getInstructions().size() + 2); - for (Block pred : from.getPredecessors()) { - range += markRangeUp(pred, subTree); - } - return range; - } - - private Block getCommonDominator(Block a, Block b) { - if (a == null) { - return b; - } - if (b == null) { - return a; - } - return commonDominator(a, b); - } - - private void sortNodesWithinBlocks() { - NodeBitMap map = graph.createNodeBitMap(); - for (Block b : blocks) { - sortNodesWithinBlocks(b, map); - } - } - - private void sortNodesWithinBlocks(Block b, NodeBitMap map) { - List instructions = b.getInstructions(); - List sortedInstructions = new ArrayList(instructions.size() + 2); - - assert !map.isMarked(b.firstNode()) && nodeToBlock.get(b.firstNode()) == b; - assert !map.isMarked(b.lastNode()) && nodeToBlock.get(b.lastNode()) == b; - - for (Node i : instructions) { - addToSorting(b, i, sortedInstructions, map); - } - - // Make sure that last node gets really last (i.e. when a frame state successor hangs off it). - Node lastSorted = sortedInstructions.get(sortedInstructions.size() - 1); - if (lastSorted != b.lastNode()) { - int idx = sortedInstructions.indexOf(b.lastNode()); - boolean canNotMove = false; - for (int i = idx + 1; i < sortedInstructions.size(); i++) { - if (sortedInstructions.get(i).inputs().contains(b.lastNode())) { - canNotMove = true; - break; - } - } - if (canNotMove) { - assert !(b.lastNode() instanceof ControlSplitNode); - //b.setLastNode(lastSorted); - } else { - sortedInstructions.remove(b.lastNode()); - sortedInstructions.add(b.lastNode()); - } - } - b.setInstructions(sortedInstructions); -// TTY.println(); -// TTY.println("B" + b.blockID()); -// for (Node n : sortedInstructions) { -// TTY.println("n=" + n); -// } - } - - private void addToSorting(Block b, Node i, List sortedInstructions, NodeBitMap map) { - if (i == null || map.isMarked(i) || nodeToBlock.get(i) != b || i instanceof PhiNode || i instanceof LocalNode || i instanceof LoopCounterNode) { - return; - } - - if (i instanceof WriteNode) { - // TODO(tw): Make sure every ReadNode that is connected to the same memory state is executed before every write node. - // WriteNode wn = (WriteNode) i; - } - - FrameState state = null; - WriteNode writeNode = null; - for (Node input : i.inputs()) { - if (input instanceof WriteNode && !map.isMarked(input) && nodeToBlock.get(input) == b) { - writeNode = (WriteNode) input; - } else if (input instanceof FrameState) { - state = (FrameState) input; - } else { - addToSorting(b, input, sortedInstructions, map); - } - } - - if (i.predecessor() != null) { - addToSorting(b, i.predecessor(), sortedInstructions, map); - } - - map.mark(i); - - addToSorting(b, state, sortedInstructions, map); - assert writeNode == null || !map.isMarked(writeNode); - addToSorting(b, writeNode, sortedInstructions, map); - - // Now predecessors and inputs are scheduled => we can add this node. - sortedInstructions.add(i); - } - - private void computeDominators() { - Block dominatorRoot = nodeToBlock.get(graph.start()); - assert dominatorRoot.getPredecessors().size() == 0; - BitMap visited = new BitMap(blocks.size()); - visited.set(dominatorRoot.blockID()); - LinkedList workList = new LinkedList(); - for (Block block : blocks) { - if (block.getPredecessors().size() == 0) { - workList.add(block); - } - } - - int cnt = 0; - while (!workList.isEmpty()) { - if (cnt++ > blocks.size() * 20) { - throw new RuntimeException("(ls) endless loop in computeDominators?"); - } - Block b = workList.remove(); - - List predecessors = b.getPredecessors(); - if (predecessors.size() == 1) { - b.setDominator(predecessors.get(0)); - } else if (predecessors.size() > 0) { - boolean delay = false; - for (Block pred : predecessors) { - if (pred != dominatorRoot && pred.dominator() == null) { - delay = true; - break; - } - } - - if (delay) { - workList.add(b); - continue; - } - - Block dominator = null; - for (Block pred : predecessors) { - if (dominator == null) { - dominator = pred; - } else { - dominator = commonDominator(dominator, pred); - } - } - b.setDominator(dominator); - } - - for (Block succ : b.getSuccessors()) { - if (!visited.get(succ.blockID())) { - visited.set(succ.blockID()); - workList.add(succ); - } - } - } - } - - public Block commonDominator(Block a, Block b) { - BitMap bitMap = new BitMap(blocks.size()); - Block cur = a; - while (cur != null) { - bitMap.set(cur.blockID()); - cur = cur.dominator(); - } - - cur = b; - while (cur != null) { - if (bitMap.get(cur.blockID())) { - return cur; - } - cur = cur.dominator(); - } - - throw new IllegalStateException("no common dominator between " + a + " and " + b); - } - - public static int trueSuccessorCount(Node n) { - if (n == null) { - return 0; - } - int i = 0; - for (Node s : n.successors()) { - if (isFixed(s)) { - i++; - } - } - return i; - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/Backend.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/Backend.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,65 +0,0 @@ -/* - * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.compiler.target; - -import java.lang.reflect.*; - -import com.oracle.max.asm.*; -import com.oracle.max.graal.compiler.*; -import com.oracle.max.graal.compiler.gen.*; -import com.oracle.max.graal.compiler.globalstub.*; -import com.oracle.max.graal.compiler.lir.*; -import com.sun.cri.ci.*; -import com.sun.cri.ri.*; -import com.sun.cri.xir.*; - -/** - * The {@code Backend} class represents a compiler backend for Graal. - * - * @author Ben L. Titzer - */ -public abstract class Backend { - public final GraalCompiler compiler; - - protected Backend(GraalCompiler compiler) { - this.compiler = compiler; - } - - public static Backend create(CiArchitecture arch, GraalCompiler compiler) { - String className = arch.getClass().getName().replace("com.oracle.max.asm", "com.oracle.max.graal.compiler") + "Backend"; - try { - Class c = Class.forName(className); - Constructor cons = c.getDeclaredConstructor(GraalCompiler.class); - return (Backend) cons.newInstance(compiler); - } catch (Exception e) { - throw new Error("Could not instantiate " + className, e); - } - } - - public abstract FrameMap newFrameMap(RiMethod method, int numberOfLocks); - public abstract LIRGenerator newLIRGenerator(GraalCompilation compilation); - public abstract LIRAssembler newLIRAssembler(GraalCompilation compilation); - public abstract AbstractAssembler newAssembler(RiRegisterConfig registerConfig); - public abstract GlobalStubEmitter newGlobalStubEmitter(); - public abstract CiXirAssembler newXirAssembler(); -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64Backend.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64Backend.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,85 +0,0 @@ -/* - * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.compiler.target.amd64; - -import static com.oracle.max.graal.compiler.GraalCompilation.*; - -import com.oracle.max.asm.*; -import com.oracle.max.asm.target.amd64.*; -import com.oracle.max.graal.compiler.*; -import com.oracle.max.graal.compiler.gen.*; -import com.oracle.max.graal.compiler.globalstub.*; -import com.oracle.max.graal.compiler.lir.*; -import com.oracle.max.graal.compiler.target.*; -import com.sun.cri.ri.*; -import com.sun.cri.xir.*; - -/** - * The {@code X86Backend} class represents the backend for the AMD64 architecture. - * - * @author Ben L. Titzer - */ -public class AMD64Backend extends Backend { - - public AMD64Backend(GraalCompiler compiler) { - super(compiler); - } - /** - * Creates a new LIRGenerator for x86. - * @param compilation the compilation for which to create the LIR generator - * @return an appropriate LIR generator instance - */ - @Override - public LIRGenerator newLIRGenerator(GraalCompilation compilation) { - return new AMD64LIRGenerator(compilation); - } - - /** - * Creates a new LIRAssembler for x86. - * @param compilation the compilation for which to create the LIR assembler - * @return an appropriate LIR assembler instance - */ - @Override - public LIRAssembler newLIRAssembler(GraalCompilation compilation) { - return new AMD64LIRAssembler(compilation); - } - - @Override - public FrameMap newFrameMap(RiMethod method, int numberOfLocks) { - return new FrameMap(compilation(), method, numberOfLocks); - } - @Override - public AbstractAssembler newAssembler(RiRegisterConfig registerConfig) { - return new AMD64MacroAssembler(compiler.target, registerConfig); - } - - @Override - public CiXirAssembler newXirAssembler() { - return new AMD64XirAssembler(); - } - - @Override - public GlobalStubEmitter newGlobalStubEmitter() { - return new AMD64GlobalStubEmitter(compiler); - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64GlobalStubEmitter.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64GlobalStubEmitter.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,412 +0,0 @@ -/* - * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.compiler.target.amd64; - -import static com.sun.cri.ci.CiCallingConvention.Type.*; - -import java.util.*; - -import com.oracle.max.asm.*; -import com.oracle.max.asm.target.amd64.*; -import com.oracle.max.asm.target.amd64.AMD64Assembler.ConditionFlag; -import com.oracle.max.graal.compiler.*; -import com.oracle.max.graal.compiler.asm.*; -import com.oracle.max.graal.compiler.globalstub.*; -import com.sun.cri.ci.*; -import com.sun.cri.ci.CiRegister.RegisterFlag; -import com.sun.cri.ri.*; -import com.sun.cri.xir.*; -import com.sun.cri.xir.CiXirAssembler.XirConstant; -import com.sun.cri.xir.CiXirAssembler.XirConstantOperand; -import com.sun.cri.xir.CiXirAssembler.XirOperand; -import com.sun.cri.xir.CiXirAssembler.XirParameter; -import com.sun.cri.xir.CiXirAssembler.XirRegister; -import com.sun.cri.xir.CiXirAssembler.XirTemp; - -public class AMD64GlobalStubEmitter implements GlobalStubEmitter { - - public static final int ARGUMENT_SIZE = 8; - - private static final long FloatSignFlip = 0x8000000080000000L; - private static final long DoubleSignFlip = 0x8000000000000000L; - private static final CiRegister convertArgument = AMD64.xmm0; - private static final CiRegister convertResult = AMD64.rax; - - private TargetMethodAssembler tasm; - private AMD64MacroAssembler asm; - private final CiTarget target; - private int argsSize; - private int[] argOffsets; - private int resultOffset; - private int saveSize; - private int registerRestoreEpilogueOffset; - - private RiRuntime runtime; - private GraalCompiler compiler; - private CiRegister[] registersSaved; - - private boolean savedAllRegisters; - - public AMD64GlobalStubEmitter(GraalCompiler compiler) { - this.compiler = compiler; - this.target = compiler.target; - this.runtime = compiler.runtime; - } - - private void reset(CiKind resultKind, CiKind[] argTypes) { - asm = new AMD64MacroAssembler(compiler.target, compiler.globalStubRegisterConfig); - tasm = new TargetMethodAssembler(asm); - saveSize = 0; - argsSize = 0; - argOffsets = new int[argTypes.length]; - resultOffset = 0; - registerRestoreEpilogueOffset = -1; - registersSaved = null; - - for (int i = 0; i < argTypes.length; i++) { - argOffsets[i] = argsSize; - argsSize += ARGUMENT_SIZE; - } - - if (resultKind != CiKind.Void) { - if (argsSize == 0) { - argsSize = ARGUMENT_SIZE; - } - resultOffset = 0; - } - } - - public GlobalStub emit(CiRuntimeCall runtimeCall, RiRuntime runtime) { - reset(runtimeCall.resultKind, runtimeCall.arguments); - emitStandardForward(null, runtimeCall); - String name = "stub-" + runtimeCall; - CiTargetMethod targetMethod = tasm.finishTargetMethod(name, runtime, registerRestoreEpilogueOffset, true); - Object stubObject = runtime.registerCompilerStub(targetMethod, name); - return new GlobalStub(null, runtimeCall.resultKind, stubObject, argsSize, argOffsets, resultOffset); - } - - public GlobalStub emit(GlobalStub.Id stub, RiRuntime runtime) { - reset(stub.resultKind, stub.arguments); - - switch (stub) { - case f2i: - emitF2I(); - break; - case f2l: - emitF2L(); - break; - case d2i: - emitD2I(); - break; - case d2l: - emitD2L(); - break; - } - - String name = "stub-" + stub; - CiTargetMethod targetMethod = tasm.finishTargetMethod(name, runtime, registerRestoreEpilogueOffset, true); - Object stubObject = runtime.registerCompilerStub(targetMethod, name); - return new GlobalStub(stub, stub.resultKind, stubObject, argsSize, argOffsets, resultOffset); - } - - private CiValue allocateParameterOperand(XirParameter param, int parameterIndex) { - return new CiAddress(param.kind, AMD64.RSP, argumentIndexToStackOffset(parameterIndex)); - } - - private CiValue allocateResultOperand(XirOperand result) { - return new CiAddress(result.kind, AMD64.RSP, argumentIndexToStackOffset(0)); - } - - private CiValue allocateOperand(XirTemp temp, ArrayList allocatableRegisters) { - if (temp instanceof XirRegister) { - XirRegister fixed = (XirRegister) temp; - return fixed.register; - } - - return newRegister(temp.kind, allocatableRegisters); - } - - private CiValue newRegister(CiKind kind, ArrayList allocatableRegisters) { - assert kind != CiKind.Float && kind != CiKind.Double; - assert allocatableRegisters.size() > 0; - return allocatableRegisters.remove(allocatableRegisters.size() - 1).asValue(kind); - } - - public GlobalStub emit(XirTemplate template, RiRuntime runtime) { - GraalCompilation compilation = new GraalCompilation(compiler, null, -1, null); - try { - return emit(template, compilation); - } finally { - compilation.close(); - } - } - - public GlobalStub emit(XirTemplate template, GraalCompilation compilation) { - reset(template.resultOperand.kind, getArgumentKinds(template)); - compilation.initFrameMap(0); - compilation.frameMap().setFrameSize(frameSize()); - AMD64LIRAssembler assembler = new AMD64LIRAssembler(compilation); - asm = assembler.masm; - tasm = assembler.tasm; - - ArrayList allocatableRegisters = new ArrayList(Arrays.asList(compiler.globalStubRegisterConfig.getCategorizedAllocatableRegisters().get(RegisterFlag.CPU))); - for (XirTemp t : template.temps) { - if (t instanceof XirRegister) { - final XirRegister fixed = (XirRegister) t; - if (fixed.register.isRegister()) { - allocatableRegisters.remove(fixed.register.asRegister()); - } - } - } - - completeSavePrologue(); - - CiValue[] operands = new CiValue[template.variableCount]; - - XirOperand resultOperand = template.resultOperand; - - if (template.allocateResultOperand) { - CiValue outputOperand = CiValue.IllegalValue; - // This snippet has a result that must be separately allocated - // Otherwise it is assumed that the result is part of the inputs - if (resultOperand.kind != CiKind.Void && resultOperand.kind != CiKind.Illegal) { - outputOperand = allocateResultOperand(resultOperand); - assert operands[resultOperand.index] == null; - } - operands[resultOperand.index] = outputOperand; - } - - for (XirParameter param : template.parameters) { - assert !(param instanceof XirConstantOperand) : "constant parameters not supported for stubs"; - CiValue op = allocateParameterOperand(param, param.parameterIndex); - assert operands[param.index] == null; - - // Is the value destroyed? - if (template.isParameterDestroyed(param.parameterIndex)) { - CiValue newOp = newRegister(op.kind, allocatableRegisters); - assembler.moveOp(op, newOp, op.kind, null, false); - operands[param.index] = newOp; - } else { - operands[param.index] = op; - } - } - - for (XirConstant c : template.constants) { - assert operands[c.index] == null; - operands[c.index] = c.value; - } - - for (XirTemp t : template.temps) { - CiValue op = allocateOperand(t, allocatableRegisters); - assert operands[t.index] == null; - operands[t.index] = op; - } - - for (CiValue operand : operands) { - assert operand != null; - } - - Label[] labels = new Label[template.labels.length]; - for (int i = 0; i < labels.length; i++) { - labels[i] = new Label(); - } - - assert template.marks.length == 0 : "marks not supported in global stubs"; - assembler.emitXirInstructions(null, template.fastPath, labels, operands, null); - epilogue(); - CiTargetMethod targetMethod = tasm.finishTargetMethod(template.name, runtime, registerRestoreEpilogueOffset, true); - Object stubObject = runtime.registerCompilerStub(targetMethod, template.name); - return new GlobalStub(null, template.resultOperand.kind, stubObject, argsSize, argOffsets, resultOffset); - } - - private CiKind[] getArgumentKinds(XirTemplate template) { - CiXirAssembler.XirParameter[] params = template.parameters; - CiKind[] result = new CiKind[params.length]; - for (int i = 0; i < params.length; i++) { - result[i] = params[i].kind; - } - return result; - } - - private void convertPrologue() { - partialSavePrologue(convertArgument, convertResult); - loadArgument(0, convertArgument); - } - - private void convertEpilogue() { - storeArgument(0, convertResult); - epilogue(); - } - - private void emitD2L() { - emitCOMISSD(true, false); - } - - private void emitD2I() { - emitCOMISSD(true, true); - } - - private void emitF2L() { - emitCOMISSD(false, false); - } - - private void emitF2I() { - emitCOMISSD(false, true); - } - - private void emitCOMISSD(boolean isDouble, boolean isInt) { - convertPrologue(); - if (isDouble) { - asm.ucomisd(convertArgument, tasm.recordDataReferenceInCode(CiConstant.DOUBLE_0)); - } else { - asm.ucomiss(convertArgument, tasm.recordDataReferenceInCode(CiConstant.FLOAT_0)); - } - Label nan = new Label(); - Label ret = new Label(); - asm.jccb(ConditionFlag.parity, nan); - asm.jccb(ConditionFlag.below, ret); - - // input is > 0 -> return maxInt - // result register already contains 0x80000000, so subtracting 1 gives 0x7fffffff - asm.decrementl(convertResult, 1); - asm.jmpb(ret); - - // input is NaN -> return 0 - asm.bind(nan); - asm.xorptr(convertResult, convertResult); - - asm.bind(ret); - convertEpilogue(); - } - - private void emitStandardForward(GlobalStub.Id stub, CiRuntimeCall call) { - if (stub != null) { - assert stub.resultKind == call.resultKind; - assert stub.arguments.length == call.arguments.length; - for (int i = 0; i < stub.arguments.length; i++) { - assert stub.arguments[i] == call.arguments[i]; - } - } - - completeSavePrologue(); - forwardRuntimeCall(call); - epilogue(); - } - - private int argumentIndexToStackOffset(int index) { - // <-- lower addresses - // | stub frame | caller frame | - // | locals,savearea,retaddr | args ..... | - return frameSize() + (index + 1) * ARGUMENT_SIZE; - } - - private void loadArgument(int index, CiRegister register) { - asm.movq(register, new CiAddress(CiKind.Word, AMD64.RSP, argumentIndexToStackOffset(index))); - } - - private void storeArgument(int index, CiRegister register) { - asm.movq(new CiAddress(CiKind.Word, AMD64.RSP, argumentIndexToStackOffset(index)), register); - } - - private void partialSavePrologue(CiRegister... registersToSave) { - this.registersSaved = registersToSave; - this.saveSize = registersToSave.length * target.wordSize; - - // align to code size - int entryCodeOffset = runtime.codeOffset(); - if (entryCodeOffset != 0) { - asm.nop(entryCodeOffset); - } - asm.subq(AMD64.rsp, frameSize()); - - int index = 0; - for (CiRegister r : registersToSave) { - asm.movq(new CiAddress(CiKind.Word, AMD64.RSP, index * target.arch.wordSize), r); - index++; - } - - tasm.setFrameSize(frameSize()); - this.savedAllRegisters = false; - } - - private void completeSavePrologue() { - CiCalleeSaveLayout csa = compiler.globalStubRegisterConfig.getCalleeSaveLayout(); - this.saveSize = csa.size; - int entryCodeOffset = runtime.codeOffset(); - if (entryCodeOffset != 0) { - // align to code size - asm.nop(entryCodeOffset); - } - asm.subq(AMD64.rsp, frameSize()); - tasm.setFrameSize(frameSize()); - int frameToCSA = 0; - asm.save(csa, frameToCSA); - this.savedAllRegisters = true; - } - - private void epilogue() { - assert registerRestoreEpilogueOffset == -1; - registerRestoreEpilogueOffset = asm.codeBuffer.position(); - - if (savedAllRegisters) { - CiCalleeSaveLayout csa = compiler.globalStubRegisterConfig.getCalleeSaveLayout(); - int frameToCSA = 0; - asm.restore(csa, frameToCSA); - } else { - // saved only select registers - for (int index = 0; index < registersSaved.length; index++) { - CiRegister r = registersSaved[index]; - asm.movq(r, new CiAddress(CiKind.Word, AMD64.RSP, index * target.wordSize)); - } - registersSaved = null; - } - - // Restore rsp - asm.addq(AMD64.rsp, frameSize()); - asm.ret(0); - } - - private int frameSize() { - return target.alignFrameSize(saveSize); - } - - private void forwardRuntimeCall(CiRuntimeCall call) { - // Load arguments - CiCallingConvention cc = compiler.globalStubRegisterConfig.getCallingConvention(RuntimeCall, call.arguments, target, false); - for (int i = 0; i < cc.locations.length; ++i) { - CiValue location = cc.locations[i]; - loadArgument(i, location.asRegister()); - } - - // Call to the runtime - int before = asm.codeBuffer.position(); - asm.call(); - int after = asm.codeBuffer.position(); - tasm.recordDirectCall(before, after, call, null); - - if (call.resultKind != CiKind.Void) { - CiRegister returnRegister = compiler.globalStubRegisterConfig.getReturnRegister(call.resultKind); - this.storeArgument(0, returnRegister); - } - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64LIRAssembler.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64LIRAssembler.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,2312 +0,0 @@ -/* - * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.compiler.target.amd64; - -import static com.sun.cri.bytecode.Bytecodes.*; -import static com.sun.cri.ci.CiCallingConvention.Type.*; -import static com.sun.cri.ci.CiRegister.*; -import static com.sun.cri.ci.CiValue.*; -import static java.lang.Double.*; -import static java.lang.Float.*; - -import java.util.*; - -import com.oracle.max.asm.*; -import com.oracle.max.asm.target.amd64.*; -import com.oracle.max.asm.target.amd64.AMD64Assembler.ConditionFlag; -import com.oracle.max.graal.compiler.*; -import com.oracle.max.graal.compiler.debug.*; -import com.oracle.max.graal.compiler.gen.LIRGenerator.DeoptimizationStub; -import com.oracle.max.graal.compiler.globalstub.*; -import com.oracle.max.graal.compiler.lir.FrameMap.StackBlock; -import com.oracle.max.graal.compiler.lir.*; -import com.oracle.max.graal.compiler.util.*; -import com.oracle.max.graal.nodes.calc.*; -import com.sun.cri.ci.*; -import com.sun.cri.ci.CiAddress.Scale; -import com.sun.cri.ci.CiTargetMethod.JumpTable; -import com.sun.cri.ci.CiTargetMethod.Mark; -import com.sun.cri.xir.*; -import com.sun.cri.xir.CiXirAssembler.RuntimeCallInformation; -import com.sun.cri.xir.CiXirAssembler.XirInstruction; -import com.sun.cri.xir.CiXirAssembler.XirLabel; -import com.sun.cri.xir.CiXirAssembler.XirMark; - -/** - * This class implements the x86-specific code generation for LIR. - */ -public final class AMD64LIRAssembler extends LIRAssembler { - - private static final Object[] NO_PARAMS = new Object[0]; - private static final long NULLWORD = 0; - private static final CiRegister SHIFTCount = AMD64.rcx; - - private static final long DoubleSignMask = 0x7FFFFFFFFFFFFFFFL; - - final CiTarget target; - final AMD64MacroAssembler masm; - final int wordSize; - final CiRegister rscratch1; - - public AMD64LIRAssembler(GraalCompilation compilation) { - super(compilation); - masm = (AMD64MacroAssembler) asm; - target = compilation.target; - wordSize = target.wordSize; - rscratch1 = compilation.registerConfig.getScratchRegister(); - } - - private CiAddress asAddress(CiValue value) { - if (value.isAddress()) { - return (CiAddress) value; - } - assert value.isStackSlot(); - return compilation.frameMap().toStackAddress((CiStackSlot) value); - } - - @Override - protected int initialFrameSizeInBytes() { - return frameMap.frameSize(); - } - - @Override - protected void emitReturn(CiValue result) { - // TODO: Consider adding safepoint polling at return! - masm.ret(0); - } - - @Override - protected void emitMonitorAddress(int monitor, CiValue dst) { - CiStackSlot slot = frameMap.toMonitorBaseStackAddress(monitor); - masm.leaq(dst.asRegister(), new CiAddress(slot.kind, AMD64.rsp.asValue(), slot.index() * target.arch.wordSize)); - } - - @Override - protected void emitBreakpoint() { - masm.int3(); - } - - @Override - protected void emitStackAllocate(StackBlock stackBlock, CiValue dst) { - masm.leaq(dst.asRegister(), compilation.frameMap().toStackAddress(stackBlock)); - } - - private void moveRegs(CiRegister fromReg, CiRegister toReg) { - if (fromReg != toReg) { - masm.mov(toReg, fromReg); - } - } - - private void swapReg(CiRegister a, CiRegister b) { - masm.xchgptr(a, b); - } - - private void const2reg(CiRegister dst, int constant) { - // Do not optimize with an XOR as this instruction may be between - // a CMP and a Jcc in which case the XOR will modify the condition - // flags and interfere with the Jcc. - masm.movl(dst, constant); - } - - private void const2reg(CiRegister dst, long constant) { - // Do not optimize with an XOR as this instruction may be between - // a CMP and a Jcc in which case the XOR will modify the condition - // flags and interfere with the Jcc. - masm.movq(dst, constant); - } - - private void const2reg(CiRegister dst, CiConstant constant) { - assert constant.kind == CiKind.Object; - // Do not optimize with an XOR as this instruction may be between - // a CMP and a Jcc in which case the XOR will modify the condition - // flags and interfere with the Jcc. - if (constant.isNull()) { - masm.movq(dst, 0x0L); - } else if (target.inlineObjects) { - tasm.recordDataReferenceInCode(constant); - masm.movq(dst, 0xDEADDEADDEADDEADL); - } else { - masm.movq(dst, tasm.recordDataReferenceInCode(constant)); - } - } - - @Override - public void emitTraps() { - for (int i = 0; i < GraalOptions.MethodEndBreakpointGuards; ++i) { - masm.int3(); - } - } - - private void const2reg(CiRegister dst, float constant) { - if (constant == 0.0f) { - masm.xorps(dst, dst); - } else { - masm.movflt(dst, tasm.recordDataReferenceInCode(CiConstant.forFloat(constant))); - } - } - - private void const2reg(CiRegister dst, double constant) { - if (constant == 0.0f) { - masm.xorpd(dst, dst); - } else { - masm.movdbl(dst, tasm.recordDataReferenceInCode(CiConstant.forDouble(constant))); - } - } - - @Override - protected void const2reg(CiValue src, CiValue dest, LIRDebugInfo info) { - assert src.isConstant(); - assert dest.isRegister(); - CiConstant c = (CiConstant) src; - - // Checkstyle: off - switch (c.kind) { - case Boolean : - case Byte : - case Char : - case Short : - case Jsr : - case Int : const2reg(dest.asRegister(), c.asInt()); break; - case Word : - case Long : const2reg(dest.asRegister(), c.asLong()); break; - case Object : const2reg(dest.asRegister(), c); break; - case Float : const2reg(asXmmFloatReg(dest), c.asFloat()); break; - case Double : const2reg(asXmmDoubleReg(dest), c.asDouble()); break; - default : throw Util.shouldNotReachHere(); - } - // Checkstyle: on - } - - @Override - protected void const2stack(CiValue src, CiValue dst) { - assert src.isConstant(); - assert dst.isStackSlot(); - CiStackSlot slot = (CiStackSlot) dst; - CiConstant c = (CiConstant) src; - - // Checkstyle: off - switch (c.kind) { - case Boolean : - case Byte : - case Char : - case Short : - case Jsr : - case Int : masm.movl(frameMap.toStackAddress(slot), c.asInt()); break; - case Float : masm.movl(frameMap.toStackAddress(slot), floatToRawIntBits(c.asFloat())); break; - case Object : movoop(frameMap.toStackAddress(slot), c); break; - case Long : masm.mov64(frameMap.toStackAddress(slot), c.asLong()); break; - case Double : masm.mov64(frameMap.toStackAddress(slot), doubleToRawLongBits(c.asDouble())); break; - default : throw Util.shouldNotReachHere("Unknown constant kind for const2stack: " + c.kind); - } - // Checkstyle: on - } - - @Override - protected void const2mem(CiValue src, CiValue dst, CiKind kind, LIRDebugInfo info) { - assert src.isConstant(); - assert dst.isAddress(); - CiConstant constant = (CiConstant) src; - CiAddress addr = asAddress(dst); - - int nullCheckHere = codePos(); - // Checkstyle: off - switch (kind) { - case Boolean : - case Byte : masm.movb(addr, constant.asInt() & 0xFF); break; - case Char : - case Short : masm.movw(addr, constant.asInt() & 0xFFFF); break; - case Jsr : - case Int : masm.movl(addr, constant.asInt()); break; - case Float : masm.movl(addr, floatToRawIntBits(constant.asFloat())); break; - case Object : movoop(addr, constant); break; - case Word: - case Long : masm.movq(rscratch1, constant.asLong()); - nullCheckHere = codePos(); - masm.movq(addr, rscratch1); break; - case Double : masm.movq(rscratch1, doubleToRawLongBits(constant.asDouble())); - nullCheckHere = codePos(); - masm.movq(addr, rscratch1); break; - default : throw Util.shouldNotReachHere(); - } - // Checkstyle: on - - if (info != null) { - tasm.recordImplicitException(nullCheckHere, info); - } - } - - @Override - protected void reg2reg(CiValue src, CiValue dest) { - assert src.isRegister(); - assert dest.isRegister(); - - if (dest.kind.isFloat()) { - masm.movflt(asXmmFloatReg(dest), asXmmFloatReg(src)); - } else if (dest.kind.isDouble()) { - masm.movdbl(asXmmDoubleReg(dest), asXmmDoubleReg(src)); - } else { - moveRegs(src.asRegister(), dest.asRegister()); - } - } - - @Override - protected void reg2stack(CiValue src, CiValue dst, CiKind kind) { - assert src.isRegister(); - assert dst.isStackSlot(); - CiAddress addr = frameMap.toStackAddress((CiStackSlot) dst); - - // Checkstyle: off - switch (src.kind) { - case Boolean : - case Byte : - case Char : - case Short : - case Jsr : - case Int : masm.movl(addr, src.asRegister()); break; - case Object : - case Word : - case Long : masm.movq(addr, src.asRegister()); break; - case Float : masm.movflt(addr, asXmmFloatReg(src)); break; - case Double : masm.movsd(addr, asXmmDoubleReg(src)); break; - default : throw Util.shouldNotReachHere(); - } - // Checkstyle: on - } - - @Override - protected void reg2mem(CiValue src, CiValue dest, CiKind kind, LIRDebugInfo info, boolean unaligned) { - CiAddress toAddr = (CiAddress) dest; - - if (info != null) { - tasm.recordImplicitException(codePos(), info); - } - - // Checkstyle: off - switch (kind) { - case Float : masm.movflt(toAddr, asXmmFloatReg(src)); break; - case Double : masm.movsd(toAddr, asXmmDoubleReg(src)); break; - case Jsr : - case Int : masm.movl(toAddr, src.asRegister()); break; - case Long : - case Word : - case Object : masm.movq(toAddr, src.asRegister()); break; - case Char : - case Short : masm.movw(toAddr, src.asRegister()); break; - case Byte : - case Boolean : masm.movb(toAddr, src.asRegister()); break; - default : throw Util.shouldNotReachHere(); - } - // Checkstyle: on - } - - private static CiRegister asXmmFloatReg(CiValue src) { - assert src.kind.isFloat() : "must be float, actual kind: " + src.kind; - CiRegister result = src.asRegister(); - assert result.isFpu() : "must be xmm, actual type: " + result; - return result; - } - - @Override - protected void stack2reg(CiValue src, CiValue dest, CiKind kind) { - assert src.isStackSlot(); - assert dest.isRegister(); - - CiAddress addr = frameMap.toStackAddress((CiStackSlot) src); - - // Checkstyle: off - switch (dest.kind) { - case Boolean : - case Byte : - case Char : - case Short : - case Jsr : - case Int : masm.movl(dest.asRegister(), addr); break; - case Object : - case Word : - case Long : masm.movq(dest.asRegister(), addr); break; - case Float : masm.movflt(asXmmFloatReg(dest), addr); break; - case Double : masm.movdbl(asXmmDoubleReg(dest), addr); break; - default : throw Util.shouldNotReachHere(); - } - // Checkstyle: on - } - - @Override - protected void mem2mem(CiValue src, CiValue dest, CiKind kind) { - if (dest.kind.isInt()) { - masm.pushl((CiAddress) src); - masm.popl((CiAddress) dest); - } else { - masm.pushptr((CiAddress) src); - masm.popptr((CiAddress) dest); - } - } - - @Override - protected void mem2stack(CiValue src, CiValue dest, CiKind kind) { - if (dest.kind.isInt()) { - masm.pushl((CiAddress) src); - masm.popl(frameMap.toStackAddress((CiStackSlot) dest)); - } else { - masm.pushptr((CiAddress) src); - masm.popptr(frameMap.toStackAddress((CiStackSlot) dest)); - } - } - - @Override - protected void stack2stack(CiValue src, CiValue dest, CiKind kind) { - if (src.kind.isInt()) { - masm.pushl(frameMap.toStackAddress((CiStackSlot) src)); - masm.popl(frameMap.toStackAddress((CiStackSlot) dest)); - } else { - masm.pushptr(frameMap.toStackAddress((CiStackSlot) src)); - masm.popptr(frameMap.toStackAddress((CiStackSlot) dest)); - } - } - - @Override - protected void mem2reg(CiValue src, CiValue dest, CiKind kind, LIRDebugInfo info, boolean unaligned) { - assert src.isAddress(); - assert dest.isRegister() : "dest=" + dest; - - CiAddress addr = (CiAddress) src; - if (info != null) { - tasm.recordImplicitException(codePos(), info); - } - - // Checkstyle: off - switch (kind) { - case Float : masm.movflt(asXmmFloatReg(dest), addr); break; - case Double : masm.movdbl(asXmmDoubleReg(dest), addr); break; - case Object : masm.movq(dest.asRegister(), addr); break; - case Int : masm.movslq(dest.asRegister(), addr); break; - case Word : - case Long : masm.movq(dest.asRegister(), addr); break; - case Boolean : - case Byte : masm.movsxb(dest.asRegister(), addr); break; - case Char : masm.movzxl(dest.asRegister(), addr); break; - case Short : masm.movswl(dest.asRegister(), addr); break; - default : throw Util.shouldNotReachHere(); - } - // Checkstyle: on - } - - @Override - protected void emitReadPrefetch(CiValue src) { - CiAddress addr = (CiAddress) src; - // Checkstyle: off - switch (GraalOptions.ReadPrefetchInstr) { - case 0 : masm.prefetchnta(addr); break; - case 1 : masm.prefetcht0(addr); break; - case 2 : masm.prefetcht2(addr); break; - default : throw Util.shouldNotReachHere(); - } - // Checkstyle: on - } - - @Override - protected void emitOp3(LIROp3 op) { - // Checkstyle: off - switch (op.code) { - case Idiv : - case Irem : arithmeticIdiv(op.code, op.opr1(), op.opr2(), op.result(), op.info); break; - case Ldiv : - case Lrem : arithmeticLdiv(op.code, op.opr1(), op.opr2(), op.result(), op.info); break; - case Wdiv : - case Wdivi : - case Wrem : - case Wremi : arithmeticWdiv(op.code, op.opr1(), op.opr2(), op.result(), op.info); break; - default : throw Util.shouldNotReachHere(); - } - // Checkstyle: on - } - - private boolean assertEmitBranch(LIRBranch op) { - assert op.block() == null || op.block().label() == op.label() : "wrong label"; - return true; - } - - private boolean assertEmitTableSwitch(LIRTableSwitch op) { - assert op.defaultTarget != null; - return true; - } - - @Override - protected void emitTableSwitch(LIRTableSwitch op) { - - assert assertEmitTableSwitch(op); - - CiRegister value = op.value().asRegister(); - final Buffer buf = masm.codeBuffer; - - // Compare index against jump table bounds - int highKey = op.lowKey + op.targets.length - 1; - if (op.lowKey != 0) { - // subtract the low value from the switch value - masm.subl(value, op.lowKey); - masm.cmpl(value, highKey - op.lowKey); - } else { - masm.cmpl(value, highKey); - } - - // Jump to default target if index is not within the jump table - masm.jcc(ConditionFlag.above, op.defaultTarget.label()); - - // Set scratch to address of jump table - int leaPos = buf.position(); - buf.putMark(); - masm.leaq(rscratch1, new CiAddress(CiKind.Word, InstructionRelative.asValue(), 0)); - - // Load jump table entry into scratch and jump to it - masm.movslq(value, new CiAddress(CiKind.Int, rscratch1.asValue(), value.asValue(), Scale.Times4, 0)); - masm.addq(rscratch1, value); - masm.jmp(rscratch1); - - // Inserting padding so that jump table address is 4-byte aligned - if ((buf.position() & 0x3) != 0) { - masm.nop(4 - (buf.position() & 0x3)); - } - - // Patch LEA instruction above now that we know the position of the jump table - int jumpTablePos = buf.position(); - buf.setPosition(leaPos); - buf.putMark(); - masm.leaq(rscratch1, new CiAddress(CiKind.Word, InstructionRelative.asValue(), jumpTablePos - leaPos)); - buf.setPosition(jumpTablePos); - - // Emit jump table entries - for (LIRBlock target : op.targets) { - Label label = target.label(); - int offsetToJumpTableBase = buf.position() - jumpTablePos; - if (label.isBound()) { - int imm32 = label.position() - jumpTablePos; - buf.emitInt(imm32); - } else { - label.addPatchAt(buf.position()); - - buf.emitByte(0); // psuedo-opcode for jump table entry - buf.emitShort(offsetToJumpTableBase); - buf.emitByte(0); // padding to make jump table entry 4 bytes wide - } - } - - JumpTable jt = new JumpTable(jumpTablePos, op.lowKey, highKey, 4); - tasm.targetMethod.addAnnotation(jt); - } - - @Override - protected void emitBranch(LIRBranch op) { - - assert assertEmitBranch(op); - - if (op.cond() == Condition.TRUE) { - if (op.info != null) { - int codePos = codePos(); - if (codePos <= tasm.lastSafepointPos()) { - masm.nop(); - } - tasm.recordImplicitException(codePos(), op.info); - } - masm.jmp(op.label()); - } else { - ConditionFlag acond = ConditionFlag.zero; - Label unorderedLabel = null; - if (op.code == LIROpcode.CondFloatBranch) { - if (op.unorderedBlock() == null) { - unorderedLabel = new Label(); - } else { - unorderedLabel = op.unorderedBlock().label; - } - if (unorderedLabel != op.label() || !trueOnUnordered(op.cond())) { - masm.jcc(ConditionFlag.parity, unorderedLabel); - } - // Checkstyle: off - switch (op.cond()) { - case EQ : acond = ConditionFlag.equal; break; - case NE : acond = ConditionFlag.notEqual; break; - case BT : acond = ConditionFlag.below; break; - case BE : acond = ConditionFlag.belowEqual; break; - case AE : acond = ConditionFlag.aboveEqual; break; - case AT : acond = ConditionFlag.above; break; - default : throw Util.shouldNotReachHere(); - } - } else { - switch (op.cond()) { - case EQ : acond = ConditionFlag.equal; break; - case NE : acond = ConditionFlag.notEqual; break; - case LT : acond = ConditionFlag.less; break; - case LE : acond = ConditionFlag.lessEqual; break; - case GE : acond = ConditionFlag.greaterEqual; break; - case GT : acond = ConditionFlag.greater; break; - case BE : acond = ConditionFlag.belowEqual; break; - case AE : acond = ConditionFlag.aboveEqual; break; - case AT : acond = ConditionFlag.above; break; - case BT : acond = ConditionFlag.below; break; - case OF : acond = ConditionFlag.overflow; break; - case NOF : acond = ConditionFlag.noOverflow; break; - default : throw Util.shouldNotReachHere(); - } - // Checkstyle: on - } - masm.jcc(acond, op.label()); - if (unorderedLabel != null && op.unorderedBlock() == null) { - masm.bind(unorderedLabel); - } - } - } - - @Override - protected void emitConvert(LIRConvert op) { - CiValue src = op.operand(); - CiValue dest = op.result(); - Label endLabel = new Label(); - CiRegister srcRegister = src.asRegister(); - switch (op.bytecode) { - case I2L: - masm.movslq(dest.asRegister(), srcRegister); - break; - - case L2I: - moveRegs(srcRegister, dest.asRegister()); - masm.andl(dest.asRegister(), 0xFFFFFFFF); - break; - - case I2B: - moveRegs(srcRegister, dest.asRegister()); - masm.signExtendByte(dest.asRegister()); - break; - - case I2C: - moveRegs(srcRegister, dest.asRegister()); - masm.andl(dest.asRegister(), 0xFFFF); - break; - - case I2S: - moveRegs(srcRegister, dest.asRegister()); - masm.signExtendShort(dest.asRegister()); - break; - - case F2D: - masm.cvtss2sd(asXmmDoubleReg(dest), asXmmFloatReg(src)); - break; - - case D2F: - masm.cvtsd2ss(asXmmFloatReg(dest), asXmmDoubleReg(src)); - break; - - case I2F: - masm.cvtsi2ssl(asXmmFloatReg(dest), srcRegister); - break; - case I2D: - masm.cvtsi2sdl(asXmmDoubleReg(dest), srcRegister); - break; - - case F2I: { - assert srcRegister.isFpu() && dest.isRegister() : "must both be XMM register (no fpu stack)"; - masm.cvttss2sil(dest.asRegister(), srcRegister); - masm.cmp32(dest.asRegister(), Integer.MIN_VALUE); - masm.jcc(ConditionFlag.notEqual, endLabel); - callGlobalStub(op.globalStub, null, dest.asRegister(), src); - // cannot cause an exception - masm.bind(endLabel); - break; - } - case D2I: { - assert srcRegister.isFpu() && dest.isRegister() : "must both be XMM register (no fpu stack)"; - masm.cvttsd2sil(dest.asRegister(), asXmmDoubleReg(src)); - masm.cmp32(dest.asRegister(), Integer.MIN_VALUE); - masm.jcc(ConditionFlag.notEqual, endLabel); - callGlobalStub(op.globalStub, null, dest.asRegister(), src); - // cannot cause an exception - masm.bind(endLabel); - break; - } - case L2F: - masm.cvtsi2ssq(asXmmFloatReg(dest), srcRegister); - break; - - case L2D: - masm.cvtsi2sdq(asXmmDoubleReg(dest), srcRegister); - break; - - case F2L: { - assert srcRegister.isFpu() && dest.kind.isLong() : "must both be XMM register (no fpu stack)"; - masm.cvttss2siq(dest.asRegister(), asXmmFloatReg(src)); - masm.movq(rscratch1, java.lang.Long.MIN_VALUE); - masm.cmpq(dest.asRegister(), rscratch1); - masm.jcc(ConditionFlag.notEqual, endLabel); - callGlobalStub(op.globalStub, null, dest.asRegister(), src); - masm.bind(endLabel); - break; - } - - case D2L: { - assert srcRegister.isFpu() && dest.kind.isLong() : "must both be XMM register (no fpu stack)"; - masm.cvttsd2siq(dest.asRegister(), asXmmDoubleReg(src)); - masm.movq(rscratch1, java.lang.Long.MIN_VALUE); - masm.cmpq(dest.asRegister(), rscratch1); - masm.jcc(ConditionFlag.notEqual, endLabel); - callGlobalStub(op.globalStub, null, dest.asRegister(), src); - masm.bind(endLabel); - break; - } - - case MOV_I2F: - masm.movdl(asXmmFloatReg(dest), srcRegister); - break; - - case MOV_L2D: - masm.movdq(asXmmDoubleReg(dest), srcRegister); - break; - - case MOV_F2I: - masm.movdl(dest.asRegister(), asXmmFloatReg(src)); - break; - - case MOV_D2L: - masm.movdq(dest.asRegister(), asXmmDoubleReg(src)); - break; - - default: - throw Util.shouldNotReachHere(); - } - } - - @Override - protected void emitCompareAndSwap(LIRCompareAndSwap op) { - CiAddress address = new CiAddress(CiKind.Object, op.address(), 0); - CiRegister newval = op.newValue().asRegister(); - CiRegister cmpval = op.expectedValue().asRegister(); - assert cmpval == AMD64.rax : "wrong register"; - assert newval != null : "new val must be register"; - assert cmpval != newval : "cmp and new values must be in different registers"; - assert cmpval != address.base() : "cmp and addr must be in different registers"; - assert newval != address.base() : "new value and addr must be in different registers"; - assert cmpval != address.index() : "cmp and addr must be in different registers"; - assert newval != address.index() : "new value and addr must be in different registers"; - if (compilation.target.isMP) { - masm.lock(); - } - if (op.code == LIROpcode.CasInt) { - masm.cmpxchgl(newval, address); - } else { - assert op.code == LIROpcode.CasObj || op.code == LIROpcode.CasLong || op.code == LIROpcode.CasWord; - masm.cmpxchgq(newval, address); - } - } - - @Override - protected void emitConditionalMove(Condition condition, CiValue opr1, CiValue opr2, CiValue result, boolean mayBeUnordered, boolean unorderedcmovOpr1) { - //TTY.println("cmov " + condition + " " + opr1 + " : " + opr2 + " mayBeUnordered:" + mayBeUnordered + " pcmovop=" + (unorderedcmovOpr1 ? 1 : 2)); - ConditionFlag acond; - ConditionFlag ncond; - switch (condition) { - case EQ: - acond = ConditionFlag.equal; - ncond = ConditionFlag.notEqual; - break; - case NE: - acond = ConditionFlag.notEqual; - ncond = ConditionFlag.equal; - break; - case LT: - acond = ConditionFlag.less; - ncond = ConditionFlag.greaterEqual; - break; - case LE: - acond = ConditionFlag.lessEqual; - ncond = ConditionFlag.greater; - break; - case GE: - acond = ConditionFlag.greaterEqual; - ncond = ConditionFlag.less; - break; - case GT: - acond = ConditionFlag.greater; - ncond = ConditionFlag.lessEqual; - break; - case BE: - acond = ConditionFlag.belowEqual; - ncond = ConditionFlag.above; - break; - case BT: - acond = ConditionFlag.below; - ncond = ConditionFlag.aboveEqual; - break; - case AE: - acond = ConditionFlag.aboveEqual; - ncond = ConditionFlag.below; - break; - case AT: - acond = ConditionFlag.above; - ncond = ConditionFlag.belowEqual; - break; - case OF: - acond = ConditionFlag.overflow; - ncond = ConditionFlag.noOverflow; - break; - case NOF: - acond = ConditionFlag.noOverflow; - ncond = ConditionFlag.overflow; - break; - default: - throw Util.shouldNotReachHere(); - } - - CiValue def = opr1; // assume left operand as default - CiValue other = opr2; - - if (opr2.isRegister() && opr2.asRegister() == result.asRegister()) { - // if the right operand is already in the result register, then use it as the default - def = opr2; - other = opr1; - // and flip the condition - condition = condition.negate(); - ConditionFlag tcond = acond; - acond = ncond; - ncond = tcond; - unorderedcmovOpr1 = !unorderedcmovOpr1; - } - - if (def.isRegister()) { - if (def.asRegister() != result.asRegister()) { - reg2reg(def, result); - } - } else if (def.isStackSlot()) { - stack2reg(def, result, result.kind); - } else { - assert def.isConstant(); - const2reg(def, result, null); - } - - boolean cmovOnParity = (unorderedcmovOpr1 && mayBeTrueOnUnordered(condition.negate())) || (!unorderedcmovOpr1 && mayBeFalseOnUnordered(condition.negate())); - if (!other.isConstant() && !(cmovOnParity && def.isConstant())) { - // optimized version that does not require a branch - //TTY.println("> emitting cmov" + (mayBeUnordered && cmovOnParity ? " (with parity check)" : "")); - cmov(result, ncond, other); - if (mayBeUnordered && cmovOnParity) { - cmov(result, ConditionFlag.parity, unorderedcmovOpr1 ? def : other); - } - } else { - //TTY.println("> emitting jumps instead of cmov"); - // conditional move not available, use emit a branch and move - Label skip = new Label(); - Label mov = new Label(); - if (mayBeUnordered && ((mayBeTrueOnUnordered(condition) && !unorderedcmovOpr1) || (mayBeFalseOnUnordered(condition) && unorderedcmovOpr1))) { - masm.jcc(ConditionFlag.parity, unorderedcmovOpr1 ? skip : mov); - } - masm.jcc(acond, skip); - masm.bind(mov); - if (other.isRegister()) { - reg2reg(other, result); - } else if (other.isStackSlot()) { - stack2reg(other, result, result.kind); - } else { - assert other.isConstant(); - const2reg(other, result, null); - } - masm.bind(skip); - } - } - - private void cmov(CiValue result, ConditionFlag ncond, CiValue other) { - if (other.isRegister()) { - assert other.asRegister() != result.asRegister() : "other already overwritten by previous move"; - if (other.kind.isInt()) { - masm.cmovl(ncond, result.asRegister(), other.asRegister()); - } else { - masm.cmovq(ncond, result.asRegister(), other.asRegister()); - } - } else { - assert other.isStackSlot(); - CiStackSlot otherSlot = (CiStackSlot) other; - if (other.kind.isInt()) { - masm.cmovl(ncond, result.asRegister(), frameMap.toStackAddress(otherSlot)); - } else { - masm.cmovq(ncond, result.asRegister(), frameMap.toStackAddress(otherSlot)); - } - } - } - - @Override - protected void emitArithOp(LIROpcode code, CiValue left, CiValue right, CiValue dest, LIRDebugInfo info) { - assert info == null : "should never be used : idiv/irem and ldiv/lrem not handled by this method"; - assert Util.archKindsEqual(left.kind, right.kind) || (left.kind == CiKind.Word && right.kind == CiKind.Int) : code.toString() + " left arch is " + left.kind + " and right arch is " + right.kind; - assert left.equals(dest) : "left and dest must be equal"; - CiKind kind = left.kind; - - // Checkstyle: off - if (left.isRegister()) { - CiRegister lreg = left.asRegister(); - - if (right.isRegister()) { - // register - register - CiRegister rreg = right.asRegister(); - if (kind.isInt()) { - switch (code) { - case Add : masm.addl(lreg, rreg); break; - case Sub : masm.subl(lreg, rreg); break; - case Mul : masm.imull(lreg, rreg); break; - default : throw Util.shouldNotReachHere(); - } - } else if (kind.isFloat()) { - assert rreg.isFpu() : "must be xmm"; - switch (code) { - case Add : masm.addss(lreg, rreg); break; - case Sub : masm.subss(lreg, rreg); break; - case Mul : masm.mulss(lreg, rreg); break; - case Div : masm.divss(lreg, rreg); break; - default : throw Util.shouldNotReachHere(); - } - } else if (kind.isDouble()) { - assert rreg.isFpu(); - switch (code) { - case Add : masm.addsd(lreg, rreg); break; - case Sub : masm.subsd(lreg, rreg); break; - case Mul : masm.mulsd(lreg, rreg); break; - case Div : masm.divsd(lreg, rreg); break; - default : throw Util.shouldNotReachHere(); - } - } else { - assert target.sizeInBytes(kind) == 8; - switch (code) { - case Add : masm.addq(lreg, rreg); break; - case Sub : masm.subq(lreg, rreg); break; - case Mul : masm.imulq(lreg, rreg); break; - default : throw Util.shouldNotReachHere(); - } - } - } else { - if (kind.isInt()) { - if (right.isStackSlot()) { - // register - stack - CiAddress raddr = frameMap.toStackAddress(((CiStackSlot) right)); - switch (code) { - case Add : masm.addl(lreg, raddr); break; - case Sub : masm.subl(lreg, raddr); break; - default : throw Util.shouldNotReachHere(); - } - } else if (right.isConstant()) { - // register - constant - assert kind.isInt(); - int delta = ((CiConstant) right).asInt(); - switch (code) { - case Add : masm.incrementl(lreg, delta); break; - case Sub : masm.decrementl(lreg, delta); break; - default : throw Util.shouldNotReachHere(); - } - } - } else if (kind.isFloat()) { - // register - stack/constant - CiAddress raddr; - if (right.isStackSlot()) { - raddr = frameMap.toStackAddress(((CiStackSlot) right)); - } else { - assert right.isConstant(); - raddr = tasm.recordDataReferenceInCode(CiConstant.forFloat(((CiConstant) right).asFloat())); - } - switch (code) { - case Add : masm.addss(lreg, raddr); break; - case Sub : masm.subss(lreg, raddr); break; - case Mul : masm.mulss(lreg, raddr); break; - case Div : masm.divss(lreg, raddr); break; - default : throw Util.shouldNotReachHere(); - } - } else if (kind.isDouble()) { - // register - stack/constant - CiAddress raddr; - if (right.isStackSlot()) { - raddr = frameMap.toStackAddress(((CiStackSlot) right)); - } else { - assert right.isConstant(); - raddr = tasm.recordDataReferenceInCode(CiConstant.forDouble(((CiConstant) right).asDouble())); - } - switch (code) { - case Add : masm.addsd(lreg, raddr); break; - case Sub : masm.subsd(lreg, raddr); break; - case Mul : masm.mulsd(lreg, raddr); break; - case Div : masm.divsd(lreg, raddr); break; - default : throw Util.shouldNotReachHere(); - } - } else { - assert target.sizeInBytes(kind) == 8; - if (right.isStackSlot()) { - // register - stack - CiAddress raddr = frameMap.toStackAddress(((CiStackSlot) right)); - switch (code) { - case Add : masm.addq(lreg, raddr); break; - case Sub : masm.subq(lreg, raddr); break; - default : throw Util.shouldNotReachHere(); - } - } else { - // register - constant - assert right.isConstant(); - long c = ((CiConstant) right).asLong(); - if (NumUtil.isInt(c)) { - switch (code) { - case Add : masm.addq(lreg, (int) c); break; - case Sub : masm.subq(lreg, (int) c); break; - default : throw Util.shouldNotReachHere(); - } - } else { - masm.movq(rscratch1, c); - switch (code) { - case Add : masm.addq(lreg, rscratch1); break; - case Sub : masm.subq(lreg, rscratch1); break; - default : throw Util.shouldNotReachHere(); - } - } - } - } - } - } else { - assert kind.isInt(); - CiAddress laddr = asAddress(left); - - if (right.isRegister()) { - CiRegister rreg = right.asRegister(); - switch (code) { - case Add : masm.addl(laddr, rreg); break; - case Sub : masm.subl(laddr, rreg); break; - default : throw Util.shouldNotReachHere(); - } - } else { - assert right.isConstant(); - int c = ((CiConstant) right).asInt(); - switch (code) { - case Add : masm.incrementl(laddr, c); break; - case Sub : masm.decrementl(laddr, c); break; - default : throw Util.shouldNotReachHere(); - } - } - } - // Checkstyle: on - } - - @Override - protected void emitIntrinsicOp(LIROpcode code, CiValue value, CiValue unused, CiValue dest, LIROp2 op) { - assert value.kind.isDouble(); - switch (code) { - case Abs: - if (asXmmDoubleReg(dest) != asXmmDoubleReg(value)) { - masm.movdbl(asXmmDoubleReg(dest), asXmmDoubleReg(value)); - } - masm.andpd(asXmmDoubleReg(dest), tasm.recordDataReferenceInCode(CiConstant.forLong(DoubleSignMask))); - break; - - case Sqrt: - masm.sqrtsd(asXmmDoubleReg(dest), asXmmDoubleReg(value)); - break; - - default: - throw Util.shouldNotReachHere(); - } - } - - @Override - protected void emitLogicOp(LIROpcode code, CiValue left, CiValue right, CiValue dst) { - assert left.isRegister(); - // Checkstyle: off - if (left.kind.isInt()) { - CiRegister reg = left.asRegister(); - if (right.isConstant()) { - int val = ((CiConstant) right).asInt(); - switch (code) { - case LogicAnd : masm.andl(reg, val); break; - case LogicOr : masm.orl(reg, val); break; - case LogicXor : masm.xorl(reg, val); break; - default : throw Util.shouldNotReachHere(); - } - } else if (right.isStackSlot()) { - // added support for stack operands - CiAddress raddr = frameMap.toStackAddress(((CiStackSlot) right)); - switch (code) { - case LogicAnd : masm.andl(reg, raddr); break; - case LogicOr : masm.orl(reg, raddr); break; - case LogicXor : masm.xorl(reg, raddr); break; - default : throw Util.shouldNotReachHere(); - } - } else { - CiRegister rright = right.asRegister(); - switch (code) { - case LogicAnd : masm.andq(reg, rright); break; - case LogicOr : masm.orq(reg, rright); break; - case LogicXor : masm.xorptr(reg, rright); break; - default : throw Util.shouldNotReachHere(); - } - } - moveRegs(reg, dst.asRegister()); - } else { - assert target.sizeInBytes(left.kind) == 8; - CiRegister lreg = left.asRegister(); - if (right.isConstant()) { - CiConstant rightConstant = (CiConstant) right; - masm.movq(rscratch1, rightConstant.asLong()); - switch (code) { - case LogicAnd : masm.andq(lreg, rscratch1); break; - case LogicOr : masm.orq(lreg, rscratch1); break; - case LogicXor : masm.xorq(lreg, rscratch1); break; - default : throw Util.shouldNotReachHere(); - } - } else { - CiRegister rreg = right.asRegister(); - switch (code) { - case LogicAnd : masm.andq(lreg, rreg); break; - case LogicOr : masm.orq(lreg, rreg); break; - case LogicXor : masm.xorptr(lreg, rreg); break; - default : throw Util.shouldNotReachHere(); - } - } - - CiRegister dreg = dst.asRegister(); - moveRegs(lreg, dreg); - } - // Checkstyle: on - } - - void arithmeticIdiv(LIROpcode code, CiValue left, CiValue right, CiValue result, LIRDebugInfo info) { - assert left.isRegister() : "left must be register"; - assert right.isRegister() || right.isConstant() : "right must be register or constant"; - assert result.isRegister() : "result must be register"; - - CiRegister lreg = left.asRegister(); - CiRegister dreg = result.asRegister(); - - if (right.isConstant()) { - int divisor = ((CiConstant) right).asInt(); - assert divisor > 0 && CiUtil.isPowerOf2(divisor) : "divisor must be power of two"; - if (code == LIROpcode.Idiv) { - assert lreg == AMD64.rax : "dividend must be rax"; - masm.cdql(); // sign extend into rdx:rax - if (divisor == 2) { - masm.subl(lreg, AMD64.rdx); - } else { - masm.andl(AMD64.rdx, divisor - 1); - masm.addl(lreg, AMD64.rdx); - } - masm.sarl(lreg, CiUtil.log2(divisor)); - moveRegs(lreg, dreg); - } else { - assert code == LIROpcode.Irem; - Label done = new Label(); - masm.mov(dreg, lreg); - masm.andl(dreg, 0x80000000 | (divisor - 1)); - masm.jcc(ConditionFlag.positive, done); - masm.decrementl(dreg, 1); - masm.orl(dreg, ~(divisor - 1)); - masm.incrementl(dreg, 1); - masm.bind(done); - } - } else { - CiRegister rreg = right.asRegister(); - assert lreg == AMD64.rax : "left register must be rax"; - assert rreg != AMD64.rdx : "right register must not be rdx"; - - moveRegs(lreg, AMD64.rax); - - Label continuation = new Label(); - masm.cdql(); - int offset = masm.codeBuffer.position(); - masm.idivl(rreg); - - // normal and special case exit - masm.bind(continuation); - - tasm.recordImplicitException(offset, info); - if (code == LIROpcode.Irem) { - moveRegs(AMD64.rdx, dreg); // result is in rdx - } else { - assert code == LIROpcode.Idiv; - moveRegs(AMD64.rax, dreg); - } - } - } - - void arithmeticLdiv(LIROpcode code, CiValue left, CiValue right, CiValue result, LIRDebugInfo info) { - assert left.isRegister() : "left must be register"; - assert right.isRegister() : "right must be register"; - assert result.isRegister() : "result must be register"; - assert result.kind.isLong(); - - CiRegister lreg = left.asRegister(); - CiRegister dreg = result.asRegister(); - CiRegister rreg = right.asRegister(); - assert lreg == AMD64.rax : "left register must be rax"; - assert rreg != AMD64.rdx : "right register must not be rdx"; - - moveRegs(lreg, AMD64.rax); - - Label continuation = new Label(); - - if (GraalOptions.GenSpecialDivChecks && code == LIROpcode.Ldiv) { - // check for special case of Long.MIN_VALUE / -1 - Label normalCase = new Label(); - masm.movq(AMD64.rdx, java.lang.Long.MIN_VALUE); - masm.cmpq(AMD64.rax, AMD64.rdx); - masm.jcc(ConditionFlag.notEqual, normalCase); - masm.cmpl(rreg, -1); - masm.jcc(ConditionFlag.equal, continuation); - - // handle normal case - masm.bind(normalCase); - } - masm.cdqq(); - int offset = masm.codeBuffer.position(); - masm.idivq(rreg); - - // normal and special case exit - masm.bind(continuation); - - tasm.recordImplicitException(offset, info); - if (code == LIROpcode.Lrem) { - moveRegs(AMD64.rdx, dreg); - } else { - assert code == LIROpcode.Ldiv; - moveRegs(AMD64.rax, dreg); - } - } - - void arithmeticWdiv(LIROpcode code, CiValue left, CiValue right, CiValue result, LIRDebugInfo info) { - assert left.isRegister() : "left must be register"; - assert right.isRegister() : "right must be register"; - assert result.isRegister() : "result must be register"; - - CiRegister lreg = left.asRegister(); - CiRegister dreg = result.asRegister(); - CiRegister rreg = right.asRegister(); - assert lreg == AMD64.rax : "left register must be rax"; - assert rreg != AMD64.rdx : "right register must not be rdx"; - - // Must zero the high 64-bit word (in RDX) of the dividend - masm.xorq(AMD64.rdx, AMD64.rdx); - - if (code == LIROpcode.Wdivi || code == LIROpcode.Wremi) { - // Zero the high 32 bits of the divisor - masm.movzxd(rreg, rreg); - } - - moveRegs(lreg, AMD64.rax); - - int offset = masm.codeBuffer.position(); - masm.divq(rreg); - - tasm.recordImplicitException(offset, info); - if (code == LIROpcode.Wrem || code == LIROpcode.Wremi) { - moveRegs(AMD64.rdx, dreg); - } else { - assert code == LIROpcode.Wdiv || code == LIROpcode.Wdivi; - moveRegs(AMD64.rax, dreg); - } - } - - @Override - protected void emitCompare(Condition condition, CiValue opr1, CiValue opr2, LIROp2 op) { - // Checkstyle: off - assert Util.archKindsEqual(opr1.kind.stackKind(), opr2.kind.stackKind()) || (opr1.kind == CiKind.Word && opr2.kind == CiKind.Int) : "nonmatching stack kinds (" + condition + "): " + opr1.kind.stackKind() + "==" + opr2.kind.stackKind(); - - if (opr1.isConstant()) { - // Use scratch register - CiValue newOpr1 = compilation.registerConfig.getScratchRegister().asValue(opr1.kind); - const2reg(opr1, newOpr1, null); - opr1 = newOpr1; - } - - if (opr1.isRegister()) { - CiRegister reg1 = opr1.asRegister(); - if (opr2.isRegister()) { - // register - register - switch (opr1.kind) { - case Boolean : - case Byte : - case Char : - case Short : - case Int : masm.cmpl(reg1, opr2.asRegister()); break; - case Long : - case Word : - case Object : masm.cmpq(reg1, opr2.asRegister()); break; - case Float : masm.ucomiss(reg1, asXmmFloatReg(opr2)); break; - case Double : masm.ucomisd(reg1, asXmmDoubleReg(opr2)); break; - default : throw Util.shouldNotReachHere(opr1.kind.toString()); - } - } else if (opr2.isStackSlot()) { - // register - stack - CiStackSlot opr2Slot = (CiStackSlot) opr2; - switch (opr1.kind) { - case Boolean : - case Byte : - case Char : - case Short : - case Int : masm.cmpl(reg1, frameMap.toStackAddress(opr2Slot)); break; - case Long : - case Word : - case Object : masm.cmpptr(reg1, frameMap.toStackAddress(opr2Slot)); break; - case Float : masm.ucomiss(reg1, frameMap.toStackAddress(opr2Slot)); break; - case Double : masm.ucomisd(reg1, frameMap.toStackAddress(opr2Slot)); break; - default : throw Util.shouldNotReachHere(); - } - } else if (opr2.isConstant()) { - // register - constant - CiConstant c = (CiConstant) opr2; - switch (opr1.kind) { - case Boolean : - case Byte : - case Char : - case Short : - case Int : masm.cmpl(reg1, c.asInt()); break; - case Float : masm.ucomiss(reg1, tasm.recordDataReferenceInCode(CiConstant.forFloat(((CiConstant) opr2).asFloat()))); break; - case Double : masm.ucomisd(reg1, tasm.recordDataReferenceInCode(CiConstant.forDouble(((CiConstant) opr2).asDouble()))); break; - case Long : - case Word : { - if (NumUtil.isInt(c.asLong())) { - masm.cmpq(reg1, (int) c.asLong()); - } else { - masm.movq(rscratch1, c.asLong()); - masm.cmpq(reg1, rscratch1); - - } - break; - } - case Object : { - movoop(rscratch1, c); - masm.cmpq(reg1, rscratch1); - break; - } - default : throw Util.shouldNotReachHere(); - } - } else { - throw Util.shouldNotReachHere(); - } - } else if (opr1.isStackSlot()) { - CiAddress left = asAddress(opr1); - if (opr2.isConstant()) { - CiConstant right = (CiConstant) opr2; - // stack - constant - switch (opr1.kind) { - case Boolean : - case Byte : - case Char : - case Short : - case Int : masm.cmpl(left, right.asInt()); break; - case Long : - case Word : if (NumUtil.isInt(right.asLong())) { - masm.cmpq(left, (int) right.asLong()); - } else { - masm.movq(rscratch1, right.asLong()); - masm.cmpq(left, rscratch1); - - } - break; - case Object : if (right.isNull()) { - masm.cmpq(left, 0); - } else { - movoop(rscratch1, right); - masm.cmpq(left, rscratch1); - } - break; - default : throw Util.shouldNotReachHere(); - } - } else { - throw Util.shouldNotReachHere("opr1=" + opr1.toString() + " opr2=" + opr2); - } - - } else { - throw Util.shouldNotReachHere("opr1=" + opr1.toString() + " opr2=" + opr2); - } - // Checkstyle: on - } - - @Override - protected void emitCompare2Int(LIROpcode code, CiValue left, CiValue right, CiValue dst, LIROp2 op) { - if (code == LIROpcode.Cmpfd2i || code == LIROpcode.Ucmpfd2i) { - if (left.kind.isFloat()) { - masm.cmpss2int(asXmmFloatReg(left), asXmmFloatReg(right), dst.asRegister(), code == LIROpcode.Ucmpfd2i); - } else if (left.kind.isDouble()) { - masm.cmpsd2int(asXmmDoubleReg(left), asXmmDoubleReg(right), dst.asRegister(), code == LIROpcode.Ucmpfd2i); - } else { - assert false : "no fpu stack"; - } - } else { - assert code == LIROpcode.Cmpl2i; - CiRegister dest = dst.asRegister(); - Label high = new Label(); - Label done = new Label(); - Label isEqual = new Label(); - masm.cmpptr(left.asRegister(), right.asRegister()); - masm.jcc(ConditionFlag.equal, isEqual); - masm.jcc(ConditionFlag.greater, high); - masm.xorptr(dest, dest); - masm.decrementl(dest, 1); - masm.jmp(done); - masm.bind(high); - masm.xorptr(dest, dest); - masm.incrementl(dest, 1); - masm.jmp(done); - masm.bind(isEqual); - masm.xorptr(dest, dest); - masm.bind(done); - } - } - - @Override - protected void emitCallAlignment(LIROpcode code) { - if (GraalOptions.AlignCallsForPatching) { - // make sure that the displacement word of the call ends up word aligned - int offset = masm.codeBuffer.position(); - offset += compilation.target.arch.machineCodeCallDisplacementOffset; - while (offset++ % wordSize != 0) { - masm.nop(); - } - } - } - - @Override - protected void emitIndirectCall(Object target, LIRDebugInfo info, CiValue callAddress) { - CiRegister reg = rscratch1; - if (callAddress.isRegister()) { - reg = callAddress.asRegister(); - } else { - moveOp(callAddress, reg.asValue(callAddress.kind), callAddress.kind, null, false); - } - indirectCall(reg, target, info); - } - - @Override - protected void emitDirectCall(Object target, LIRDebugInfo info) { - directCall(target, info); - } - - @Override - protected void emitNativeCall(String symbol, LIRDebugInfo info, CiValue callAddress) { - CiRegister reg = rscratch1; - if (callAddress.isRegister()) { - reg = callAddress.asRegister(); - } else { - moveOp(callAddress, reg.asValue(callAddress.kind), callAddress.kind, null, false); - } - indirectCall(reg, symbol, info); - } - - @Override - protected void emitTemplateCall(CiValue address) { - if (address == null) { - directCall(null, null); - return; - } - - CiRegister reg = rscratch1; - if (address.isRegister()) { - reg = address.asRegister(); - } else { - moveOp(address, reg.asValue(address.kind), address.kind, null, false); - } - indirectCall(reg, null, null); - } - - private void emitXIRShiftOp(LIROpcode code, CiValue left, CiValue count, CiValue dest) { - if (count.isConstant()) { - emitShiftOp(code, left, ((CiConstant) count).asInt(), dest); - } else { - emitShiftOp(code, left, count, dest, IllegalValue); - } - } - - @Override - protected void emitShiftOp(LIROpcode code, CiValue left, CiValue count, CiValue dest, CiValue tmp) { - // optimized version for linear scan: - // * count must be already in ECX (guaranteed by LinearScan) - // * left and dest must be equal - // * tmp must be unused - assert count.asRegister() == SHIFTCount : "count must be in ECX"; - assert left == dest : "left and dest must be equal"; - assert tmp.isIllegal() : "wasting a register if tmp is allocated"; - assert left.isRegister(); - - if (left.kind.isInt()) { - CiRegister value = left.asRegister(); - assert value != SHIFTCount : "left cannot be ECX"; - - // Checkstyle: off - switch (code) { - case Shl : masm.shll(value); break; - case Shr : masm.sarl(value); break; - case Ushr : masm.shrl(value); break; - default : throw Util.shouldNotReachHere(); - } - } else { - CiRegister lreg = left.asRegister(); - assert lreg != SHIFTCount : "left cannot be ECX"; - - switch (code) { - case Shl : masm.shlq(lreg); break; - case Shr : masm.sarq(lreg); break; - case Ushr : masm.shrq(lreg); break; - default : throw Util.shouldNotReachHere(); - } - // Checkstyle: on - } - } - - @Override - protected void emitShiftOp(LIROpcode code, CiValue left, int count, CiValue dest) { - assert dest.isRegister(); - if (dest.kind.isInt()) { - // first move left into dest so that left is not destroyed by the shift - CiRegister value = dest.asRegister(); - count = count & 0x1F; // Java spec - - moveRegs(left.asRegister(), value); - // Checkstyle: off - switch (code) { - case Shl : masm.shll(value, count); break; - case Shr : masm.sarl(value, count); break; - case Ushr : masm.shrl(value, count); break; - default : throw Util.shouldNotReachHere(); - } - } else { - - // first move left into dest so that left is not destroyed by the shift - CiRegister value = dest.asRegister(); - count = count & 0x1F; // Java spec - - moveRegs(left.asRegister(), value); - switch (code) { - case Shl : masm.shlq(value, count); break; - case Shr : masm.sarq(value, count); break; - case Ushr : masm.shrq(value, count); break; - default : throw Util.shouldNotReachHere(); - } - // Checkstyle: on - } - } - - @Override - protected void emitSignificantBitOp(boolean most, CiValue src, CiValue dst) { - assert dst.isRegister(); - CiRegister result = dst.asRegister(); - masm.xorq(result, result); - masm.notq(result); - if (src.isRegister()) { - CiRegister value = src.asRegister(); - assert value != result; - if (most) { - masm.bsrq(result, value); - } else { - masm.bsfq(result, value); - } - } else { - CiAddress laddr = asAddress(src); - if (most) { - masm.bsrq(result, laddr); - } else { - masm.bsfq(result, laddr); - } - } - } - - @Override - protected void emitAlignment() { - masm.align(wordSize); - } - - @Override - protected void emitNegate(LIRNegate op) { - CiValue left = op.operand(); - CiValue dest = op.result(); - assert left.isRegister(); - if (left.kind.isInt()) { - masm.negl(left.asRegister()); - moveRegs(left.asRegister(), dest.asRegister()); - - } else if (dest.kind.isFloat()) { - if (asXmmFloatReg(left) != asXmmFloatReg(dest)) { - masm.movflt(asXmmFloatReg(dest), asXmmFloatReg(left)); - } - masm.xorps(asXmmFloatReg(dest), tasm.recordDataReferenceInCode(CiConstant.forLong(0x8000000080000000L))); - } else if (dest.kind.isDouble()) { - if (asXmmDoubleReg(left) != asXmmDoubleReg(dest)) { - masm.movdbl(asXmmDoubleReg(dest), asXmmDoubleReg(left)); - } - masm.xorpd(asXmmDoubleReg(dest), tasm.recordDataReferenceInCode(CiConstant.forLong(0x8000000000000000L))); - } else { - CiRegister lreg = left.asRegister(); - CiRegister dreg = dest.asRegister(); - masm.movq(dreg, lreg); - masm.negq(dreg); - } - } - - @Override - protected void emitLea(CiValue src, CiValue dest) { - CiRegister reg = dest.asRegister(); - masm.leaq(reg, asAddress(src)); - } - - @Override - protected void emitNullCheck(CiValue src, LIRDebugInfo info) { - assert src.isRegister(); - if (GraalOptions.NullCheckUniquePc) { - masm.nop(); - } - tasm.recordImplicitException(codePos(), info); - masm.nullCheck(src.asRegister()); - } - - @Override - protected void emitVolatileMove(CiValue src, CiValue dest, CiKind kind, LIRDebugInfo info) { - assert kind == CiKind.Long : "only for volatile long fields"; - - if (info != null) { - tasm.recordImplicitException(codePos(), info); - } - - if (src.kind.isDouble()) { - if (dest.isRegister()) { - masm.movdq(dest.asRegister(), asXmmDoubleReg(src)); - } else if (dest.isStackSlot()) { - masm.movsd(frameMap.toStackAddress((CiStackSlot) dest), asXmmDoubleReg(src)); - } else { - assert dest.isAddress(); - masm.movsd((CiAddress) dest, asXmmDoubleReg(src)); - } - } else { - assert dest.kind.isDouble(); - if (src.isStackSlot()) { - masm.movdbl(asXmmDoubleReg(dest), frameMap.toStackAddress((CiStackSlot) src)); - } else { - assert src.isAddress(); - masm.movdbl(asXmmDoubleReg(dest), (CiAddress) src); - } - } - } - - private static CiRegister asXmmDoubleReg(CiValue dest) { - assert dest.kind.isDouble() : "must be double XMM register"; - CiRegister result = dest.asRegister(); - assert result.isFpu() : "must be XMM register"; - return result; - } - - @Override - protected void emitMemoryBarriers(int barriers) { - masm.membar(barriers); - } - - @Override - protected void doPeephole(LIRList list) { - // Do nothing for now - } - - @Override - protected void emitXir(LIRXirInstruction instruction) { - XirSnippet snippet = instruction.snippet; - - - Label endLabel = null; - Label[] labels = new Label[snippet.template.labels.length]; - for (int i = 0; i < labels.length; i++) { - labels[i] = new Label(); - if (snippet.template.labels[i].name == XirLabel.TrueSuccessor) { - if (instruction.trueSuccessor() == null) { - assert endLabel == null; - endLabel = new Label(); - labels[i] = endLabel; - } else { - labels[i] = instruction.trueSuccessor().label; - } - } else if (snippet.template.labels[i].name == XirLabel.FalseSuccessor) { - if (instruction.falseSuccessor() == null) { - assert endLabel == null; - endLabel = new Label(); - labels[i] = endLabel; - } else { - labels[i] = instruction.falseSuccessor().label; - } - } - } - emitXirInstructions(instruction, snippet.template.fastPath, labels, instruction.getOperands(), snippet.marks); - if (endLabel != null) { - masm.bind(endLabel); - } - - if (snippet.template.slowPath != null) { - addSlowPath(new SlowPath(instruction, labels, snippet.marks)); - } - } - - @Override - protected void emitSlowPath(SlowPath sp) { - int start = -1; - if (GraalOptions.TraceAssembler) { - TTY.println("Emitting slow path for XIR instruction " + sp.instruction.snippet.template.name); - start = masm.codeBuffer.position(); - } - emitXirInstructions(sp.instruction, sp.instruction.snippet.template.slowPath, sp.labels, sp.instruction.getOperands(), sp.marks); - masm.nop(); - if (GraalOptions.TraceAssembler) { - TTY.println("From " + start + " to " + masm.codeBuffer.position()); - } - } - - public void emitXirInstructions(LIRXirInstruction xir, XirInstruction[] instructions, Label[] labels, CiValue[] operands, Map marks) { - LIRDebugInfo info = xir == null ? null : xir.info; - LIRDebugInfo infoAfter = xir == null ? null : xir.infoAfter; - - for (XirInstruction inst : instructions) { - switch (inst.op) { - case Add: - emitArithOp(LIROpcode.Add, operands[inst.x().index], operands[inst.y().index], operands[inst.result.index], null); - break; - - case Sub: - emitArithOp(LIROpcode.Sub, operands[inst.x().index], operands[inst.y().index], operands[inst.result.index], null); - break; - - case Div: - if (inst.kind == CiKind.Int) { - arithmeticIdiv(LIROpcode.Idiv, operands[inst.x().index], operands[inst.y().index], operands[inst.result.index], null); - } else { - emitArithOp(LIROpcode.Div, operands[inst.x().index], operands[inst.y().index], operands[inst.result.index], null); - } - break; - - case Mul: - emitArithOp(LIROpcode.Mul, operands[inst.x().index], operands[inst.y().index], operands[inst.result.index], null); - break; - - case Mod: - if (inst.kind == CiKind.Int) { - arithmeticIdiv(LIROpcode.Irem, operands[inst.x().index], operands[inst.y().index], operands[inst.result.index], null); - } else { - emitArithOp(LIROpcode.Rem, operands[inst.x().index], operands[inst.y().index], operands[inst.result.index], null); - } - break; - - case Shl: - emitXIRShiftOp(LIROpcode.Shl, operands[inst.x().index], operands[inst.y().index], operands[inst.result.index]); - break; - - case Sar: - emitXIRShiftOp(LIROpcode.Shr, operands[inst.x().index], operands[inst.y().index], operands[inst.result.index]); - break; - - case Shr: - emitXIRShiftOp(LIROpcode.Ushr, operands[inst.x().index], operands[inst.y().index], operands[inst.result.index]); - break; - - case And: - emitLogicOp(LIROpcode.LogicAnd, operands[inst.x().index], operands[inst.y().index], operands[inst.result.index]); - break; - - case Or: - emitLogicOp(LIROpcode.LogicOr, operands[inst.x().index], operands[inst.y().index], operands[inst.result.index]); - break; - - case Xor: - emitLogicOp(LIROpcode.LogicXor, operands[inst.x().index], operands[inst.y().index], operands[inst.result.index]); - break; - - case Mov: { - CiValue result = operands[inst.result.index]; - CiValue source = operands[inst.x().index]; - moveOp(source, result, result.kind, null, false); - break; - } - - case PointerLoad: { - if ((Boolean) inst.extra && info != null) { - tasm.recordImplicitException(codePos(), info); - } - - CiValue result = operands[inst.result.index]; - CiValue pointer = operands[inst.x().index]; - CiRegisterValue register = assureInRegister(pointer); - moveOp(new CiAddress(inst.kind, register, 0), result, inst.kind, null, false); - break; - } - - case PointerStore: { - if ((Boolean) inst.extra && info != null) { - tasm.recordImplicitException(codePos(), info); - } - - CiValue value = operands[inst.y().index]; - CiValue pointer = operands[inst.x().index]; - assert pointer.isVariableOrRegister(); - moveOp(value, new CiAddress(inst.kind, pointer, 0), inst.kind, null, false); - break; - } - - case PointerLoadDisp: { - CiXirAssembler.AddressAccessInformation addressInformation = (CiXirAssembler.AddressAccessInformation) inst.extra; - boolean canTrap = addressInformation.canTrap; - - CiAddress.Scale scale = addressInformation.scale; - int displacement = addressInformation.disp; - - CiValue result = operands[inst.result.index]; - CiValue pointer = operands[inst.x().index]; - CiValue index = operands[inst.y().index]; - - pointer = assureInRegister(pointer); - assert pointer.isVariableOrRegister(); - - CiValue src = null; - if (index.isConstant()) { - assert index.kind == CiKind.Int; - CiConstant constantIndex = (CiConstant) index; - src = new CiAddress(inst.kind, pointer, constantIndex.asInt() * scale.value + displacement); - } else { - src = new CiAddress(inst.kind, pointer, index, scale, displacement); - } - - moveOp(src, result, inst.kind, canTrap ? info : null, false); - break; - } - - case LoadEffectiveAddress: { - CiXirAssembler.AddressAccessInformation addressInformation = (CiXirAssembler.AddressAccessInformation) inst.extra; - - CiAddress.Scale scale = addressInformation.scale; - int displacement = addressInformation.disp; - - CiValue result = operands[inst.result.index]; - CiValue pointer = operands[inst.x().index]; - CiValue index = operands[inst.y().index]; - - pointer = assureInRegister(pointer); - assert pointer.isVariableOrRegister(); - CiValue src = new CiAddress(CiKind.Illegal, pointer, index, scale, displacement); - emitLea(src, result); - break; - } - - case PointerStoreDisp: { - CiXirAssembler.AddressAccessInformation addressInformation = (CiXirAssembler.AddressAccessInformation) inst.extra; - boolean canTrap = addressInformation.canTrap; - - CiAddress.Scale scale = addressInformation.scale; - int displacement = addressInformation.disp; - - CiValue value = operands[inst.z().index]; - CiValue pointer = operands[inst.x().index]; - CiValue index = operands[inst.y().index]; - - pointer = assureInRegister(pointer); - assert pointer.isVariableOrRegister(); - - CiValue dst; - if (index.isConstant()) { - assert index.kind == CiKind.Int; - CiConstant constantIndex = (CiConstant) index; - dst = new CiAddress(inst.kind, pointer, IllegalValue, scale, constantIndex.asInt() * scale.value + displacement); - } else { - dst = new CiAddress(inst.kind, pointer, index, scale, displacement); - } - - moveOp(value, dst, inst.kind, canTrap ? info : null, false); - break; - } - - case RepeatMoveBytes: - assert operands[inst.x().index].asRegister().equals(AMD64.rsi) : "wrong input x: " + operands[inst.x().index]; - assert operands[inst.y().index].asRegister().equals(AMD64.rdi) : "wrong input y: " + operands[inst.y().index]; - assert operands[inst.z().index].asRegister().equals(AMD64.rcx) : "wrong input z: " + operands[inst.z().index]; - masm.repeatMoveBytes(); - break; - - case RepeatMoveWords: - assert operands[inst.x().index].asRegister().equals(AMD64.rsi) : "wrong input x: " + operands[inst.x().index]; - assert operands[inst.y().index].asRegister().equals(AMD64.rdi) : "wrong input y: " + operands[inst.y().index]; - assert operands[inst.z().index].asRegister().equals(AMD64.rcx) : "wrong input z: " + operands[inst.z().index]; - masm.repeatMoveWords(); - break; - - case PointerCAS: - - if ((Boolean) inst.extra && info != null) { - tasm.recordImplicitException(codePos(), info); - } - assert operands[inst.x().index].asRegister().equals(AMD64.rax) : "wrong input x: " + operands[inst.x().index]; - - CiValue exchangedVal = operands[inst.y().index]; - CiValue exchangedAddress = operands[inst.x().index]; - CiRegisterValue pointerRegister = assureInRegister(exchangedAddress); - CiAddress addr = new CiAddress(CiKind.Word, pointerRegister); - masm.cmpxchgq(exchangedVal.asRegister(), addr); - - break; - - case CallStub: { - XirTemplate stubId = (XirTemplate) inst.extra; - CiRegister result = CiRegister.None; - if (inst.result != null) { - result = operands[inst.result.index].asRegister(); - } - CiValue[] args = new CiValue[inst.arguments.length]; - for (int i = 0; i < args.length; i++) { - args[i] = operands[inst.arguments[i].index]; - } - callGlobalStub(stubId, info, result, args); - break; - } - case CallRuntime: { - CiKind[] signature = new CiKind[inst.arguments.length]; - for (int i = 0; i < signature.length; i++) { - signature[i] = inst.arguments[i].kind; - } - - CiCallingConvention cc = frameMap.getCallingConvention(signature, RuntimeCall); - for (int i = 0; i < inst.arguments.length; i++) { - CiValue argumentLocation = cc.locations[i]; - CiValue argumentSourceLocation = operands[inst.arguments[i].index]; - if (argumentLocation != argumentSourceLocation) { - moveOp(argumentSourceLocation, argumentLocation, argumentLocation.kind, null, false); - } - } - - RuntimeCallInformation runtimeCallInformation = (RuntimeCallInformation) inst.extra; - directCall(runtimeCallInformation.target, (runtimeCallInformation.useInfoAfter) ? infoAfter : info); - - if (inst.result != null && inst.result.kind != CiKind.Illegal && inst.result.kind != CiKind.Void) { - CiRegister returnRegister = compilation.registerConfig.getReturnRegister(inst.result.kind); - CiValue resultLocation = returnRegister.asValue(inst.result.kind.stackKind()); - moveOp(resultLocation, operands[inst.result.index], inst.result.kind.stackKind(), null, false); - } - break; - } - case Jmp: { - if (inst.extra instanceof XirLabel) { - Label label = labels[((XirLabel) inst.extra).index]; - masm.jmp(label); - } else { - directJmp(inst.extra); - } - break; - } - case DecAndJumpNotZero: { - Label label = labels[((XirLabel) inst.extra).index]; - CiValue value = operands[inst.x().index]; - if (value.kind == CiKind.Long) { - masm.decq(value.asRegister()); - } else { - assert value.kind == CiKind.Int; - masm.decl(value.asRegister()); - } - masm.jcc(ConditionFlag.notZero, label); - break; - } - case Jeq: { - Label label = labels[((XirLabel) inst.extra).index]; - emitXirCompare(inst, Condition.EQ, ConditionFlag.equal, operands, label); - break; - } - case Jneq: { - Label label = labels[((XirLabel) inst.extra).index]; - emitXirCompare(inst, Condition.NE, ConditionFlag.notEqual, operands, label); - break; - } - - case Jgt: { - Label label = labels[((XirLabel) inst.extra).index]; - emitXirCompare(inst, Condition.GT, ConditionFlag.greater, operands, label); - break; - } - - case Jgteq: { - Label label = labels[((XirLabel) inst.extra).index]; - emitXirCompare(inst, Condition.GE, ConditionFlag.greaterEqual, operands, label); - break; - } - - case Jugteq: { - Label label = labels[((XirLabel) inst.extra).index]; - emitXirCompare(inst, Condition.AE, ConditionFlag.aboveEqual, operands, label); - break; - } - - case Jlt: { - Label label = labels[((XirLabel) inst.extra).index]; - emitXirCompare(inst, Condition.LT, ConditionFlag.less, operands, label); - break; - } - - case Jlteq: { - Label label = labels[((XirLabel) inst.extra).index]; - emitXirCompare(inst, Condition.LE, ConditionFlag.lessEqual, operands, label); - break; - } - - case Jbset: { - Label label = labels[((XirLabel) inst.extra).index]; - CiValue pointer = operands[inst.x().index]; - CiValue offset = operands[inst.y().index]; - CiValue bit = operands[inst.z().index]; - assert offset.isConstant() && bit.isConstant(); - CiConstant constantOffset = (CiConstant) offset; - CiConstant constantBit = (CiConstant) bit; - CiAddress src = new CiAddress(inst.kind, pointer, constantOffset.asInt()); - masm.btli(src, constantBit.asInt()); - masm.jcc(ConditionFlag.aboveEqual, label); - break; - } - - case Bind: { - XirLabel l = (XirLabel) inst.extra; - Label label = labels[l.index]; - asm.bind(label); - break; - } - case Safepoint: { - assert info != null : "Must have debug info in order to create a safepoint."; - tasm.recordSafepoint(codePos(), info); - break; - } - case NullCheck: { - tasm.recordImplicitException(codePos(), info); - CiValue pointer = operands[inst.x().index]; - masm.nullCheck(pointer.asRegister()); - break; - } - case Align: { - masm.align((Integer) inst.extra); - break; - } - case StackOverflowCheck: { - int frameSize = initialFrameSizeInBytes(); - int lastFramePage = frameSize / target.pageSize; - // emit multiple stack bangs for methods with frames larger than a page - for (int i = 0; i <= lastFramePage; i++) { - int offset = (i + GraalOptions.StackShadowPages) * target.pageSize; - // Deduct 'frameSize' to handle frames larger than the shadow - bangStackWithOffset(offset - frameSize); - } - break; - } - case PushFrame: { - int frameSize = initialFrameSizeInBytes(); - masm.decrementq(AMD64.rsp, frameSize); // does not emit code for frameSize == 0 - if (GraalOptions.ZapStackOnMethodEntry) { - final int intSize = 4; - for (int i = 0; i < frameSize / intSize; ++i) { - masm.movl(new CiAddress(CiKind.Int, AMD64.rsp.asValue(), i * intSize), 0xC1C1C1C1); - } - } - CiCalleeSaveLayout csa = compilation.registerConfig.getCalleeSaveLayout(); - if (csa.size != 0) { - int frameToCSA = frameMap.offsetToCalleeSaveAreaStart(); - assert frameToCSA >= 0; - masm.save(csa, frameToCSA); - } - break; - } - case PopFrame: { - int frameSize = initialFrameSizeInBytes(); - - CiCalleeSaveLayout csa = compilation.registerConfig.getCalleeSaveLayout(); - if (csa.size != 0) { - registerRestoreEpilogueOffset = masm.codeBuffer.position(); - // saved all registers, restore all registers - int frameToCSA = frameMap.offsetToCalleeSaveAreaStart(); - masm.restore(csa, frameToCSA); - } - - masm.incrementq(AMD64.rsp, frameSize); - break; - } - case Push: { - CiRegisterValue value = assureInRegister(operands[inst.x().index]); - masm.push(value.asRegister()); - break; - } - case Pop: { - CiValue result = operands[inst.result.index]; - if (result.isRegister()) { - masm.pop(result.asRegister()); - } else { - masm.pop(rscratch1); - moveOp(rscratch1.asValue(), result, result.kind, null, true); - } - break; - } - case Mark: { - XirMark xmark = (XirMark) inst.extra; - Mark[] references = new Mark[xmark.references.length]; - for (int i = 0; i < references.length; i++) { - references[i] = marks.get(xmark.references[i]); - assert references[i] != null; - } - Mark mark = tasm.recordMark(xmark.id, references); - marks.put(xmark, mark); - break; - } - case Nop: { - for (int i = 0; i < (Integer) inst.extra; i++) { - masm.nop(); - } - break; - } - case RawBytes: { - for (byte b : (byte[]) inst.extra) { - masm.codeBuffer.emitByte(b & 0xff); - } - break; - } - case ShouldNotReachHere: { - if (inst.extra == null) { - stop("should not reach here"); - } else { - stop("should not reach here: " + inst.extra); - } - break; - } - default: - assert false : "Unknown XIR operation " + inst.op; - } - } - } - - /** - * @param offset the offset RSP at which to bang. Note that this offset is relative to RSP after RSP has been - * adjusted to allocated the frame for the method. It denotes an offset "down" the stack. - * For very large frames, this means that the offset may actually be negative (i.e. denoting - * a slot "up" the stack above RSP). - */ - private void bangStackWithOffset(int offset) { - masm.movq(new CiAddress(CiKind.Word, AMD64.RSP, -offset), AMD64.rax); - } - - private CiRegisterValue assureInRegister(CiValue pointer) { - if (pointer.isConstant()) { - CiRegisterValue register = rscratch1.asValue(pointer.kind); - moveOp(pointer, register, pointer.kind, null, false); - return register; - } - - assert pointer.isRegister() : "should be register, but is: " + pointer; - return (CiRegisterValue) pointer; - } - - private void emitXirCompare(XirInstruction inst, Condition condition, ConditionFlag cflag, CiValue[] ops, Label label) { - CiValue x = ops[inst.x().index]; - CiValue y = ops[inst.y().index]; - emitCompare(condition, x, y, null); - masm.jcc(cflag, label); - } - - @Override - public void emitDeoptizationStub(DeoptimizationStub stub) { - masm.bind(stub.label); - int code; - switch(stub.action) { - case None: - code = 0; - break; - case Recompile: - code = 1; - break; - case InvalidateReprofile: - code = 2; - break; - case InvalidateRecompile: - code = 3; - break; - case InvalidateStopCompiling: - code = 4; - break; - default: - throw Util.shouldNotReachHere(); - } - if (code == 0) { - throw new RuntimeException(); - } - masm.movq(rscratch1, code); - directCall(CiRuntimeCall.Deoptimize, stub.info); - shouldNotReachHere(); - } - - public GlobalStub lookupGlobalStub(XirTemplate template) { - return compilation.compiler.lookupGlobalStub(template); - } - - public void callGlobalStub(XirTemplate stub, LIRDebugInfo info, CiRegister result, CiValue... args) { - callGlobalStubHelper(lookupGlobalStub(stub), stub.resultOperand.kind, info, result, args); - } - - public void callGlobalStub(GlobalStub stub, LIRDebugInfo info, CiRegister result, CiValue... args) { - callGlobalStubHelper(stub, stub.resultKind, info, result, args); - } - - private void callGlobalStubHelper(GlobalStub stub, CiKind resultKind, LIRDebugInfo info, CiRegister result, CiValue... args) { - assert args.length == stub.argOffsets.length; - - for (int i = 0; i < args.length; i++) { - storeParameter(args[i], stub.argOffsets[i]); - } - - directCall(stub.stubObject, info); - - if (result != CiRegister.None) { - loadResult(result, stub.resultOffset, resultKind); - } - - // Clear out parameters - if (GraalOptions.GenAssertionCode) { - for (int i = 0; i < args.length; i++) { - masm.movptr(new CiAddress(CiKind.Word, AMD64.RSP, stub.argOffsets[i]), 0); - } - } - } - - private void loadResult(CiRegister r, int offset, CiKind kind) { - if (kind == CiKind.Int || kind == CiKind.Boolean) { - masm.movl(r, new CiAddress(CiKind.Int, AMD64.RSP, offset)); - } else if (kind == CiKind.Float) { - masm.movss(r, new CiAddress(CiKind.Float, AMD64.RSP, offset)); - } else if (kind == CiKind.Double) { - masm.movsd(r, new CiAddress(CiKind.Double, AMD64.RSP, offset)); - } else { - masm.movq(r, new CiAddress(CiKind.Word, AMD64.RSP, offset)); - } - } - - private void storeParameter(CiValue registerOrConstant, int offset) { - CiKind k = registerOrConstant.kind; - if (registerOrConstant.isConstant()) { - CiConstant c = (CiConstant) registerOrConstant; - if (c.kind == CiKind.Object) { - movoop(new CiAddress(CiKind.Word, AMD64.RSP, offset), c); - } else { - masm.movptr(new CiAddress(CiKind.Word, AMD64.RSP, offset), c.asInt()); - } - } else if (registerOrConstant.isRegister()) { - if (k.isFloat()) { - masm.movss(new CiAddress(CiKind.Float, AMD64.RSP, offset), registerOrConstant.asRegister()); - } else if (k.isDouble()) { - masm.movsd(new CiAddress(CiKind.Double, AMD64.RSP, offset), registerOrConstant.asRegister()); - } else { - masm.movq(new CiAddress(CiKind.Word, AMD64.RSP, offset), registerOrConstant.asRegister()); - } - } else { - throw new InternalError("should not reach here"); - } - } - - public void movoop(CiRegister dst, CiConstant obj) { - assert obj.kind == CiKind.Object; - if (obj.isNull()) { - masm.xorq(dst, dst); - } else { - if (target.inlineObjects) { - tasm.recordDataReferenceInCode(obj); - masm.movq(dst, 0xDEADDEADDEADDEADL); - } else { - masm.movq(dst, tasm.recordDataReferenceInCode(obj)); - } - } - } - - public void movoop(CiAddress dst, CiConstant obj) { - movoop(rscratch1, obj); - masm.movq(dst, rscratch1); - } - - public void directCall(Object target, LIRDebugInfo info) { - int before = masm.codeBuffer.position(); - masm.call(); - int after = masm.codeBuffer.position(); - tasm.recordDirectCall(before, after, target, info); - tasm.recordExceptionHandlers(after, info); - } - - public void directJmp(Object target) { - int before = masm.codeBuffer.position(); - masm.jmp(0, true); - int after = masm.codeBuffer.position(); - tasm.recordDirectCall(before, after, target, null); - } - - public void indirectCall(CiRegister dst, Object target, LIRDebugInfo info) { - int before = masm.codeBuffer.position(); - masm.call(dst); - int after = masm.codeBuffer.position(); - tasm.recordIndirectCall(before, after, target, info); - tasm.recordExceptionHandlers(after, info); - } - - @Override - public boolean falseOnUnordered(Condition condition) { - switch(condition) { - case AE: - case NE: - case GT: - case AT: - return true; - case EQ: - case LE: - case BE: - case BT: - case LT: - case GE: - case OF: - case NOF: - return false; - default: - throw Util.shouldNotReachHere(); - } - } - - @Override - public boolean trueOnUnordered(Condition condition) { - switch(condition) { - case AE: - case NE: - case GT: - case AT: - return false; - case EQ: - case LE: - case BE: - case BT: - return true; - case LT: - case GE: - case OF: - case NOF: - return false; - default: - throw Util.shouldNotReachHere(); - } - } - - protected void stop(String msg) { - if (GraalOptions.GenAssertionCode) { - // TODO: pass a pointer to the message - directCall(CiRuntimeCall.Debug, null); - masm.hlt(); - } - } - - public void shouldNotReachHere() { - stop("should not reach here"); - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64LIRGenerator.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64LIRGenerator.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,515 +0,0 @@ -/* - * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package com.oracle.max.graal.compiler.target.amd64; - -import com.oracle.max.asm.*; -import com.oracle.max.asm.target.amd64.*; -import com.oracle.max.graal.compiler.*; -import com.oracle.max.graal.compiler.gen.*; -import com.oracle.max.graal.compiler.globalstub.*; -import com.oracle.max.graal.compiler.lir.*; -import com.oracle.max.graal.compiler.util.*; -import com.oracle.max.graal.nodes.*; -import com.oracle.max.graal.nodes.calc.*; -import com.oracle.max.graal.nodes.extended.*; -import com.oracle.max.graal.nodes.java.*; -import com.sun.cri.bytecode.*; -import com.sun.cri.ci.*; - -/** - * This class implements the X86-specific portion of the LIR generator. - */ -public class AMD64LIRGenerator extends LIRGenerator { - - private static final CiRegisterValue RAX_I = AMD64.rax.asValue(CiKind.Int); - private static final CiRegisterValue RAX_L = AMD64.rax.asValue(CiKind.Long); - private static final CiRegisterValue RAX_W = AMD64.rax.asValue(CiKind.Word); - private static final CiRegisterValue RDX_I = AMD64.rdx.asValue(CiKind.Int); - private static final CiRegisterValue RDX_L = AMD64.rdx.asValue(CiKind.Long); - - private static final CiRegisterValue LDIV_TMP = RDX_L; - - - /** - * The register in which MUL puts the result for 64-bit multiplication. - */ - private static final CiRegisterValue LMUL_OUT = RAX_L; - - private static final CiRegisterValue SHIFT_COUNT_IN = AMD64.rcx.asValue(CiKind.Int); - - protected static final CiValue ILLEGAL = CiValue.IllegalValue; - - public AMD64LIRGenerator(GraalCompilation compilation) { - super(compilation); - } - - @Override - protected boolean canStoreAsConstant(ValueNode v, CiKind kind) { - if (kind == CiKind.Short || kind == CiKind.Char) { - // there is no immediate move of word values in asemblerI486.?pp - return false; - } - return v instanceof ConstantNode; - } - - @Override - public boolean canInlineAsConstant(ValueNode v) { - if (!v.isConstant()) { - return false; - } - if (v.kind == CiKind.Long) { - return NumUtil.isInt(v.asConstant().asLong()); - } - return v.kind != CiKind.Object || v.isNullConstant(); - } - - @Override - protected CiAddress genAddress(CiValue base, CiValue index, int shift, int disp, CiKind kind) { - assert base.isVariableOrRegister(); - if (index.isConstant()) { - return new CiAddress(kind, base, (((CiConstant) index).asInt() << shift) + disp); - } else { - assert index.isVariableOrRegister(); - return new CiAddress(kind, base, (index), CiAddress.Scale.fromShift(shift), disp); - } - } - - @Override - protected void genCmpMemInt(Condition condition, CiValue base, int disp, int c, LIRDebugInfo info) { - lir.cmpMemInt(condition, base, disp, c, info); - } - - @Override - protected void genCmpRegMem(Condition condition, CiValue reg, CiValue base, int disp, CiKind kind, LIRDebugInfo info) { - lir.cmpRegMem(condition, reg, new CiAddress(kind, base, disp), info); - } - - @Override - protected boolean strengthReduceMultiply(CiValue left, int c, CiValue result, CiValue tmp) { - if (tmp.isLegal()) { - if (CiUtil.isPowerOf2(c + 1)) { - lir.move(left, tmp); - lir.shiftLeft(left, CiUtil.log2(c + 1), left); - lir.sub(left, tmp, result); - return true; - } else if (CiUtil.isPowerOf2(c - 1)) { - lir.move(left, tmp); - lir.shiftLeft(left, CiUtil.log2(c - 1), left); - lir.add(left, tmp, result); - return true; - } - } - return false; - } - - @Override - public void visitNegate(NegateNode x) { - LIRItem value = new LIRItem(x.x(), this); - value.setDestroysRegister(); - value.loadItem(); - CiVariable reg = newVariable(x.kind); - lir.negate(value.result(), reg); - setResult(x, reg); - } - - public boolean livesLonger(ValueNode x, ValueNode y) { - // TODO(tw): Estimate which value will live longer. - return false; - } - - public void visitArithmeticOpFloat(ArithmeticNode x) { - LIRItem left = new LIRItem(x.x(), this); - LIRItem right = new LIRItem(x.y(), this); - assert !left.isStack() || !right.isStack() : "can't both be memory operands"; - boolean mustLoadBoth = x.opcode == Bytecodes.FREM || x.opcode == Bytecodes.DREM; - - // Both are in register, swap operands such that the short-living one is on the left side. - if (x.isCommutative() && left.isRegisterOrVariable() && right.isRegisterOrVariable()) { - if (livesLonger(x.x(), x.y())) { - LIRItem tmp = left; - left = right; - right = tmp; - } - } - - if (left.isRegisterOrVariable() || x.x().isConstant() || mustLoadBoth) { - left.loadItem(); - } - - if (mustLoadBoth) { - // frem and drem destroy also right operand, so move it to a new register - right.setDestroysRegister(); - right.loadItem(); - } else if (right.isRegisterOrVariable()) { - right.loadItem(); - } - - CiVariable reg; - - if (x.opcode == Bytecodes.FREM) { - reg = callRuntimeWithResult(CiRuntimeCall.ArithmeticFrem, null, left.result(), right.result()); - } else if (x.opcode == Bytecodes.DREM) { - reg = callRuntimeWithResult(CiRuntimeCall.ArithmeticDrem, null, left.result(), right.result()); - } else { - reg = newVariable(x.kind); - arithmeticOpFpu(x.opcode, reg, left.result(), right.result(), ILLEGAL); - } - - setResult(x, reg); - } - - public void visitArithmeticOpLong(ArithmeticNode x) { - int opcode = x.opcode; - if (opcode == Bytecodes.LDIV || opcode == Bytecodes.LREM) { - // emit inline 64-bit code - LIRDebugInfo info = stateFor(x); - CiValue dividend = force(x.x(), RAX_L); // dividend must be in RAX - CiValue divisor = load(x.y()); // divisor can be in any (other) register - - CiValue result = createResultVariable(x); - CiValue resultReg; - if (opcode == Bytecodes.LREM) { - resultReg = RDX_L; // remainder result is produced in rdx - lir.lrem(dividend, divisor, resultReg, LDIV_TMP, info); - } else { - resultReg = RAX_L; // division result is produced in rax - lir.ldiv(dividend, divisor, resultReg, LDIV_TMP, info); - } - - lir.move(resultReg, result); - } else if (opcode == Bytecodes.LMUL) { - LIRItem right = new LIRItem(x.y(), this); - - // right register is destroyed by the long mul, so it must be - // copied to a new register. - right.setDestroysRegister(); - - CiValue left = load(x.x()); - right.loadItem(); - - arithmeticOpLong(opcode, LMUL_OUT, left, right.result()); - CiValue result = createResultVariable(x); - lir.move(LMUL_OUT, result); - } else { - LIRItem right = new LIRItem(x.y(), this); - - CiValue left = load(x.x()); - // don't load constants to save register - right.loadNonconstant(); - createResultVariable(x); - arithmeticOpLong(opcode, x.operand(), left, right.result()); - } - } - - public void visitArithmeticOpInt(ArithmeticNode x) { - int opcode = x.opcode; - if (opcode == Bytecodes.IDIV || opcode == Bytecodes.IREM) { - // emit code for integer division or modulus - - // Call 'stateFor' before 'force()' because 'stateFor()' may - // force the evaluation of other instructions that are needed for - // correct debug info. Otherwise the live range of the fixed - // register might be too long. - LIRDebugInfo info = stateFor(x); - - CiValue dividend = force(x.x(), RAX_I); // dividend must be in RAX - CiValue divisor = load(x.y()); // divisor can be in any (other) register - - // idiv and irem use rdx in their implementation so the - // register allocator must not assign it to an interval that overlaps - // this division instruction. - CiRegisterValue tmp = RDX_I; - - CiValue result = createResultVariable(x); - CiValue resultReg; - if (opcode == Bytecodes.IREM) { - resultReg = tmp; // remainder result is produced in rdx - lir.irem(dividend, divisor, resultReg, tmp, info); - } else { - resultReg = RAX_I; // division result is produced in rax - lir.idiv(dividend, divisor, resultReg, tmp, info); - } - - lir.move(resultReg, result); - } else { - // emit code for other integer operations - LIRItem left = new LIRItem(x.x(), this); - LIRItem right = new LIRItem(x.y(), this); - LIRItem leftArg = left; - LIRItem rightArg = right; - if (x.isCommutative() && left.isStack() && right.isRegisterOrVariable()) { - // swap them if left is real stack (or cached) and right is real register(not cached) - leftArg = right; - rightArg = left; - } - - leftArg.loadItem(); - - // do not need to load right, as we can handle stack and constants - if (opcode == Bytecodes.IMUL) { - // check if we can use shift instead - boolean useConstant = false; - boolean useTmp = false; - if (rightArg.result().isConstant()) { - int iconst = rightArg.instruction.asConstant().asInt(); - if (iconst > 0) { - if (CiUtil.isPowerOf2(iconst)) { - useConstant = true; - } else if (CiUtil.isPowerOf2(iconst - 1) || CiUtil.isPowerOf2(iconst + 1)) { - useConstant = true; - useTmp = true; - } - } - } - if (!useConstant) { - rightArg.loadItem(); - } - CiValue tmp = ILLEGAL; - if (useTmp) { - tmp = newVariable(CiKind.Int); - } - createResultVariable(x); - - arithmeticOpInt(opcode, x.operand(), leftArg.result(), rightArg.result(), tmp); - } else { - createResultVariable(x); - CiValue tmp = ILLEGAL; - arithmeticOpInt(opcode, x.operand(), leftArg.result(), rightArg.result(), tmp); - } - } - } - - public void visitArithmeticOpWord(ArithmeticNode x) { - int opcode = x.opcode; - if (opcode == Bytecodes.WDIV || opcode == Bytecodes.WREM || opcode == Bytecodes.WDIVI || opcode == Bytecodes.WREMI) { - // emit code for long division or modulus - // emit inline 64-bit code - LIRDebugInfo info = stateFor(x); - CiValue dividend = force(x.x(), RAX_L); // dividend must be in RAX - CiValue divisor = load(x.y()); // divisor can be in any (other) register - - CiValue result = createResultVariable(x); - CiValue resultReg; - if (opcode == Bytecodes.WREM) { - resultReg = RDX_L; // remainder result is produced in rdx - lir.wrem(dividend, divisor, resultReg, LDIV_TMP, info); - } else if (opcode == Bytecodes.WREMI) { - resultReg = RDX_L; // remainder result is produced in rdx - lir.wremi(dividend, divisor, resultReg, LDIV_TMP, info); - } else if (opcode == Bytecodes.WDIV) { - resultReg = RAX_L; // division result is produced in rax - lir.wdiv(dividend, divisor, resultReg, LDIV_TMP, info); - } else { - assert opcode == Bytecodes.WDIVI; - resultReg = RAX_L; // division result is produced in rax - lir.wdivi(dividend, divisor, resultReg, LDIV_TMP, info); - } - - lir.move(resultReg, result); - } else if (opcode == Bytecodes.LMUL) { - LIRItem right = new LIRItem(x.y(), this); - - // right register is destroyed by the long mul, so it must be - // copied to a new register. - right.setDestroysRegister(); - - CiValue left = load(x.x()); - right.loadItem(); - - CiValue reg = LMUL_OUT; - arithmeticOpLong(opcode, reg, left, right.result()); - CiValue result = createResultVariable(x); - lir.move(reg, result); - } else { - LIRItem right = new LIRItem(x.y(), this); - - CiValue left = load(x.x()); - // don't load constants to save register - right.loadNonconstant(); - createResultVariable(x); - arithmeticOpLong(opcode, x.operand(), left, right.result()); - } - } - - @Override - public void visitArithmetic(ArithmeticNode x) { - trySwap(x); - - if (x.kind.isWord() || x.opcode == Bytecodes.WREMI) { - visitArithmeticOpWord(x); - return; - } - - assert Util.archKindsEqual(x.x().kind, x.kind) && Util.archKindsEqual(x.y().kind, x.kind) : "wrong parameter types: " + Bytecodes.nameOf(x.opcode) + ", x: " + x.x() + ", y: " + x.y() + ", kind: " + x.kind; - switch (x.kind) { - case Float: - case Double: - visitArithmeticOpFloat(x); - return; - case Long: - visitArithmeticOpLong(x); - return; - case Int: - visitArithmeticOpInt(x); - return; - } - throw Util.shouldNotReachHere(); - } - - @Override - public void visitShift(ShiftNode x) { - // count must always be in rcx - CiValue count = makeOperand(x.y()); - boolean mustLoadCount = !count.isConstant() || x.kind == CiKind.Long; - if (mustLoadCount) { - // count for long must be in register - count = force(x.y(), SHIFT_COUNT_IN); - } - - CiValue value = load(x.x()); - CiValue reg = createResultVariable(x); - - shiftOp(x.opcode, reg, value, count, ILLEGAL); - } - - @Override - public void visitLogic(LogicNode x) { - trySwap(x); - - LIRItem right = new LIRItem(x.y(), this); - - CiValue left = load(x.x()); - right.loadNonconstant(); - CiValue reg = createResultVariable(x); - - logicOp(x.opcode, reg, left, right.result()); - } - - private void trySwap(BinaryNode x) { - // (tw) TODO: Check what this is for? - } - - @Override - public void visitNormalizeCompare(NormalizeCompareNode x) { - LIRItem left = new LIRItem(x.x(), this); - LIRItem right = new LIRItem(x.y(), this); - if (!x.kind.isVoid() && x.x().kind.isLong()) { - left.setDestroysRegister(); - } - left.loadItem(); - right.loadItem(); - - if (x.kind.isVoid()) { - lir.cmp(Condition.TRUE, left.result(), right.result()); - } else if (x.x().kind.isFloat() || x.x().kind.isDouble()) { - CiValue reg = createResultVariable(x); - lir.fcmp2int(left.result(), right.result(), reg, x.isUnorderedLess()); - } else if (x.x().kind.isLong() || x.x().kind.isWord()) { - CiValue reg = createResultVariable(x); - lir.lcmp2int(left.result(), right.result(), reg); - } else { - assert false; - } - } - - @Override - public void visitConvert(ConvertNode x) { - CiValue input = load(x.value()); - CiVariable result = newVariable(x.kind); - // arguments of lirConvert - GlobalStub globalStub = null; - // Checkstyle: off - switch (x.opcode) { - case Bytecodes.F2I: globalStub = stubFor(GlobalStub.Id.f2i); break; - case Bytecodes.F2L: globalStub = stubFor(GlobalStub.Id.f2l); break; - case Bytecodes.D2I: globalStub = stubFor(GlobalStub.Id.d2i); break; - case Bytecodes.D2L: globalStub = stubFor(GlobalStub.Id.d2l); break; - } - // Checkstyle: on - if (globalStub != null) { - // Force result to be rax to match global stubs expectation. - CiValue stubResult = x.kind == CiKind.Int ? RAX_I : RAX_L; - lir.convert(x.opcode, input, stubResult, globalStub); - lir.move(stubResult, result); - } else { - lir.convert(x.opcode, input, result, globalStub); - } - setResult(x, result); - } - - @Override - public void visitLoopBegin(LoopBeginNode x) { - } - - @Override - public void visitValueAnchor(ValueAnchorNode valueAnchor) { - // nothing to do for ValueAnchors - } - - @Override - public void visitMathIntrinsic(MathIntrinsicNode node) { - assert node.kind == CiKind.Double; - LIRItem opd = new LIRItem(node.x(), this); - opd.setDestroysRegister(); - opd.loadItem(); - CiVariable dest = createResultVariable(node); - switch (node.operation()) { - case ABS: - lir.abs(opd.result(), dest, CiValue.IllegalValue); - break; - case SQRT: - lir.sqrt(opd.result(), dest, CiValue.IllegalValue); - break; - - default: - throw Util.shouldNotReachHere(); - } - } - - @Override - public Condition floatingPointCondition(Condition cond) { - switch(cond) { - case LT: - return Condition.BT; - case LE: - return Condition.BE; - case GT: - return Condition.AT; - case GE: - return Condition.AE; - default : - return cond; - } - } - - @Override - public void emitMove(CiValue src, CiValue dst) { - lir().move(src, dst); - } - - @Override - public void emitLea(CiAddress address, CiVariable dest) { - lir().lea(address, dest); - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64XirAssembler.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64XirAssembler.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,220 +0,0 @@ -/* - * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.compiler.target.amd64; - -import static com.sun.cri.xir.XirTemplate.GlobalFlags.*; - -import java.util.*; - -import com.oracle.max.asm.target.amd64.*; -import com.sun.cri.ci.*; -import com.sun.cri.xir.*; - -/** - * AMD64 version of {@link CiXirAssembler}. - * - * @author Thomas Wuerthinger - * - */ -public class AMD64XirAssembler extends CiXirAssembler { - - @Override - protected XirTemplate buildTemplate(String name, boolean isStub) { - List fastPath = new ArrayList(instructions.size()); - List slowPath = new ArrayList(); - List calleeTemplates = new ArrayList(); - - int flags = 0; - - if (isStub) { - flags |= GLOBAL_STUB.mask; - } - - List currentList = fastPath; - - XirOperand fixedRDX = null; - XirOperand fixedRAX = null; - XirOperand fixedRCX = null; - XirOperand fixedRSI = null; - XirOperand fixedRDI = null; - HashSet boundLabels = new HashSet(); - - for (XirInstruction i : instructions) { - boolean appended = false; - switch (i.op) { - case Mov: - break; - - case Add: - case Sub: - case Div: - case Mul: - case Mod: - case Shl: - case Shr: - case And: - case Or: - case Xor: - // Convert to two operand form - XirOperand xOp = i.x(); - if (i.op == XirOp.Div || i.op == XirOp.Mod) { - if (fixedRDX == null) { - fixedRDX = createRegisterTemp("divModTemp", CiKind.Int, AMD64.rdx); - } - // Special treatment to make sure that the left input of % and / is in RAX - if (fixedRAX == null) { - fixedRAX = createRegisterTemp("divModLeftInput", CiKind.Int, AMD64.rax); - } - currentList.add(new XirInstruction(i.x().kind, XirOp.Mov, fixedRAX, i.x())); - xOp = fixedRAX; - } else { - if (i.result != i.x()) { - currentList.add(new XirInstruction(i.result.kind, XirOp.Mov, i.result, i.x())); - xOp = i.result; - } - } - - XirOperand yOp = i.y(); - if ((i.op == XirOp.Shl || i.op == XirOp.Shr) && (!(i.y() instanceof XirConstantOperand))) { - // Special treatment to make sure that the shift count is always in RCX - if (fixedRCX == null) { - fixedRCX = createRegisterTemp("fixedShiftCount", i.y().kind, AMD64.rcx); - } - currentList.add(new XirInstruction(i.result.kind, XirOp.Mov, fixedRCX, i.y())); - yOp = fixedRCX; - } else if (i.op == XirOp.Mul && (i.y() instanceof XirConstantOperand)) { - // Cannot multiply directly with a constant, so introduce a new temporary variable - XirOperand tempLocation = createTemp("mulTempLocation", i.y().kind); - currentList.add(new XirInstruction(i.result.kind, XirOp.Mov, tempLocation, i.y())); - yOp = tempLocation; - - } - - if (xOp != i.x() || yOp != i.y()) { - currentList.add(new XirInstruction(i.result.kind, i.op, i.result, xOp, yOp)); - appended = true; - } - break; - - case RepeatMoveWords: - case RepeatMoveBytes: - if (fixedRSI == null) { - fixedRSI = createRegisterTemp("fixedRSI", CiKind.Word, AMD64.rsi); - } - if (fixedRDI == null) { - fixedRDI = createRegisterTemp("fixedRDI", CiKind.Word, AMD64.rdi); - } - if (fixedRCX == null) { - fixedRCX = createRegisterTemp("fixedRCX", CiKind.Word, AMD64.rcx); - } - currentList.add(new XirInstruction(CiKind.Word, XirOp.Mov, fixedRSI, i.x())); - currentList.add(new XirInstruction(CiKind.Word, XirOp.Mov, fixedRDI, i.y())); - currentList.add(new XirInstruction(CiKind.Word, XirOp.Mov, fixedRCX, i.z())); - currentList.add(new XirInstruction(CiKind.Illegal, i.op, i.result, fixedRSI, fixedRDI, fixedRCX)); - appended = true; - break; - - case NullCheck: - case PointerLoad: - case LoadEffectiveAddress: - case PointerStore: - case PointerLoadDisp: - case PointerStoreDisp: - break; - case PointerCAS: - if (fixedRAX == null) { - fixedRAX = createRegisterTemp("fixedRAX", CiKind.Word, AMD64.rax); - } - // x = source of cmpxch - // y = new value - // z = old value (i.e., the one compared to). Must be in RAX (and so must the result). - currentList.add(new XirInstruction(CiKind.Word, XirOp.Mov, fixedRAX, i.z())); - currentList.add(new XirInstruction(i.kind, i.op, i.result, i.x(), i.y(), fixedRAX)); - appended = true; - break; - case CallStub: - flags |= HAS_STUB_CALL.mask; - calleeTemplates.add((XirTemplate) i.extra); - break; - case CallRuntime: - flags |= HAS_RUNTIME_CALL.mask; - break; - case Jmp: - // jmp can be either into the snippet or to a runtime target - flags |= i.extra instanceof XirLabel ? HAS_CONTROL_FLOW.mask : HAS_RUNTIME_CALL.mask; - break; - case Jeq: - case Jneq: - case Jgt: - case Jgteq: - case Jugteq: - case Jlt: - case Jlteq: - case DecAndJumpNotZero: - case Jbset: - flags |= HAS_CONTROL_FLOW.mask; - break; - case Bind: - XirLabel label = (XirLabel) i.extra; - currentList = label.inline ? fastPath : slowPath; - assert !boundLabels.contains(label) : "label may be bound only once"; - boundLabels.add(label); - break; - case Safepoint: - case Align: - case StackOverflowCheck: - case PushFrame: - case PopFrame: - case Push: - case Pop: - case Mark: - case Nop: - case RawBytes: - case ShouldNotReachHere: - break; - default: - assert false : "Unknown XIR operation " + i.op; - } - if (!appended) { - currentList.add(i); - } - } - for (XirLabel label : labels) { - assert label.name == XirLabel.TrueSuccessor || label.name == XirLabel.FalseSuccessor || boundLabels.contains(label) : "label " + label.name + " is not bound!"; - } - XirInstruction[] fp = fastPath.toArray(new XirInstruction[fastPath.size()]); - XirInstruction[] sp = slowPath.size() > 0 ? slowPath.toArray(new XirInstruction[slowPath.size()]) : null; - XirLabel[] xirLabels = labels.toArray(new XirLabel[labels.size()]); - XirParameter[] xirParameters = parameters.toArray(new XirParameter[parameters.size()]); - XirTemp[] temporaryOperands = temps.toArray(new XirTemp[temps.size()]); - XirConstant[] constantOperands = constants.toArray(new XirConstant[constants.size()]); - XirTemplate[] calleeTemplateArray = calleeTemplates.toArray(new XirTemplate[calleeTemplates.size()]); - XirMark[] marksArray = marks.toArray(new XirMark[marks.size()]); - return new XirTemplate(name, this.variableCount, this.allocateResultOperand, resultOperand, fp, sp, xirLabels, xirParameters, temporaryOperands, constantOperands, flags, calleeTemplateArray, marksArray, outgoingStackSize); - } - - @Override - public CiXirAssembler copy() { - return new AMD64XirAssembler(); - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/util/ArrayMap.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/util/ArrayMap.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,117 +0,0 @@ -/* - * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.compiler.util; - -/** - * The {@code ArrayMap} class implements an efficient one-level map which is implemented - * as an array. Note that because of the one-level array inside, this data structure performs best - * when the range of integer keys is small and densely used. Note that the implementation can - * handle arbitrary intervals, including negative numbers, up to intervals of size 2^31 - 1. - * - * @author Ben L. Titzer - */ -public class ArrayMap { - - private static final int INITIAL_SIZE = 5; // how big the initial array should be - private static final int EXTRA = 2; // how far on the left or right of a new element to grow - - Object[] map; - int low; - - /** - * Constructs a new {@code ArrayMap} with no initial assumptions. - */ - public ArrayMap() { - } - - /** - * Constructs a new {@code ArrayMap} that initially covers the specified interval. - * Note that this map will automatically expand if necessary later. - * @param low the low index, inclusive - * @param high the high index, exclusive - */ - public ArrayMap(int low, int high) { - this.low = low; - this.map = new Object[high - low + 1]; - } - - /** - * Puts a new value in the map at the specified index. - * @param i the index at which to store the value - * @param value the value to store at the specified index - */ - public void put(int i, T value) { - int index = i - low; - if (map == null) { - // no map yet - map = new Object[INITIAL_SIZE]; - low = index - 2; - map[INITIAL_SIZE / 2] = value; - } else if (index < 0) { - // grow backwards - growBackward(i, value); - } else if (index >= map.length) { - // grow forwards - growForward(i, value); - } else { - // no growth necessary - map[index] = value; - } - } - - /** - * Gets the value at the specified index in the map. - * @param i the index - * @return the value at the specified index; {@code null} if there is no value at the specified index, - * or if the index is out of the currently stored range - */ - public T get(int i) { - int index = i - low; - if (map == null || index < 0 || index >= map.length) { - return null; - } - Class type = null; - return Util.uncheckedCast(type, map[index]); - } - - public int length() { - return map.length; - } - - private void growBackward(int i, T value) { - int nlow = i - EXTRA; - Object[] nmap = new Object[low - nlow + map.length]; - System.arraycopy(map, 0, nmap, low - nlow, map.length); - map = nmap; - low = nlow; - map[i - low] = value; - } - - private void growForward(int i, T value) { - int nlen = i - low + 1 + EXTRA; - Object[] nmap = new Object[nlen]; - System.arraycopy(map, 0, nmap, 0, map.length); - map = nmap; - map[i - low] = value; - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/util/BitMap2D.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/util/BitMap2D.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,102 +0,0 @@ -/* - * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.compiler.util; - -import com.oracle.max.graal.graph.*; - -/** - * This class implements a two-dimensional bitmap. - * - * @author Marcelo Cintra - * @author Thomas Wuerthinger - */ -public final class BitMap2D { - - private BitMap map; - private final int bitsPerSlot; - - private int bitIndex(int slotIndex, int bitWithinSlotIndex) { - return slotIndex * bitsPerSlot + bitWithinSlotIndex; - } - - private boolean verifyBitWithinSlotIndex(int index) { - assert index < bitsPerSlot : "index " + index + " is out of bounds " + bitsPerSlot; - return true; - } - - public BitMap2D(int sizeInSlots, int bitsPerSlot) { - map = new BitMap(sizeInSlots * bitsPerSlot); - this.bitsPerSlot = bitsPerSlot; - } - - public int sizeInBits() { - return map.size(); - } - - // Returns number of full slots that have been allocated - public int sizeInSlots() { - return map.size() / bitsPerSlot; - } - - public boolean isValidIndex(int slotIndex, int bitWithinSlotIndex) { - assert verifyBitWithinSlotIndex(bitWithinSlotIndex); - return (bitIndex(slotIndex, bitWithinSlotIndex) < sizeInBits()); - } - - public boolean at(int slotIndex, int bitWithinSlotIndex) { - assert verifyBitWithinSlotIndex(bitWithinSlotIndex); - return map.get(bitIndex(slotIndex, bitWithinSlotIndex)); - } - - public void setBit(int slotIndex, int bitWithinSlotIndex) { - assert verifyBitWithinSlotIndex(bitWithinSlotIndex); - map.set(bitIndex(slotIndex, bitWithinSlotIndex)); - } - - public void clearBit(int slotIndex, int bitWithinSlotIndex) { - assert verifyBitWithinSlotIndex(bitWithinSlotIndex); - map.clear(bitIndex(slotIndex, bitWithinSlotIndex)); - } - - public void atPutGrow(int slotIndex, int bitWithinSlotIndex, boolean value) { - int size = sizeInSlots(); - if (size <= slotIndex) { - while (size <= slotIndex) { - size *= 2; - } - BitMap newBitMap = new BitMap(size * bitsPerSlot); - newBitMap.setUnion(map); - map = newBitMap; - } - - if (value) { - setBit(slotIndex, bitWithinSlotIndex); - } else { - clearBit(slotIndex, bitWithinSlotIndex); - } - } - - public void clear() { - map.clearAll(); - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/util/BlockWorkList.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/util/BlockWorkList.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,129 +0,0 @@ -/* - * Copyright (c) 2009, 2009, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.compiler.util; - -import com.oracle.max.graal.nodes.*; - -/** - * This class implements a worklist for dealing with blocks. The worklist can - * operate either as a stack (i.e. first-in / last-out), or as a sorted list, - * where blocks can be sorted by a supplied number. The latter usage lends itself - * naturally to iterative dataflow analysis problems. - * - * This implementation is not able to tell if a block is in the worklist already. - * Note that this implementation is slightly less efficient than the dedicated - * work list in {@link com.oracle.max.graal.compiler.graph.ScopeData}, because this worklist uses - * an externally supplied number. - * - * @author Ben L. Titzer - */ -public class BlockWorkList { - MergeNode[] workList; - int[] workListNumbers; - int workListIndex; - - /** - * Adds a block to this list in an unsorted fashion, like a stack. - * @param block the block to add - */ - public void add(MergeNode block) { - if (workList == null) { - // worklist not allocated yet - allocate(); - } else if (workListIndex == workList.length) { - // need to grow the worklist - grow(); - } - // put the block at the end of the array - workList[workListIndex++] = block; - } - - /** - * Adds a block to this list, sorted by the supplied number. The block - * with the lowest number is returned upon subsequent removes. - * @param block the block to add - * @param number the number used to sort the block - */ - public void addSorted(MergeNode block, int number) { - if (workList == null) { - // worklist not allocated yet - allocate(); - } else if (workListIndex == workList.length) { - // need to grow the worklist - grow(); - } - // put the block at the end of the array - workList[workListIndex] = block; - workListNumbers[workListIndex] = number; - workListIndex++; - int i = workListIndex - 2; - // push block towards the beginning of the array - for (; i >= 0; i--) { - int n = workListNumbers[i]; - if (n >= number) { - break; // already in the right position - } - workList[i + 1] = workList[i]; // bubble b down by one - workList[i] = block; // and overwrite its place with block - workListNumbers[i + 1] = n; // bubble n down by one - workListNumbers[i] = number; // and overwrite its place with number - } - } - - /** - * Removes the next block from this work list. If the blocks have been added - * in a sorted order, then the block with the lowest number is returned. Otherwise, - * the last block added is returned. - * @return the next block in the list - */ - public MergeNode removeFromWorkList() { - if (workListIndex != 0) { - return workList[--workListIndex]; - } - return null; - } - - /** - * Checks whether the list is empty. - * @return {@code true} if this list is empty - */ - public boolean isEmpty() { - return workListIndex == 0; - } - - private void allocate() { - workList = new MergeNode[5]; - workListNumbers = new int[5]; - } - - private void grow() { - int prevLength = workList.length; - MergeNode[] nworkList = new MergeNode[prevLength * 3]; - System.arraycopy(workList, 0, nworkList, 0, prevLength); - workList = nworkList; - - int[] nworkListNumbers = new int[prevLength * 3]; - System.arraycopy(workListNumbers, 0, nworkListNumbers, 0, prevLength); - workListNumbers = nworkListNumbers; - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/util/GraphUtil.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/util/GraphUtil.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,336 +0,0 @@ -/* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.compiler.util; - -import java.util.*; -import java.util.Map.Entry; - -import com.oracle.max.graal.compiler.*; -import com.oracle.max.graal.compiler.observer.*; -import com.oracle.max.graal.graph.*; -import com.oracle.max.graal.graph.NodeClass.NodeClassIterator; -import com.oracle.max.graal.graph.NodeClass.Position; -import com.oracle.max.graal.graph.collections.*; -import com.oracle.max.graal.graph.collections.NodeWorkList.InfiniteWorkException; -import com.oracle.max.graal.nodes.*; -import com.oracle.max.graal.nodes.PhiNode.PhiType; -import com.oracle.max.graal.nodes.extended.*; - -public class GraphUtil { - - public static interface ColoringLambda { - T color(Iterable incomming, MergeNode merge); - T danglingColor(Iterable incomming, MergeNode merge); - } - - /** - * colors down, applying the lambda at merge points, starting at the pre-colored points. - */ - public static void colorCFGDown(NodeMap colors, ColoringLambda lambda) { - Set delayed = new HashSet(); - Set currentPoints = new HashSet(); - Set otherPoints = new HashSet(); - Set otherMerges = new HashSet(); - for (Entry entry : colors.entries()) { - currentPoints.add(entry.getKey()); - } - ArrayList incomming = new ArrayList(2); - while (!currentPoints.isEmpty()) { - for (Node node : currentPoints) { - otherMerges.addAll(colorCFGDownToMerge(node, colors.get(node), colors)); - } - for (MergeNode merge : otherMerges) { - incomming.clear(); - for (EndNode end : merge.cfgPredecessors()) { - incomming.add(colors.get(end)); - } - T color = lambda.color(incomming, merge); - if (color != null) { - colors.set(merge, color); - colors.set(merge.next(), color); - otherPoints.add(merge.next()); - delayed.remove(merge); - } else { - delayed.add(merge); - } - } - Set tmp = currentPoints; - currentPoints = otherPoints; - otherPoints = tmp; - otherPoints.clear(); - otherMerges.clear(); - } - for (MergeNode merge : delayed) { - T color = lambda.danglingColor(incomming, merge); - if (color != null) { - colors.set(merge, color); - } - } - } - - private static Collection colorCFGDownToMerge(Node from, T color, NodeMap colors) { - NodeFlood work = from.graph().createNodeFlood(); - Collection merges = new LinkedList(); - work.add(from); - for (Node node : work) { - Node current = node; - while (current != null) { - if (current instanceof MergeNode) { - merges.add((MergeNode) current); - break; - } - colors.set(current, color); - if (current instanceof FixedWithNextNode && !(current instanceof AbstractVectorNode) && !(current instanceof InvokeNode && ((InvokeNode) current).exceptionEdge() != null)) { - current = ((FixedWithNextNode) current).next(); - } else if (current instanceof EndNode) { - current = ((EndNode) current).merge(); - } else { - if (current instanceof ControlSplitNode) { - for (Node sux : current.cfgSuccessors()) { - work.add(sux); - } - } else if (current instanceof InvokeNode && ((InvokeNode) current).exceptionEdge() != null) { - InvokeNode invoke = (InvokeNode) current; - work.add(invoke.next()); - work.add(invoke.exceptionEdge()); - } else if (current instanceof AbstractVectorNode) { - for (Node usage : current.usages()) { - work.add(usage); - } - work.add(((AbstractVectorNode) current).next()); - } - current = null; - } - } - } - return merges; - } - - public static interface ColorSplitingLambda { - void fixSplit(Node oldNode, Node newNode, T color); - void fixNode(Node node, T color); - ValueNode fixPhiInput(ValueNode input, T color); - boolean explore(Node n); - List parentColors(T color); - MergeNode merge(T color); - } - - // TODO (gd) rework that code around Phi handling : too complicated - public static void splitFromColoring(NodeMap coloring, ColorSplitingLambda lambda) { - Map internalColoring = new HashMap(); - NodeWorkList work = coloring.graph().createNodeWorkList(); - for (Entry entry : coloring.entries()) { - T color = entry.getValue(); - Node node = entry.getKey(); - work.add(node); - internalColoring.put(node, color); - } - Set colors = new HashSet(); - try { - for (Node node : work) { - if (node instanceof PhiNode) { - PhiNode phi = (PhiNode) node; - MergeNode merge = phi.merge(); - for (int i = 0; i < phi.valueCount(); i++) { - ValueNode v = phi.valueAt(i); - if (v != null) { - T color = internalColoring.get(merge.phiPredecessorAt(i)); - if (color != null) { - ValueNode replace = lambda.fixPhiInput(v, color); - if (replace != v) { - phi.setValueAt(i, replace); - } else { - if (lambda.explore(v) && coloring.get(v) == null && !work.isNew(v)) { - work.add(v); - } - } - } - } - } - } else { - boolean delay = false; - colors.clear(); - T originalColoringColor = coloring.get(node); - if (originalColoringColor == null && internalColoring.get(node) != null) { - continue; - } - if (originalColoringColor == null) { - for (Node usage : node.dataUsages()) { - if (usage instanceof PhiNode) { - PhiNode phi = (PhiNode) usage; - MergeNode merge = phi.merge(); - for (int i = 0; i < phi.valueCount(); i++) { - ValueNode v = phi.valueAt(i); - if (v == node) { - T color = internalColoring.get(merge.phiPredecessorAt(i)); - if (color != null) { - colors.add(color); - } - } - } - } else { - T color = internalColoring.get(usage); - if (color == null) { - if (lambda.explore(usage)) { - delay = true; - break; - } - } else { - colors.add(color); - } - } - } - if (delay) { - work.addAgain(node); - continue; - } - } else { - colors.add(originalColoringColor); - } - if (colors.size() == 1) { - T color = colors.iterator().next(); - internalColoring.put(node, color); - lambda.fixNode(node, color); - } else { - Map newNodes = new HashMap(); - Queue colorQueue = new LinkedList(colors); - while (!colorQueue.isEmpty()) { - T color = colorQueue.poll(); - List parentColors = lambda.parentColors(color); - Node newNode; - if (parentColors.size() > 1 && !(node instanceof FrameState) && colors.containsAll(parentColors)) { - boolean ready = true; - for (T parentColor : parentColors) { - if (newNodes.get(parentColor) == null) { - ready = false; - break; - } - } - if (!ready) { - colorQueue.offer(color); - continue; - } - PhiNode phi = new PhiNode(((ValueNode) node).kind, lambda.merge(color), PhiType.Value, node.graph()); - for (T parentColor : parentColors) { - Node input = newNodes.get(parentColor); - phi.addInput((ValueNode) input); - } - newNode = phi; - } else { - newNode = node.clone(node.graph()); - for (NodeClassIterator iter = node.inputs().iterator(); iter.hasNext();) { - Position pos = iter.nextPosition(); - newNode.set(pos, node.get(pos)); - } - for (NodeClassIterator iter = node.successors().iterator(); iter.hasNext();) { - Position pos = iter.nextPosition(); - newNode.set(pos, node.get(pos)); - } - internalColoring.put(newNode, color); - lambda.fixSplit(node, newNode, color); - } - newNodes.put(color, newNode); - LinkedList dataUsages = new LinkedList(); - for (Node usage : node.dataUsages()) { - dataUsages.add(usage); - } - for (Node usage : dataUsages) { - if (usage instanceof PhiNode) { - PhiNode phi = (PhiNode) usage; - MergeNode merge = phi.merge(); - for (int i = 0; i < phi.valueCount(); i++) { - ValueNode v = phi.valueAt(i); - if (v == node) { - T uColor = internalColoring.get(merge.endAt(i)); - if (uColor == color) { - phi.setValueAt(i, (ValueNode) newNode); - } - } - } - } else { - T uColor = internalColoring.get(usage); - if (uColor == color) { - usage.inputs().replace(node, newNode); - } - } - } - } - lambda.fixNode(node, null /*white*/); - } - if (node instanceof StateSplit) { - FrameState stateAfter = ((StateSplit) node).stateAfter(); - if (stateAfter != null && lambda.explore(stateAfter) && !work.isNew(stateAfter)) { - if (!(node instanceof MergeNode && coloring.get(((MergeNode) node).next()) == null)) { // not dangling colored merge - work.add(stateAfter); - } - } - } - - if (node instanceof MergeNode) { - for (Node usage : node.usages()) { - if (!work.isNew(usage)) { - work.add(usage); - } - } - } - - if (node instanceof LoopEndNode) { - work.add(((LoopEndNode) node).loopBegin()); - } - - for (Node input : node.dataInputs()) { - if (lambda.explore(input) && coloring.get(input) == null && !work.isNew(input)) { - work.add(input); - } - } - } - } - } catch (InfiniteWorkException re) { - System.out.println("Infinite work, current queue :"); - for (Node n : work) { - System.out.println(" - " + n); - } - GraalCompilation compilation = GraalCompilation.compilation(); - if (compilation.compiler.isObserved()) { - NodeMap debugColoring = coloring.graph().createNodeMap(); - for (Entry entry : internalColoring.entrySet()) { - debugColoring.set(entry.getKey(), entry.getValue()); - } - Map debug = new HashMap(); - debug.put("split", debugColoring); - compilation.compiler.fireCompilationEvent(new CompilationEvent(compilation, "RuntimeException in split", coloring.graph(), true, false, true, debug)); - } - throw re; - } - GraalCompilation compilation = GraalCompilation.compilation(); - if (compilation.compiler.isObserved()) { - NodeMap debugColoring = coloring.graph().createNodeMap(); - for (Entry entry : internalColoring.entrySet()) { - debugColoring.set(entry.getKey(), entry.getValue()); - } - Map debug = new HashMap(); - debug.put("split", debugColoring); - compilation.compiler.fireCompilationEvent(new CompilationEvent(compilation, "Split end!!", coloring.graph(), true, false, debug)); - } - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/util/IntList.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/util/IntList.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,163 +0,0 @@ -/* - * Copyright (c) 2010, 2010, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.compiler.util; - -import java.util.*; - -/** - * An expandable and indexable list of {@code int}s. - * - * This class avoids the boxing/unboxing incurred by {@code ArrayList}. - * - * @author Doug Simon - */ -public final class IntList { - - private int[] array; - private int size; - - /** - * Creates an int list with a specified initial capacity. - * - * @param initialCapacity - */ - public IntList(int initialCapacity) { - array = new int[initialCapacity]; - } - - /** - * Creates an int list with a specified initial array. - * - * @param array the initial array used for the list (no copy is made) - * @param initialSize the initial {@linkplain #size() size} of the list (must be less than or equal to {@code array.length} - */ - public IntList(int[] array, int initialSize) { - assert initialSize <= array.length; - this.array = array; - this.size = initialSize; - } - - /** - * Makes a new int list by copying a range from a given int list. - * - * @param other the list from which a range of values is to be copied into the new list - * @param startIndex the index in {@code other} at which to start copying - * @param length the number of values to copy from {@code other} - * @return a new int list whose {@linkplain #size() size} and capacity is {@code length} - */ - public static IntList copy(IntList other, int startIndex, int length) { - return copy(other, startIndex, length, length); - } - - /** - * Makes a new int list by copying a range from a given int list. - * - * @param other the list from which a range of values is to be copied into the new list - * @param startIndex the index in {@code other} at which to start copying - * @param length the number of values to copy from {@code other} - * @param initialCapacity the initial capacity of the new int list (must be greater or equal to {@code length}) - * @return a new int list whose {@linkplain #size() size} is {@code length} - */ - public static IntList copy(IntList other, int startIndex, int length, int initialCapacity) { - assert initialCapacity >= length : "initialCapacity < length"; - int[] array = new int[initialCapacity]; - System.arraycopy(other.array, startIndex, array, 0, length); - return new IntList(array, length); - } - - public int size() { - return size; - } - - /** - * Appends a value to the end of this list, increasing its {@linkplain #size() size} by 1. - * - * @param value the value to append - */ - public void add(int value) { - if (size == array.length) { - int newSize = (size * 3) / 2 + 1; - array = Arrays.copyOf(array, newSize); - } - array[size++] = value; - } - - /** - * Gets the value in this list at a given index. - * - * @param index the index of the element to return - * @throws IndexOutOfBoundsException if {@code index < 0 || index >= size()} - */ - public int get(int index) { - if (index >= size) { - throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + size); - } - return array[index]; - } - - /** - * Sets the size of this list to 0. - */ - public void clear() { - size = 0; - } - - /** - * Sets a value at a given index in this list. - * - * @param index the index of the element to update - * @param value the new value of the element - * @throws IndexOutOfBoundsException if {@code index < 0 || index >= size()} - */ - public void set(int index, int value) { - if (index >= size) { - throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + size); - } - array[index] = value; - } - - /** - * Adjusts the {@linkplain #size() size} of this int list. - * - * If {@code newSize < size()}, the size is changed to {@code newSize}. - * If {@code newSize > size()}, sufficient 0 elements are {@linkplain #add(int) added} - * until {@code size() == newSize}. - * - * @param newSize the new size of this int list - */ - public void setSize(int newSize) { - if (newSize < size) { - size = newSize; - } else if (newSize > size) { - array = Arrays.copyOf(array, newSize); - } - } - - @Override - public String toString() { - if (array.length == size) { - return Arrays.toString(array); - } - return Arrays.toString(Arrays.copyOf(array, size)); - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/util/LoopUtil.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/util/LoopUtil.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,900 +0,0 @@ -/* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.compiler.util; - -import java.util.*; -import java.util.Map.Entry; - -import com.oracle.max.graal.compiler.*; -import com.oracle.max.graal.compiler.observer.*; -import com.oracle.max.graal.compiler.schedule.*; -import com.oracle.max.graal.compiler.util.GraphUtil.ColorSplitingLambda; -import com.oracle.max.graal.compiler.util.GraphUtil.ColoringLambda; -import com.oracle.max.graal.graph.*; -import com.oracle.max.graal.graph.NodeClass.NodeClassIterator; -import com.oracle.max.graal.graph.NodeClass.Position; -import com.oracle.max.graal.graph.collections.*; -import com.oracle.max.graal.nodes.*; -import com.oracle.max.graal.nodes.PhiNode.PhiType; -import com.oracle.max.graal.nodes.extended.*; -import com.oracle.max.graal.nodes.loop.*; -import com.sun.cri.ci.*; - -public class LoopUtil { - - public static class Loop { - private final LoopBeginNode loopBegin; - private NodeBitMap cfgNodes; - private Loop parent; - private NodeBitMap exits; - private NodeBitMap inOrBefore; - private NodeBitMap inOrAfter; - private NodeBitMap nodes; - public Loop(LoopBeginNode loopBegin, NodeBitMap nodes, NodeBitMap exits) { - this.loopBegin = loopBegin; - this.cfgNodes = nodes; - this.exits = exits; - } - - public LoopBeginNode loopBegin() { - return loopBegin; - } - - public NodeBitMap cfgNodes() { - return cfgNodes; - } - - public NodeBitMap nodes() { - if (nodes == null) { - nodes = loopBegin().graph().createNodeBitMap(); - nodes.setUnion(inOrAfter()); - nodes.setIntersect(inOrBefore()); - } - return nodes; - } - - public Loop parent() { - return parent; - } - - public NodeBitMap exits() { - return exits; - } - - public void setParent(Loop parent) { - this.parent = parent; - } - - public boolean isChild(Loop loop) { - return loop.parent != null && (loop.parent == this || loop.parent.isChild(this)); - } - - public NodeBitMap inOrAfter() { - if (inOrAfter == null) { - inOrAfter = LoopUtil.inOrAfter(this); - } - return inOrAfter; - } - - public NodeBitMap inOrBefore() { - if (inOrBefore == null) { - inOrBefore = LoopUtil.inOrBefore(this, inOrAfter()); - } - return inOrBefore; - } - - public void invalidateCached() { - inOrAfter = null; - inOrBefore = null; - nodes = null; - } - - @Override - public String toString() { - return "Loop #" + loopBegin().id(); - } - } - - private static class PeelingResult { - public final FixedNode begin; - public final FixedNode end; - public final NodeMap exits; - public final NodeBitMap unaffectedExits; - public final NodeMap phis; - public final NodeMap phiInits; - public final NodeMap dataOut; - public final NodeBitMap exitFrameStates; - public final NodeBitMap peeledNodes; - public PeelingResult(FixedNode begin, FixedNode end, NodeMap exits, NodeMap phis, NodeMap phiInits, NodeMap dataOut, NodeBitMap unaffectedExits, NodeBitMap exitFrameStates, NodeBitMap peeledNodes) { - this.begin = begin; - this.end = end; - this.exits = exits; - this.phis = phis; - this.phiInits = phiInits; - this.dataOut = dataOut; - this.unaffectedExits = unaffectedExits; - this.exitFrameStates = exitFrameStates; - this.peeledNodes = peeledNodes; - } - } - - public static List computeLoops(Graph graph) { - List loops = new LinkedList(); - for (LoopBeginNode loopBegin : graph.getNodes(LoopBeginNode.class)) { - NodeBitMap cfgNodes = markUpCFG(loopBegin, loopBegin.loopEnd()); // computeLoopNodes(loopBegin); - cfgNodes.mark(loopBegin); - NodeBitMap exits = computeLoopExits(loopBegin, cfgNodes); - loops.add(new Loop(loopBegin, cfgNodes, exits)); - } - for (Loop loop : loops) { - for (Loop other : loops) { - if (other != loop && other.cfgNodes().isMarked(loop.loopBegin())) { - if (loop.parent() == null || loop.parent().cfgNodes().isMarked(other.loopBegin())) { - loop.setParent(other); - } - } - } - } - return loops; - } - - public static NodeBitMap computeLoopExits(LoopBeginNode loopBegin, NodeBitMap cfgNodes) { - Graph graph = loopBegin.graph(); - NodeBitMap exits = graph.createNodeBitMap(); - for (Node n : cfgNodes) { - if (IdentifyBlocksPhase.trueSuccessorCount(n) > 1) { - for (Node sux : n.cfgSuccessors()) { - if (!cfgNodes.isMarked(sux) && sux instanceof FixedNode) { - exits.mark(sux); - } - } - } - } - return exits; - } - - private static boolean recurse = false; - public static NodeBitMap computeLoopNodesFrom(Loop loop, FixedNode from) { - LoopBeginNode loopBegin = loop.loopBegin(); - NodeBitMap loopNodes = markUpCFG(loopBegin, from); - loopNodes.mark(loopBegin); - NodeBitMap inOrAfter = inOrAfter(loop, loopNodes, false); - NodeBitMap inOrBefore = inOrBefore(loop, inOrAfter, loopNodes, false); - if (!recurse) { - recurse = true; - GraalCompilation compilation = GraalCompilation.compilation(); - if (compilation.compiler.isObserved()) { - Map debug = new HashMap(); - debug.put("loopNodes", loopNodes); - debug.put("inOrAfter", inOrAfter); - debug.put("inOrBefore", inOrBefore); - compilation.compiler.fireCompilationEvent(new CompilationEvent(compilation, "Compute loop nodes loop#" + loopBegin.id(), loopBegin.graph(), true, false, debug)); - } - recurse = false; - } - inOrAfter.setIntersect(inOrBefore); - loopNodes.setUnion(inOrAfter); - if (from == loopBegin.loopEnd()) { // fill the Loop cache value for loop nodes this is correct even if after/before were partial - loop.nodes = loopNodes; - } - return loopNodes; - } - - public static NodeBitMap markUpCFG(LoopBeginNode loopBegin) { - return markUpCFG(loopBegin, loopBegin.loopEnd()); - } - - public static NodeBitMap markUpCFG(LoopBeginNode loopBegin, FixedNode from) { - NodeFlood workCFG = loopBegin.graph().createNodeFlood(); - workCFG.add(from); - NodeBitMap loopNodes = loopBegin.graph().createNodeBitMap(); - for (Node n : workCFG) { - if (n == loopBegin) { - continue; - } - loopNodes.mark(n); - if (n instanceof LoopBeginNode) { - workCFG.add(((LoopBeginNode) n).loopEnd()); - } - for (Node pred : n.cfgPredecessors()) { - workCFG.add(pred); - } - } - return loopNodes; - } - - public static void inverseLoop(Loop loop, IfNode split) { - assert loop.cfgNodes().isMarked(split); - FixedNode noExit = split.trueSuccessor(); - FixedNode exit = split.falseSuccessor(); - if (loop.cfgNodes().isMarked(exit) && !loop.cfgNodes().isMarked(noExit)) { - FixedNode tmp = noExit; - noExit = exit; - exit = tmp; - } - assert !loop.cfgNodes().isMarked(exit); - assert loop.cfgNodes().isMarked(noExit); - - PeelingResult peeling = preparePeeling(loop, split); - rewireInversion(peeling, loop, split); - - // move peeled part to the end - LoopBeginNode loopBegin = loop.loopBegin(); - LoopEndNode loopEnd = loopBegin.loopEnd(); - FixedNode lastNode = (FixedNode) loopEnd.predecessor(); - if (loopBegin.next() != lastNode) { - lastNode.successors().replace(loopEnd, loopBegin.next()); - loopBegin.setNext(noExit); - split.successors().replace(noExit, loopEnd); - } - - //rewire phi usage in peeled part - int backIndex = loopBegin.phiPredecessorIndex(loopBegin.loopEnd()); - for (PhiNode phi : loopBegin.phis()) { - ValueNode backValue = phi.valueAt(backIndex); - if (loop.nodes().isMarked(backValue) && peeling.peeledNodes.isNotNewNotMarked(backValue)) { - for (Node usage : phi.usages().snapshot()) { - if (peeling.peeledNodes.isNotNewMarked(usage)) { - usage.inputs().replace(phi, backValue); - } - } - } - } - - loop.invalidateCached(); - - // update parents - Loop parent = loop.parent(); - while (parent != null) { - parent.cfgNodes = markUpCFG(parent.loopBegin, parent.loopBegin.loopEnd()); - parent.invalidateCached(); - parent.exits = computeLoopExits(parent.loopBegin, parent.cfgNodes); - parent = parent.parent; - } - - GraalMetrics.LoopsInverted++; - } - - public static void peelLoop(Loop loop) { - LoopEndNode loopEnd = loop.loopBegin().loopEnd(); - PeelingResult peeling = preparePeeling(loop, loopEnd); - GraalCompilation compilation = GraalCompilation.compilation(); - - if (compilation.compiler.isObserved()) { - compilation.compiler.fireCompilationEvent(new CompilationEvent(compilation, "After peeling preparation", loopEnd.graph(), true, false)); - } - - rewirePeeling(peeling, loop); - - loop.invalidateCached(); - // update parents - Loop parent = loop.parent(); - while (parent != null) { - parent.cfgNodes = markUpCFG(parent.loopBegin, parent.loopBegin.loopEnd()); - parent.invalidateCached(); - parent.exits = computeLoopExits(parent.loopBegin, parent.cfgNodes); - parent = parent.parent; - } - GraalMetrics.LoopsPeeled++; - } - - private static void rewireInversion(PeelingResult peeling, Loop loop, FixedNode from) { - rewirePeeling(peeling, loop, from, true); - } - - private static void rewirePeeling(PeelingResult peeling, Loop loop) { - rewirePeeling(peeling, loop, loop.loopBegin().loopEnd(), false); - } - - private static void rewirePeeling(PeelingResult peeling, Loop loop, FixedNode from, boolean inversion) { - LoopBeginNode loopBegin = loop.loopBegin(); - Graph graph = loopBegin.graph(); - Node loopPred = loopBegin.predecessor(); - loopPred.successors().replace(loopBegin.forwardEdge(), peeling.begin); - NodeBitMap loopNodes = loop.cfgNodes(); - Node originalLast = from; - if (originalLast == loopBegin.loopEnd()) { - originalLast = loopBegin.loopEnd().predecessor(); - } - boolean found = false; - for (NodeClassIterator iter = originalLast.successors().iterator(); iter.hasNext();) { - Position pos = iter.nextPosition(); - Node sux = originalLast.getNodeClass().get(originalLast, pos); - if (sux == null) { - continue; - } - if (loopNodes.isMarked(sux)) { - assert !found; - peeling.end.getNodeClass().set(peeling.end, pos, loopBegin.forwardEdge()); - found = true; - } - } - assert found; - int phiInitIndex = loopBegin.phiPredecessorIndex(loopBegin.forwardEdge()); - for (Entry entry : peeling.phis.entries()) { - PhiNode phi = (PhiNode) entry.getKey(); - PlaceholderNode p = entry.getValue(); - ValueNode init = phi.valueAt(phiInitIndex); - p.replaceAndDelete(init); - for (Entry dataEntry : peeling.dataOut.entries()) { - if (dataEntry.getValue() == p) { - dataEntry.setValue(init); - } - } - } - for (Entry entry : peeling.phiInits.entries()) { - PhiNode phi = (PhiNode) entry.getKey(); - Node newInit = entry.getValue(); - phi.setValueAt(phiInitIndex, (ValueNode) newInit); - } - - if (from == loopBegin.loopEnd()) { - for (InductionVariableNode iv : loopBegin.inductionVariables()) { - iv.peelOneIteration(); - } - } - NodeMap> newExitValues = graph.createNodeMap(); - List exitPoints = new LinkedList(); - for (Node exit : peeling.unaffectedExits) { - exitPoints.add(exit); - } - - for (Entry entry : peeling.exits.entries()) { - StateSplit original = (StateSplit) entry.getKey(); - StateSplit newExit = entry.getValue(); - EndNode oEnd = new EndNode(graph); - EndNode nEnd = new EndNode(graph); - MergeNode merge = new MergeNode(graph); - FrameState originalState = original.stateAfter(); - merge.addEnd(nEnd); - merge.addEnd(oEnd); - merge.setStateAfter(originalState.duplicate(originalState.bci, true)); - merge.setNext(original.next()); - original.setNext(oEnd); - newExit.setNext(nEnd); - exitPoints.add(original); - exitPoints.add(newExit); - } - - int phiBackIndex = loopBegin.phiPredecessorIndex(loopBegin.loopEnd()); - for (Entry entry : peeling.exits.entries()) { - StateSplit original = (StateSplit) entry.getKey(); - EndNode oEnd = (EndNode) original.next(); - MergeNode merge = oEnd.merge(); - EndNode nEnd = merge.endAt(1 - merge.phiPredecessorIndex(oEnd)); - Node newExit = nEnd.predecessor(); - for (Entry dataEntry : peeling.dataOut.entries()) { - Node originalValue = dataEntry.getKey(); - Node newValue = dataEntry.getValue(); - NodeMap phiMap = newExitValues.get(originalValue); - if (phiMap == null) { - phiMap = graph.createNodeMap(); - newExitValues.set(originalValue, phiMap); - } - ValueNode backValue = null; - if (inversion && originalValue instanceof PhiNode && ((PhiNode) originalValue).merge() == loopBegin) { - backValue = ((PhiNode) originalValue).valueAt(phiBackIndex); - if (peeling.peeledNodes.isNotNewMarked(backValue)) { - backValue = null; - } - } - if (backValue != null) { - phiMap.set(original, backValue); - } else { - phiMap.set(original, (ValueNode) originalValue); - } - phiMap.set(newExit, (ValueNode) newValue); - } - } - - if (inversion) { - // rewire dataOut in non-peeled body - NodeBitMap exitMergesPhis = graph.createNodeBitMap(); - for (Entry entry : peeling.exits.entries()) { - StateSplit newExit = entry.getValue(); - MergeNode merge = ((EndNode) newExit.next()).merge(); - exitMergesPhis.markAll(merge.phis()); - } - for (Entry entry : peeling.dataOut.entries()) { - ValueNode originalValue = (ValueNode) entry.getKey(); - if (originalValue instanceof PhiNode && ((PhiNode) originalValue).merge() == loopBegin) { - continue; - } - ValueNode newValue = (ValueNode) entry.getValue(); - PhiNode phi = null; - for (Node usage : originalValue.usages().snapshot()) { - if (exitMergesPhis.isMarked(usage) || ( - loop.nodes().isNotNewMarked(usage) - && peeling.peeledNodes.isNotNewNotMarked(usage) - && !(usage instanceof PhiNode && ((PhiNode) usage).merge() == loopBegin)) - && !(usage instanceof FrameState && ((FrameState) usage).block() == loopBegin)) { - if (phi == null) { - phi = new PhiNode(originalValue.kind, loopBegin, PhiType.Value, graph); - phi.addInput(newValue); - phi.addInput(originalValue); - NodeMap exitMap = newExitValues.get(originalValue); - for (Node exit : peeling.unaffectedExits) { - exitMap.set(exit, phi); - } - } - usage.inputs().replace(originalValue, phi); - } - } - } - } - - for (Entry> entry : newExitValues.entries()) { - ValueNode original = (ValueNode) entry.getKey(); - NodeMap pointToValue = entry.getValue(); - for (Node exit : exitPoints) { - Node valueAtExit = pointToValue.get(exit); - if (valueAtExit == null) { - pointToValue.set(exit, original); - } - } - } - - replaceValuesAtLoopExits(newExitValues, loop, exitPoints, peeling.exitFrameStates); - } - - private static void replaceValuesAtLoopExits(final NodeMap> newExitValues, Loop loop, List exitPoints, final NodeBitMap exitFrameStates) { - Graph graph = loop.loopBegin().graph(); - final NodeMap colors = graph.createNodeMap(); - - // prepare inital colors - for (Node exitPoint : exitPoints) { - colors.set(exitPoint, exitPoint); - } - - // color - GraphUtil.colorCFGDown(colors, new ColoringLambda() { - @Override - public Node color(Iterable incomming, MergeNode merge) { - Node color = null; - for (Node c : incomming) { - if (c == null) { - return null; - } - if (color == null) { - color = c; - } else if (color != c) { - return merge; - } - } - return color; - } - @Override - public Node danglingColor(Iterable incomming, MergeNode merge) { - Node color = null; - for (Node c : incomming) { - if (color == null) { - color = c; - } else if (color != c) { - return merge; - } - } - assert color != null; - return color; - } - }); - - - loop.invalidateCached(); - final NodeBitMap inOrBefore = loop.inOrBefore(); - - GraalCompilation compilation = GraalCompilation.compilation(); - if (compilation.compiler.isObserved()) { - Map debug = new HashMap(); - debug.put("loopExits", colors); - debug.put("inOrBefore", inOrBefore); - debug.put("inOrAfter", loop.inOrAfter()); - debug.put("nodes", loop.nodes()); - debug.put("exitFrameStates", exitFrameStates); - compilation.compiler.fireCompilationEvent(new CompilationEvent(compilation, "After coloring", graph, true, false, debug)); - } - - GraphUtil.splitFromColoring(colors, new ColorSplitingLambda(){ - @Override - public void fixSplit(Node oldNode, Node newNode, Node color) { - assert color != null; - this.fixNode(newNode, color); - } - private ValueNode getValueAt(Node point, NodeMap valueMap, CiKind kind) { - ValueNode value = valueMap.get(point); - if (value != null) { - return value; - } - MergeNode merge = (MergeNode) point; - ArrayList values = new ArrayList(merge.phiPredecessorCount()); - ValueNode v = null; - boolean createPhi = false; - for (EndNode end : merge.cfgPredecessors()) { - ValueNode valueAt = getValueAt(colors.get(end), valueMap, kind); - if (v == null) { - v = valueAt; - } else if (v != valueAt) { - createPhi = true; - } - values.add(valueAt); - } - if (createPhi) { - PhiNode phi = new PhiNode(kind, merge, PhiType.Value, merge.graph()); - valueMap.set(point, phi); - for (EndNode end : merge.cfgPredecessors()) { - phi.addInput(getValueAt(colors.get(end), valueMap, kind)); - } - return phi; - } else { - assert v != null; - valueMap.set(point, v); - return v; - } - } - @Override - public boolean explore(Node n) { - return exitFrameStates.isNotNewMarked(n) || (inOrBefore.isNotNewNotMarked(n) && n.getNodeClass().directInputCount() > 0 && !afterColoringFramestate(n)); //TODO (gd) hum - } - public boolean afterColoringFramestate(Node n) { - if (!(n instanceof FrameState)) { - return false; - } - final FrameState frameState = (FrameState) n; - MergeNode block = frameState.block(); - if (block != null) { - return colors.get(block.next()) == null; - } - StateSplit stateSplit = frameState.stateSplit(); - if (stateSplit != null) { - return colors.get(stateSplit) == null; - } - for (FrameState inner : frameState.innerFrameStates()) { - if (!afterColoringFramestate(inner)) { - return false; - } - } - return true; - } - @Override - public void fixNode(Node node, Node color) { - if (color == null) { - // 'white' it out : make non-explorable - if (!exitFrameStates.isNew(node)) { - exitFrameStates.clear(node); - } - inOrBefore.mark(node); - } else { - for (NodeClassIterator iter = node.inputs().iterator(); iter.hasNext();) { - Position pos = iter.nextPosition(); - Node input = node.getNodeClass().get(node, pos); - if (input == null || newExitValues.isNew(input)) { - continue; - } - NodeMap valueMap = newExitValues.get(input); - if (valueMap != null) { - ValueNode replacement = getValueAt(color, valueMap, ((ValueNode) input).kind); - node.getNodeClass().set(node, pos, replacement); - } - } - } - } - @Override - public ValueNode fixPhiInput(ValueNode input, Node color) { - if (newExitValues.isNew(input)) { - return input; - } - NodeMap valueMap = newExitValues.get(input); - if (valueMap != null) { - return getValueAt(color, valueMap, input.kind); - } - return input; - } - @Override - public List parentColors(Node color) { - if (!(color instanceof MergeNode)) { - return Collections.emptyList(); - } - MergeNode merge = (MergeNode) color; - List parentColors = new ArrayList(merge.phiPredecessorCount()); - for (EndNode pred : merge.cfgPredecessors()) { - parentColors.add(colors.get(pred)); - } - return parentColors; - } - @Override - public MergeNode merge(Node color) { - return (MergeNode) color; - } - }); - } - - private static PeelingResult preparePeeling(Loop loop, FixedNode from) { - LoopBeginNode loopBegin = loop.loopBegin(); - Graph graph = loopBegin.graph(); - NodeBitMap marked = computeLoopNodesFrom(loop, from); - if (from == loopBegin.loopEnd()) { - clearWithState(from, marked); - } - clearWithState(loopBegin, marked); - Map replacements = new HashMap(); - NodeMap phis = graph.createNodeMap(); - NodeMap exits = graph.createNodeMap(); - NodeBitMap unaffectedExits = graph.createNodeBitMap(); - NodeBitMap clonedExits = graph.createNodeBitMap(); - NodeBitMap exitFrameStates = graph.createNodeBitMap(); - for (Node exit : loop.exits()) { - if (marked.isMarked(exit.predecessor())) { - StateSplit pExit = findNearestMergableExitPoint((FixedNode) exit, marked); - markWithState(pExit, marked); - clonedExits.mark(pExit); - FrameState stateAfter = pExit.stateAfter(); - while (stateAfter != null) { - exitFrameStates.mark(stateAfter); - stateAfter = stateAfter.outerFrameState(); - } - } else { - unaffectedExits.mark(exit); - } - } - - NodeBitMap dataOut = graph.createNodeBitMap(); - for (Node n : marked) { - if (!(n instanceof FrameState)) { - for (Node usage : n.dataUsages()) { - if ((!marked.isMarked(usage) && !((usage instanceof PhiNode) && ((PhiNode) usage).merge() != loopBegin)) - || (marked.isMarked(usage) && exitFrameStates.isMarked(usage))) { - dataOut.mark(n); - break; - } - } - } - } - - for (Node n : marked) { - if (n instanceof PhiNode && ((PhiNode) n).merge() == loopBegin) { - PlaceholderNode p = new PlaceholderNode(graph); - replacements.put(n, p); - phis.set(n, p); - marked.clear(n); - } - for (Node input : n.dataInputs()) { - if (!marked.isMarked(input) && (!(input instanceof PhiNode) || ((PhiNode) input).merge() != loopBegin) && replacements.get(input) == null) { - replacements.put(input, input); - } - } - } - - Map duplicates = graph.addDuplicate(marked, replacements); - - NodeMap dataOutMapping = graph.createNodeMap(); - for (Node n : dataOut) { - Node newOut = duplicates.get(n); - if (newOut == null) { - newOut = replacements.get(n); - } - assert newOut != null; - dataOutMapping.set(n, newOut); - } - - for (Node n : clonedExits) { - exits.set(n, (StateSplit) duplicates.get(n)); - } - - NodeMap phiInits = graph.createNodeMap(); - int backIndex = loopBegin.phiPredecessorIndex(loopBegin.loopEnd()); - int fowardIndex = loopBegin.phiPredecessorIndex(loopBegin.forwardEdge()); - for (PhiNode phi : loopBegin.phis()) { - ValueNode backValue = phi.valueAt(backIndex); - if (marked.isMarked(backValue)) { - phiInits.set(phi, duplicates.get(backValue)); - } else if (from == loopBegin.loopEnd()) { - if (backValue instanceof PhiNode && ((PhiNode) backValue).merge() == loopBegin) { - PhiNode backPhi = (PhiNode) backValue; - phiInits.set(phi, backPhi.valueAt(fowardIndex)); - } else { - phiInits.set(phi, backValue); - } - } - } - - FixedNode newBegin = (FixedNode) duplicates.get(loopBegin.next()); - FixedNode newFrom = (FixedNode) duplicates.get(from == loopBegin.loopEnd() ? from.predecessor() : from); - return new PeelingResult(newBegin, newFrom, exits, phis, phiInits, dataOutMapping, unaffectedExits, exitFrameStates, marked); - } - - private static StateSplit findNearestMergableExitPoint(FixedNode exit, NodeBitMap marked) { - - LinkedList branches = new LinkedList(); - branches.add(exit); - while (true) { - if (branches.size() == 1) { - final FixedNode fixedNode = branches.get(0); - if (fixedNode instanceof StateSplit && ((StateSplit) fixedNode).stateAfter() != null) { - return (StateSplit) fixedNode; - } - } else { - // FixedNode current = branches.poll(); - // TODO (gd) find appropriate point : will be useful if a loop exit goes "up" as a result of making a branch dead in the loop body - } - } - } - - private static NodeBitMap inOrAfter(Loop loop) { - return inOrAfter(loop, loop.cfgNodes()); - } - - private static NodeBitMap inOrAfter(Loop loop, NodeBitMap cfgNodes) { - return inOrAfter(loop, cfgNodes, true); - } - - private static NodeBitMap inOrAfter(Loop loop, NodeBitMap cfgNodes, boolean full) { - Graph graph = loop.loopBegin().graph(); - NodeBitMap inOrAfter = graph.createNodeBitMap(); - NodeFlood work = graph.createNodeFlood(); - work.addAll(cfgNodes); - for (Node n : work) { - markWithState(n, inOrAfter); - if (full) { - for (Node sux : n.successors()) { - if (sux != null) { - work.add(sux); - } - } - } - for (Node usage : n.usages()) { - if (usage instanceof PhiNode) { // filter out data graph cycles - PhiNode phi = (PhiNode) usage; - MergeNode merge = phi.merge(); - if (merge instanceof LoopBeginNode) { - LoopBeginNode phiLoop = (LoopBeginNode) merge; - int backIndex = phiLoop.phiPredecessorIndex(phiLoop.loopEnd()); - if (phi.valueAt(backIndex) == n) { - continue; - } - } - } - work.add(usage); - } - } - return inOrAfter; - } - - private static NodeBitMap inOrBefore(Loop loop) { - return inOrBefore(loop, inOrAfter(loop)); - } - - private static NodeBitMap inOrBefore(Loop loop, NodeBitMap inOrAfter) { - return inOrBefore(loop, inOrAfter, loop.cfgNodes()); - } - - private static NodeBitMap inOrBefore(Loop loop, NodeBitMap inOrAfter, NodeBitMap cfgNodes) { - return inOrBefore(loop, inOrAfter, cfgNodes, true); - } - - private static NodeBitMap inOrBefore(Loop loop, NodeBitMap inOrAfter, NodeBitMap cfgNodes, boolean full) { - Graph graph = loop.loopBegin().graph(); - NodeBitMap inOrBefore = graph.createNodeBitMap(); - NodeFlood work = graph.createNodeFlood(); - work.addAll(cfgNodes); - for (Node n : work) { - inOrBefore.mark(n); - if (full) { - if (n.predecessor() != null) { - work.add(n.predecessor()); - } - } - if (n instanceof PhiNode) { // filter out data graph cycles - PhiNode phi = (PhiNode) n; - if (phi.type() == PhiType.Value) { - int backIndex = -1; - MergeNode merge = phi.merge(); - if (merge instanceof LoopBeginNode && cfgNodes.isNotNewNotMarked(((LoopBeginNode) merge).loopEnd())) { - LoopBeginNode phiLoop = (LoopBeginNode) merge; - backIndex = phiLoop.phiPredecessorIndex(phiLoop.loopEnd()); - } - for (int i = 0; i < phi.valueCount(); i++) { - if (i != backIndex) { - work.add(phi.valueAt(i)); - } - } - } - } else { - for (Node in : n.inputs()) { - if (in != null) { - work.add(in); - } - } - if (full) { - for (Node sux : n.cfgSuccessors()) { // go down into branches that are not 'inOfAfter' - if (sux != null && !inOrAfter.isMarked(sux)) { - work.add(sux); - } - } - if (n instanceof LoopBeginNode && n != loop.loopBegin()) { - Loop p = loop.parent; - boolean isParent = false; - while (p != null) { - if (p.loopBegin() == n) { - isParent = true; - break; - } - p = p.parent; - } - if (!isParent) { - work.add(((LoopBeginNode) n).loopEnd()); - } - } - } - if (cfgNodes.isNotNewMarked(n)) { //add all values from the exits framestates - for (Node sux : n.cfgSuccessors()) { - if (loop.exits().isNotNewMarked(sux) && sux instanceof StateSplit) { - FrameState stateAfter = ((StateSplit) sux).stateAfter(); - while (stateAfter != null) { - for (Node in : stateAfter.inputs()) { - if (!(in instanceof FrameState)) { - work.add(in); - } - } - stateAfter = stateAfter.outerFrameState(); - } - } - } - } - if (n instanceof MergeNode) { //add phis & counters - for (Node usage : n.dataUsages()) { - if (!(usage instanceof LoopEndNode)) { - work.add(usage); - } - } - } - if (n instanceof AbstractVectorNode) { - for (Node usage : n.usages()) { - work.add(usage); - } - } - } - } - return inOrBefore; - } - - private static void markWithState(Node n, NodeBitMap map) { - map.mark(n); - if (n instanceof StateSplit) { - FrameState stateAfter = ((StateSplit) n).stateAfter(); - while (stateAfter != null) { - map.mark(stateAfter); - stateAfter = stateAfter.outerFrameState(); - } - } - } - - private static void clearWithState(Node n, NodeBitMap map) { - map.clear(n); - if (n instanceof StateSplit) { - FrameState stateAfter = ((StateSplit) n).stateAfter(); - while (stateAfter != null) { - map.clear(stateAfter); - stateAfter = stateAfter.outerFrameState(); - } - } - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/util/Util.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/util/Util.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,415 +0,0 @@ -/* - * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.compiler.util; - -import java.util.*; - -import com.oracle.max.graal.compiler.*; -import com.oracle.max.graal.compiler.debug.*; -import com.oracle.max.graal.nodes.*; -import com.sun.cri.ci.*; -import com.sun.cri.ri.*; - -/** - * The {@code Util} class contains a motley collection of utility methods used throughout the compiler. - * - * @author Ben L. Titzer - * @author Doug Simon - */ -public class Util { - - public static final int PRINTING_LINE_WIDTH = 40; - public static final char SECTION_CHARACTER = '*'; - public static final char SUB_SECTION_CHARACTER = '='; - public static final char SEPERATOR_CHARACTER = '-'; - - public static RuntimeException unimplemented() { - throw new InternalError("unimplemented"); - } - - public static RuntimeException unimplemented(String msg) { - throw new InternalError("unimplemented:" + msg); - } - - public static RuntimeException shouldNotReachHere() { - throw new InternalError("should not reach here"); - } - - public static RuntimeException shouldNotReachHere(String msg) { - throw new InternalError("should not reach here: " + msg); - } - - public static boolean replaceInList(T a, T b, List list) { - final int max = list.size(); - for (int i = 0; i < max; i++) { - if (list.get(i) == a) { - list.set(i, b); - return true; - } - } - return false; - } - - public static boolean replaceAllInList(T a, T b, List list) { - final int max = list.size(); - for (int i = 0; i < max; i++) { - if (list.get(i) == a) { - list.set(i, b); - } - } - return false; - } - - /** - * Statically cast an object to an arbitrary Object type. Dynamically checked. - */ - @SuppressWarnings("unchecked") - public static T uncheckedCast(Class type, Object object) { - return (T) object; - } - - /** - * Statically cast an object to an arbitrary Object type. Dynamically checked. - */ - @SuppressWarnings("unchecked") - public static T uncheckedCast(Object object) { - return (T) object; - } - - /** - * Utility method to combine a base hash with the identity hash of one or more objects. - * - * @param hash the base hash - * @param x the object to add to the hash - * @return the combined hash - */ - public static int hash1(int hash, Object x) { - // always set at least one bit in case the hash wraps to zero - return 0x10000000 | (hash + 7 * System.identityHashCode(x)); - } - - /** - * Utility method to combine a base hash with the identity hash of one or more objects. - * - * @param hash the base hash - * @param x the first object to add to the hash - * @param y the second object to add to the hash - * @return the combined hash - */ - public static int hash2(int hash, Object x, Object y) { - // always set at least one bit in case the hash wraps to zero - return 0x20000000 | (hash + 7 * System.identityHashCode(x) + 11 * System.identityHashCode(y)); - } - - /** - * Utility method to combine a base hash with the identity hash of one or more objects. - * - * @param hash the base hash - * @param x the first object to add to the hash - * @param y the second object to add to the hash - * @param z the third object to add to the hash - * @return the combined hash - */ - public static int hash3(int hash, Object x, Object y, Object z) { - // always set at least one bit in case the hash wraps to zero - return 0x30000000 | (hash + 7 * System.identityHashCode(x) + 11 * System.identityHashCode(y) + 13 * System.identityHashCode(z)); - } - - /** - * Utility method to combine a base hash with the identity hash of one or more objects. - * - * @param hash the base hash - * @param x the first object to add to the hash - * @param y the second object to add to the hash - * @param z the third object to add to the hash - * @param w the fourth object to add to the hash - * @return the combined hash - */ - public static int hash4(int hash, Object x, Object y, Object z, Object w) { - // always set at least one bit in case the hash wraps to zero - return 0x40000000 | (hash + 7 * System.identityHashCode(x) + 11 * System.identityHashCode(y) + 13 * System.identityHashCode(z) + 17 * System.identityHashCode(w)); - } - - static { - assert CiUtil.log2(2) == 1; - assert CiUtil.log2(4) == 2; - assert CiUtil.log2(8) == 3; - assert CiUtil.log2(16) == 4; - assert CiUtil.log2(32) == 5; - assert CiUtil.log2(0x40000000) == 30; - - assert CiUtil.log2(2L) == 1; - assert CiUtil.log2(4L) == 2; - assert CiUtil.log2(8L) == 3; - assert CiUtil.log2(16L) == 4; - assert CiUtil.log2(32L) == 5; - assert CiUtil.log2(0x4000000000000000L) == 62; - - assert !CiUtil.isPowerOf2(3); - assert !CiUtil.isPowerOf2(5); - assert !CiUtil.isPowerOf2(7); - assert !CiUtil.isPowerOf2(-1); - - assert CiUtil.isPowerOf2(2); - assert CiUtil.isPowerOf2(4); - assert CiUtil.isPowerOf2(8); - assert CiUtil.isPowerOf2(16); - assert CiUtil.isPowerOf2(32); - assert CiUtil.isPowerOf2(64); - } - - /** - * Sets the element at a given position of a list and ensures that this position exists. If the list is current - * shorter than the position, intermediate positions are filled with a given value. - * - * @param list the list to put the element into - * @param pos the position at which to insert the element - * @param x the element that should be inserted - * @param filler the filler element that is used for the intermediate positions in case the list is shorter than pos - */ - public static void atPutGrow(List list, int pos, T x, T filler) { - if (list.size() < pos + 1) { - while (list.size() < pos + 1) { - list.add(filler); - } - assert list.size() == pos + 1; - } - - assert list.size() >= pos + 1; - list.set(pos, x); - } - - public static void breakpoint() { - // do nothing. - } - - public static void guarantee(boolean b, String string) { - if (!b) { - throw new CiBailout(string); - } - } - - public static void warning(String string) { - TTY.println("WARNING: " + string); - } - - public static int safeToInt(long l) { - assert (int) l == l; - return (int) l; - } - - public static int roundUp(int number, int mod) { - return ((number + mod - 1) / mod) * mod; - } - - public static void truncate(List list, int length) { - while (list.size() > length) { - list.remove(list.size() - 1); - } - } - - public static void printSection(String name, char sectionCharacter) { - - String header = " " + name + " "; - int remainingCharacters = PRINTING_LINE_WIDTH - header.length(); - int leftPart = remainingCharacters / 2; - int rightPart = remainingCharacters - leftPart; - for (int i = 0; i < leftPart; i++) { - TTY.print(sectionCharacter); - } - - TTY.print(header); - - for (int i = 0; i < rightPart; i++) { - TTY.print(sectionCharacter); - } - - TTY.println(); - } - - /** - * Prints entries in a byte array as space separated hex values to {@link TTY}. - * - * @param address an address at which the bytes are located. This is used to print an address prefix per line of output. - * @param array the array containing all the bytes to print - * @param bytesPerLine the number of values to print per line of output - */ - public static void printBytes(long address, byte[] array, int bytesPerLine) { - printBytes(address, array, 0, array.length, bytesPerLine); - } - - /** - * Prints entries in a byte array as space separated hex values to {@link TTY}. - * - * @param address an address at which the bytes are located. This is used to print an address prefix per line of output. - * @param array the array containing the bytes to print - * @param offset the offset in {@code array} of the values to print - * @param length the number of values from {@code array} print - * @param bytesPerLine the number of values to print per line of output - */ - public static void printBytes(long address, byte[] array, int offset, int length, int bytesPerLine) { - assert bytesPerLine > 0; - boolean newLine = true; - for (int i = 0; i < length; i++) { - if (newLine) { - TTY.print("%08x: ", address + i); - newLine = false; - } - TTY.print("%02x ", array[i]); - if (i % bytesPerLine == bytesPerLine - 1) { - TTY.println(); - newLine = true; - } - } - - if (length % bytesPerLine != bytesPerLine) { - TTY.println(); - } - } - - public static CiKind[] signatureToKinds(RiSignature signature, CiKind receiverKind) { - int args = signature.argumentCount(false); - CiKind[] result; - int i = 0; - if (receiverKind != null) { - result = new CiKind[args + 1]; - result[0] = receiverKind; - i = 1; - } else { - result = new CiKind[args]; - } - for (int j = 0; j < args; j++) { - result[i + j] = signature.argumentKindAt(j); - } - return result; - } - - public static boolean isShiftCount(int x) { - return 0 <= x && x < 32; - } - - /** - * Determines if a given {@code int} value is the range of unsigned byte values. - */ - public static boolean isUByte(int x) { - return (x & 0xff) == x; - } - - /** - * Determines if a given {@code int} value is the range of signed byte values. - */ - public static boolean isByte(int x) { - return (byte) x == x; - } - - /** - * Determines if a given {@code long} value is the range of unsigned byte values. - */ - public static boolean isUByte(long x) { - return (x & 0xffL) == x; - } - - /** - * Determines if a given {@code long} value is the range of signed byte values. - */ - public static boolean isByte(long l) { - return (byte) l == l; - } - - /** - * Determines if a given {@code long} value is the range of unsigned int values. - */ - public static boolean isUInt(long x) { - return (x & 0xffffffffL) == x; - } - - /** - * Determines if a given {@code long} value is the range of signed int values. - */ - public static boolean isInt(long l) { - return (int) l == l; - } - /** - * Determines if a given {@code int} value is the range of signed short values. - */ - public static boolean isShort(int x) { - return (short) x == x; - } - - public static boolean is32bit(long x) { - return -0x80000000L <= x && x < 0x80000000L; - } - - public static short safeToShort(int v) { - assert isShort(v); - return (short) v; - } - - /** - * Determines if the kinds of two given IR nodes are equal at the {@linkplain #archKind(CiKind) architecture} - * level in the context of the {@linkplain GraalCompilation#compilation()} compilation. - */ - public static boolean archKindsEqual(ValueNode i, ValueNode other) { - return archKindsEqual(i.kind, other.kind); - } - - /** - * Determines if two given kinds are equal at the {@linkplain #archKind(CiKind) architecture} level - * in the context of the {@linkplain GraalCompilation#compilation()} compilation. - */ - public static boolean archKindsEqual(CiKind k1, CiKind k2) { - GraalCompilation compilation = GraalCompilation.compilation(); - assert compilation != null : "missing compilation context"; - return compilation.archKindsEqual(k1, k2); - } - - /** - * Translates a given kind to a {@linkplain GraalCompilation#archKind(CiKind) canonical architecture} - * kind in the context of the {@linkplain GraalCompilation#compilation() current} compilation. - */ - public static CiKind archKind(CiKind kind) { - GraalCompilation compilation = GraalCompilation.compilation(); - assert compilation != null : "missing compilation context"; - return compilation.archKind(kind); - } - - - /** - * Checks that two instructions are equivalent, optionally comparing constants. - * @param x the first instruction - * @param y the second instruction - * @param compareConstants {@code true} if equivalent constants should be considered equivalent - * @return {@code true} if the instructions are equivalent; {@code false} otherwise - */ - public static boolean equivalent(FixedWithNextNode x, FixedWithNextNode y, boolean compareConstants) { - if (x == y) { - return true; - } - if (compareConstants && x != null && y != null) { - if (x.isConstant() && x.asConstant().equivalent(y.asConstant())) { - return true; - } - } - return false; - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/value/FrameStateBuilder.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/value/FrameStateBuilder.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,543 +0,0 @@ -/* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.compiler.value; - -import static com.oracle.max.graal.nodes.ValueUtil.*; -import static java.lang.reflect.Modifier.*; - -import java.util.*; - -import com.oracle.max.graal.graph.*; -import com.oracle.max.graal.nodes.*; -import com.oracle.max.graal.nodes.PhiNode.PhiType; -import com.oracle.max.graal.nodes.spi.*; -import com.sun.cri.ci.*; -import com.sun.cri.ri.*; - - -public class FrameStateBuilder implements FrameStateAccess { - - private final Graph graph; - - private final ValueNode[] locals; - private final ValueNode[] stack; - private final ArrayList locks; - - private int stackIndex; - private boolean rethrowException; - - private final RiMethod method; - - public FrameStateBuilder(FrameState fs) { - this.method = fs.method; - this.graph = fs.graph(); - this.locals = new ValueNode[method.maxLocals()]; - int stackSize = Math.max(1, method.maxStackSize()); - this.stack = new ValueNode[stackSize]; - this.locks = new ArrayList(); - this.initializeFrom(fs); - } - - public FrameStateBuilder(RiMethod method, Graph graph) { - assert graph != null; - this.method = method; - this.graph = graph; - this.locals = new ValueNode[method.maxLocals()]; - // we always need at least one stack slot (for exceptions) - int stackSize = Math.max(1, method.maxStackSize()); - this.stack = new ValueNode[stackSize]; - - int javaIndex = 0; - int index = 0; - if (!isStatic(method.accessFlags())) { - // add the receiver and assume it is non null - LocalNode local = new LocalNode(method.holder().kind(), javaIndex, graph); - local.setDeclaredType(method.holder()); - storeLocal(javaIndex, local); - javaIndex = 1; - index = 1; - } - RiSignature sig = method.signature(); - int max = sig.argumentCount(false); - RiType accessingClass = method.holder(); - for (int i = 0; i < max; i++) { - RiType type = sig.argumentTypeAt(i, accessingClass); - CiKind kind = type.kind().stackKind(); - LocalNode local = new LocalNode(kind, index, graph); - if (type.isResolved()) { - local.setDeclaredType(type); - } - storeLocal(javaIndex, local); - javaIndex += kind.sizeInSlots(); - index++; - } - this.locks = new ArrayList(); - } - - @Override - public String toString() { - return String.format("FrameStateBuilder[stackSize=%d]", stackIndex); - } - - public void initializeFrom(FrameState other) { - assert locals.length == other.localsSize() : "expected: " + locals.length + ", actual: " + other.localsSize(); - assert stack.length >= other.stackSize() : "expected: <=" + stack.length + ", actual: " + other.stackSize(); - - this.stackIndex = other.stackSize(); - for (int i = 0; i < other.localsSize(); i++) { - locals[i] = other.localAt(i); - } - for (int i = 0; i < other.stackSize(); i++) { - stack[i] = other.stackAt(i); - } - locks.clear(); - for (int i = 0; i < other.locksSize(); i++) { - locks.add(other.lockAt(i)); - } - this.rethrowException = other.rethrowException(); - } - - public FrameState create(int bci) { - return new FrameState(method, bci, locals, stack, stackIndex, locks, rethrowException, graph); - } - - public FrameState duplicateWithException(int bci, ValueNode exceptionObject) { - FrameState frameState = new FrameState(method, bci, locals, new ValueNode[]{exceptionObject}, 1, locks, true, graph); - frameState.setOuterFrameState(outerFrameState()); - return frameState; - } - - /** - * Pushes an instruction onto the stack with the expected type. - * @param kind the type expected for this instruction - * @param x the instruction to push onto the stack - */ - public void push(CiKind kind, ValueNode x) { - assert kind != CiKind.Void; - xpush(assertKind(kind, x)); - if (kind.sizeInSlots() == 2) { - xpush(null); - } - } - - /** - * Pushes a value onto the stack without checking the type. - * @param x the instruction to push onto the stack - */ - public void xpush(ValueNode x) { - assert x == null || !x.isDeleted(); - stack[stackIndex++] = x; - } - - /** - * Pushes a value onto the stack and checks that it is an int. - * @param x the instruction to push onto the stack - */ - public void ipush(ValueNode x) { - xpush(assertInt(x)); - } - - /** - * Pushes a value onto the stack and checks that it is a float. - * @param x the instruction to push onto the stack - */ - public void fpush(ValueNode x) { - xpush(assertFloat(x)); - } - - /** - * Pushes a value onto the stack and checks that it is an object. - * @param x the instruction to push onto the stack - */ - public void apush(ValueNode x) { - xpush(assertObject(x)); - } - - /** - * Pushes a value onto the stack and checks that it is a word. - * @param x the instruction to push onto the stack - */ - public void wpush(ValueNode x) { - xpush(assertWord(x)); - } - - /** - * Pushes a value onto the stack and checks that it is a JSR return address. - * @param x the instruction to push onto the stack - */ - public void jpush(ValueNode x) { - xpush(assertJsr(x)); - } - - /** - * Pushes a value onto the stack and checks that it is a long. - * - * @param x the instruction to push onto the stack - */ - public void lpush(ValueNode x) { - xpush(assertLong(x)); - xpush(null); - } - - /** - * Pushes a value onto the stack and checks that it is a double. - * @param x the instruction to push onto the stack - */ - public void dpush(ValueNode x) { - xpush(assertDouble(x)); - xpush(null); - } - - public void pushReturn(CiKind kind, ValueNode x) { - if (kind != CiKind.Void) { - push(kind.stackKind(), x); - } - } - - /** - * Pops an instruction off the stack with the expected type. - * @param kind the expected type - * @return the instruction on the top of the stack - */ - public ValueNode pop(CiKind kind) { - assert kind != CiKind.Void; - if (kind.sizeInSlots() == 2) { - xpop(); - } - return assertKind(kind, xpop()); - } - - /** - * Pops a value off of the stack without checking the type. - * @return x the instruction popped off the stack - */ - public ValueNode xpop() { - ValueNode result = stack[--stackIndex]; - assert result == null || !result.isDeleted(); - return result; - } - - /** - * Pops a value off of the stack and checks that it is an int. - * @return x the instruction popped off the stack - */ - public ValueNode ipop() { - return assertInt(xpop()); - } - - /** - * Pops a value off of the stack and checks that it is a float. - * @return x the instruction popped off the stack - */ - public ValueNode fpop() { - return assertFloat(xpop()); - } - - /** - * Pops a value off of the stack and checks that it is an object. - * @return x the instruction popped off the stack - */ - public ValueNode apop() { - return assertObject(xpop()); - } - - /** - * Pops a value off of the stack and checks that it is a word. - * @return x the instruction popped off the stack - */ - public ValueNode wpop() { - return assertWord(xpop()); - } - - /** - * Pops a value off of the stack and checks that it is a JSR return address. - * @return x the instruction popped off the stack - */ - public ValueNode jpop() { - return assertJsr(xpop()); - } - - /** - * Pops a value off of the stack and checks that it is a long. - * @return x the instruction popped off the stack - */ - public ValueNode lpop() { - assertHigh(xpop()); - return assertLong(xpop()); - } - - /** - * Pops a value off of the stack and checks that it is a double. - * @return x the instruction popped off the stack - */ - public ValueNode dpop() { - assertHigh(xpop()); - return assertDouble(xpop()); - } - - /** - * Pop the specified number of slots off of this stack and return them as an array of instructions. - * @param size the number of arguments off of the stack - * @return an array containing the arguments off of the stack - */ - public ValueNode[] popArguments(int size) { - int base = stackIndex - size; - ValueNode[] r = new ValueNode[size]; - for (int i = 0; i < size; ++i) { - assert stack[base + i] != null || stack[base + i - 1].kind.jvmSlots == 2; - r[i] = stack[base + i]; - } - stackIndex = base; - return r; - } - - public CiKind peekKind() { - ValueNode top = stackAt(stackSize() - 1); - if (top == null) { - top = stackAt(stackSize() - 2); - assert top != null; - assert top.kind.isDoubleWord(); - } - return top.kind; - } - - /** - * Truncates this stack to the specified size. - * @param size the size to truncate to - */ - public void truncateStack(int size) { - stackIndex = size; - assert stackIndex >= 0; - } - - /** - * Clears all values on this stack. - */ - public void clearStack() { - stackIndex = 0; - } - - /** - * Loads the local variable at the specified index. - * - * @param i the index of the local variable to load - * @return the instruction that produced the specified local - */ - public ValueNode loadLocal(int i) { - ValueNode x = locals[i]; - if (x != null) { - if (x instanceof PhiNode) { - assert ((PhiNode) x).type() == PhiType.Value; - if (x.isDeleted()) { - return null; - } - } - assert x.kind.isSingleWord() || locals[i + 1] == null || locals[i + 1] instanceof PhiNode; - } - return x; - } - - /** - * Stores a given local variable at the specified index. If the value is a {@linkplain CiKind#isDoubleWord() double word}, - * then the next local variable index is also overwritten. - * - * @param i the index at which to store - * @param x the instruction which produces the value for the local - */ - public void storeLocal(int i, ValueNode x) { - locals[i] = x; - if (isDoubleWord(x)) { - // (tw) if this was a double word then kill i+1 - locals[i + 1] = null; - } - if (i > 0) { - // if there was a double word at i - 1, then kill it - ValueNode p = locals[i - 1]; - if (isDoubleWord(p)) { - locals[i - 1] = null; - } - } - } - - /** - * Locks a new object within the specified IRScope. - * @param scope the IRScope in which this locking operation occurs - * @param obj the object being locked - */ - public void lock(ValueNode obj) { - locks.add(obj); - } - - /** - * Unlock the lock on the top of the stack. - */ - public void unlock() { - locks.remove(locks.size() - 1); - } - - /** - * Get the value on the stack at the specified stack index. - * - * @param i the index into the stack, with {@code 0} being the bottom of the stack - * @return the instruction at the specified position in the stack - */ - public final ValueNode stackAt(int i) { - return stack[i]; - } - - /** - * Gets the value in the local variables at the specified index. - * - * @param i the index into the locals - * @return the instruction that produced the value for the specified local - */ - public final ValueNode localAt(int i) { - return locals[i]; - } - - /** - * Retrieves the lock at the specified index in the lock stack. - * @param i the index into the lock stack - * @return the instruction which produced the object at the specified location in the lock stack - */ - public final ValueNode lockAt(int i) { - return locks.get(i); - } - - /** - * Returns the size of the local variables. - * - * @return the size of the local variables - */ - public int localsSize() { - return locals.length; - } - - /** - * Gets number of locks held by this frame state. - */ - public int locksSize() { - return locks.size(); - } - - /** - * Gets the current size (height) of the stack. - */ - public int stackSize() { - return stackIndex; - } - - public Iterator locals() { - return new ValueArrayIterator(locals); - } - - public Iterator stack() { - return new ValueArrayIterator(locals); - } - - public List locks() { - return Collections.unmodifiableList(locks); - } - - - private static class ValueArrayIterator implements Iterator { - private final ValueNode[] array; - private int index; - private int length; - - public ValueArrayIterator(ValueNode[] array, int length) { - assert length <= array.length; - this.array = array; - this.index = 0; - } - - public ValueArrayIterator(ValueNode[] array) { - this(array, array.length); - } - - @Override - public boolean hasNext() { - return index < array.length; - } - - @Override - public ValueNode next() { - return array[index++]; - } - - @Override - public void remove() { - throw new UnsupportedOperationException("cannot remove from array"); - } - - } - - - @Override - public FrameState duplicate(int bci) { - return create(bci); - } - - @Override - public ValueNode valueAt(int i) { - if (i < locals.length) { - return locals[i]; - } else if (i < locals.length + stackIndex) { - return stack[i - locals.length]; - } else { - return locks.get(i - locals.length - stack.length); - } - } - - @Override - public void setValueAt(int i, ValueNode v) { - if (i < locals.length) { - locals[i] = v; - } else if (i < locals.length + stackIndex) { - stack[i - locals.length] = v; - } else { - locks.set(i - locals.length - stack.length, v); - } - } - - @Override - public FrameState outerFrameState() { - return null; - } - - public FrameState duplicateWithoutStack(int bci) { - FrameState frameState = new FrameState(method, bci, locals, new ValueNode[0], 0, locks, false, graph); - frameState.setOuterFrameState(outerFrameState()); - return frameState; - } - - @Override - public boolean rethrowException() { - return rethrowException; - } - - @Override - public void setRethrowException(boolean b) { - rethrowException = b; - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/value/package-info.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/value/package-info.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,27 +0,0 @@ -/* - * Copyright (c) 2010, 2010, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -/** - * @author Ben Titzer - */ -package com.oracle.max.graal.compiler.value; diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.examples/.checkstyle --- a/graal/com.oracle.max.graal.examples/.checkstyle Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,10 +0,0 @@ - - - - - - - - - - diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.examples/.checkstyle_checks.xml --- a/graal/com.oracle.max.graal.examples/.checkstyle_checks.xml Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,191 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.examples/.classpath --- a/graal/com.oracle.max.graal.examples/.classpath Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,14 +0,0 @@ - - - - - - - - - - - - - - diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.examples/.project --- a/graal/com.oracle.max.graal.examples/.project Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,29 +0,0 @@ - - - com.oracle.max.graal.examples - - - - - - 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 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.examples/.settings/org.eclipse.jdt.core.prefs --- a/graal/com.oracle.max.graal.examples/.settings/org.eclipse.jdt.core.prefs Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,384 +0,0 @@ -#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 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.examples/.settings/org.eclipse.jdt.ui.prefs --- a/graal/com.oracle.max.graal.examples/.settings/org.eclipse.jdt.ui.prefs Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,75 +0,0 @@ -#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 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.examples/create_examples.xml --- a/graal/com.oracle.max.graal.examples/create_examples.xml Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,14 +0,0 @@ - - - - - - - - - - - - - - diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.examples/runexample.sh --- a/graal/com.oracle.max.graal.examples/runexample.sh Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,23 +0,0 @@ -#!/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 "${GRAAL}" ]; then - echo "GRAAL is not defined. It must point to a maxine repository directory." - exit 1; -fi -if [ -z "${DACAPO}" ]; then - echo "DACAPO is not defined. It must point to a Dacapo benchmark directory." - exit 1; -fi -TEST=$1 -shift -ant -f create_examples.xml -COMMAND="${JDK7}/bin/java -client -d64 -graal -Xmx1g -esa -ea -G:Extend -G:CacheGraphs -XX:+PrintCompilation -Xcomp -XX:CompileOnly=examples -XX:CompileCommand=quiet -XX:CompileCommand=exclude,*, -XX:CompileCommand=exclude,*, -XX:CompileCommand=exclude,*,run -XX:CompileCommand=exclude,com.oracle.max.graal.examples.Main::main $* -jar examples.jar ${TEST}" -# echo $COMMAND -$COMMAND diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.examples/runexample_c1.sh --- a/graal/com.oracle.max.graal.examples/runexample_c1.sh Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,23 +0,0 @@ -#!/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 "${GRAAL}" ]; then - echo "GRAAL is not defined. It must point to a maxine repository directory." - exit 1; -fi -if [ -z "${DACAPO}" ]; then - echo "DACAPO is not defined. It must point to a Dacapo benchmark directory." - exit 1; -fi -TEST=$1 -shift -ant -f create_examples.xml -COMMAND="${JDK7G}/bin/java -client -d64 -Xmx1g -esa -XX:+PrintCFGToFile -XX:+PrintCompilation -Xcomp -XX:CompileOnly=examples -XX:CompileCommand=quiet -XX:CompileCommand=exclude,*, -XX:CompileCommand=exclude,*,run -XX:CompileCommand=exclude,com.oracle.max.graal.examples.Main::main $* -jar examples.jar ${TEST}" -# echo $COMMAND -$COMMAND diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.examples/runexample_c2.sh --- a/graal/com.oracle.max.graal.examples/runexample_c2.sh Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,23 +0,0 @@ -#!/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 "${GRAAL}" ]; then - echo "GRAAL is not defined. It must point to a maxine repository directory." - exit 1; -fi -if [ -z "${DACAPO}" ]; then - echo "DACAPO is not defined. It must point to a Dacapo benchmark directory." - exit 1; -fi -TEST=$1 -shift -ant -f create_examples.xml -COMMAND="${JDK7G}/bin/java -d64 -Xmx1g -esa -XX:+PrintCompilation -XX:PrintIdealGraphLevel=1 -Xcomp -XX:CompileOnly=examples -XX:CompileCommand=quiet -XX:CompileCommand=exclude,*, -XX:CompileCommand=exclude,*,run -XX:CompileCommand=exclude,com.oracle.max.graal.examples.Main::main $* -jar examples.jar ${TEST}" -# echo $COMMAND -$COMMAND diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.examples/runexamplescompare.sh --- a/graal/com.oracle.max.graal.examples/runexamplescompare.sh Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,29 +0,0 @@ -#!/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 "${GRAAL}" ]; then - echo "GRAAL is not defined. It must point to a maxine repository directory." - exit 1; -fi -if [ -z "${DACAPO}" ]; then - echo "DACAPO is not defined. It must point to a Dacapo benchmark directory." - exit 1; -fi -TEST=$1 -shift -ant -f create_examples.xml -COMMAND="${JDK7}/bin/java -client -d64 -graal -Xms1g -Xmx2g -esa -G:Extend -Xcomp -XX:CompileOnly=examples $* -jar examples.jar ${TEST}" -echo $COMMAND -$COMMAND -COMMAND="${JDK7}/bin/java -client -d64 -Xms1g -Xmx2g -esa -Xcomp -XX:CompileOnly=examples $* -jar examples.jar ${TEST}" -echo $COMMAND -$COMMAND -COMMAND="${JDK7}/bin/java -server -d64 -Xms1g -Xmx2g -esa -Xcomp -XX:CompileOnly=examples $* -jar examples.jar ${TEST}" -echo $COMMAND -$COMMAND diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.examples/src/META-INF/services/com.oracle.max.graal.extensions.FrameModifier --- a/graal/com.oracle.max.graal.examples/src/META-INF/services/com.oracle.max.graal.extensions.FrameModifier Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -com.oracle.max.graal.examples.deopt.FrameModifierImpl \ No newline at end of file diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.examples/src/META-INF/services/com.oracle.max.graal.extensions.InliningGuide --- a/graal/com.oracle.max.graal.examples/src/META-INF/services/com.oracle.max.graal.extensions.InliningGuide Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -com.oracle.max.graal.examples.inlining.InliningGuideImpl \ No newline at end of file diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.examples/src/META-INF/services/com.oracle.max.graal.extensions.Intrinsifier --- a/graal/com.oracle.max.graal.examples/src/META-INF/services/com.oracle.max.graal.extensions.Intrinsifier Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -com.oracle.max.graal.examples.intrinsics.IntrinsifierImpl \ No newline at end of file diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.examples/src/META-INF/services/com.oracle.max.graal.extensions.Optimizer --- a/graal/com.oracle.max.graal.examples/src/META-INF/services/com.oracle.max.graal.extensions.Optimizer Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -com.oracle.max.graal.examples.opt.OptimizerImpl \ No newline at end of file diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.examples/src/com/oracle/max/graal/examples/Main.java --- a/graal/com.oracle.max.graal.examples/src/com/oracle/max/graal/examples/Main.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,53 +0,0 @@ -/* - * Copyright (c) 2011, 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.examples; - -import com.oracle.max.graal.examples.deopt.*; -import com.oracle.max.graal.examples.inlining.*; -import com.oracle.max.graal.examples.intrinsics.*; -import com.oracle.max.graal.examples.opt.*; -import com.oracle.max.graal.examples.simple.*; - -public class Main { - - public static void main(String[] args) { - System.err.println("== Graal Examples =="); - if (args.length == 1) { - if (args[0].equals("simple")) { - SimpleExample.run(); - } else if (args[0].equals("inlining")) { - InliningExample.run(); - } else if (args[0].equals("safeadd")) { - SafeAddExample.run(); - } else if (args[0].equals("opt")) { - OptimizationExample.run(); - } else if (args[0].equals("deopt")) { - DeoptExample.run(); - } else { - System.out.println("unknown example: " + args[0]); - } - } else { - System.out.println("usage: java " + Main.class.getSimpleName() + " "); - } - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.examples/src/com/oracle/max/graal/examples/deopt/DeoptExample.java --- a/graal/com.oracle.max.graal.examples/src/com/oracle/max/graal/examples/deopt/DeoptExample.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,55 +0,0 @@ -/* - * Copyright (c) 2011, 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.examples.deopt; - -import com.oracle.max.graal.examples.intrinsics.*; - - -public class DeoptExample { - - public static void run() { - System.out.println(); - System.out.println(); - System.out.println("Running Deopt Example"); - long start = System.currentTimeMillis(); - System.out.println("result1=" + new DeoptExample().test()); - System.out.println("time=" + (System.currentTimeMillis() - start) + "ms"); - } - - private int test() { - try { - return testDeopt(90000); - } catch (IllegalStateException e) { - System.out.println(e.getMessage()); - return 0; - } - } - - private int testDeopt(int n) { - int sum = 0; - for (int i = 0; i < n; i = SafeAddExample.safeAdd(i, 1)) { - sum = SafeAddExample.safeAdd(sum, i); - } - return sum; - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.examples/src/com/oracle/max/graal/examples/deopt/DeoptHandler.java --- a/graal/com.oracle.max.graal.examples/src/com/oracle/max/graal/examples/deopt/DeoptHandler.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,82 +0,0 @@ -/* - * Copyright (c) 2011, 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.examples.deopt; - -import java.lang.reflect.*; - -import com.sun.cri.ri.*; - - -public class DeoptHandler { - - /** - * Deoptimization handler method for methods with a void return parameter. - */ - public void handle_void(RiMethod method, int bci, Object[] values, int numLocals, int numStack, int numLocks) { - handle(method, bci, values, numLocals, numStack, numLocks); - } - - /** - * Deoptimization handler method for methods with an int return parameter. - */ - public int handle_int(RiMethod method, int bci, Object[] values, int numLocals, int numStack, int numLocks) { - handle(method, bci, values, numLocals, numStack, numLocks); - return 123; - } - - /** - * Deoptimization handler method for methods with an object return parameter. - */ - public Object handle_object(RiMethod method, int bci, Object[] values, int numLocals, int numStack, int numLocks) { - handle(method, bci, values, numLocals, numStack, numLocks); - return null; - } - - /** - * Deoptimization handler method: prints the current state of the method execution. - */ - public int handle(RiMethod method, int bci, Object[] values, int numLocals, int numStack, int numLocks) { - System.out.printf("Deoptimization: %s@%d", method.name(), bci); - int p = 0; - System.out.print("\nArguments: "); - int argCount = method.signature().argumentCount(!Modifier.isStatic(method.accessFlags())); - for (int i = 0; i < argCount; i++) { - System.out.printf("%s ", values[p++]); - } - System.out.print("\nLocals: "); - for (int i = argCount; i < numLocals; i++) { - System.out.printf("%s ", values[p++]); - } - System.out.print("\nExpression stack: "); - for (int i = 0; i < numStack; i++) { - System.out.printf("%s ", values[p++]); - } - System.out.print("\nLocks: "); - for (int i = 0; i < numLocks; i++) { - System.out.printf("%s ", values[p++]); - } - System.out.println(); - return 2; - } - -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.examples/src/com/oracle/max/graal/examples/deopt/FrameModifierImpl.java --- a/graal/com.oracle.max.graal.examples/src/com/oracle/max/graal/examples/deopt/FrameModifierImpl.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,77 +0,0 @@ -/* - * Copyright (c) 2011, 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.examples.deopt; - -import java.util.*; - -import com.oracle.max.graal.extensions.*; -import com.sun.cri.ci.*; -import com.sun.cri.ci.CiVirtualObject.CiVirtualObjectFactory; -import com.sun.cri.ri.*; - - -public class FrameModifierImpl implements FrameModifier { - private static DeoptHandler HANDLER = new DeoptHandler(); - - @Override - public CiFrame getFrame(RiRuntime runtime, CiFrame frame) { - if (frame.method.name().equals("testDeopt")) { - // get the handler method - RiType type = runtime.getType(DeoptHandler.class); - CiKind returnKind = frame.method.signature().returnKind(); - String methodName = "handle_" + returnKind; - String methodSignature = "(Lcom/sun/cri/ri/RiMethod;I[Ljava/lang/Object;III)" + returnKind.signatureChar(); - RiMethod handlerMethod = type.getMethod(methodName, methodSignature); - assert handlerMethod != null : methodName + " not found..."; - - // put the current state (local vars, expressions, etc.) into an array - CiVirtualObjectFactory factory = new CiVirtualObjectFactory(runtime); - ArrayList originalValues = new ArrayList(); - for (int i = 0; i < frame.values.length; i += frame.values[i].kind.sizeInSlots()) { - originalValues.add(factory.proxy(frame.values[i])); - } - CiValue boxedValues = factory.arrayProxy(runtime.getType(Object[].class), originalValues.toArray(new CiValue[originalValues.size()])); - - // build the list of arguments - CiValue[] newValues = new CiValue[handlerMethod.maxLocals()]; - int p = 0; - newValues[p++] = CiConstant.forObject(HANDLER); // receiver - newValues[p++] = CiConstant.forObject(frame.method); // method that caused deoptimization - newValues[p++] = CiConstant.forInt(frame.bci); // bytecode index - newValues[p++] = boxedValues; // original locals, expression stack and locks - newValues[p++] = CiConstant.forInt(frame.numLocals); // number of locals - newValues[p++] = CiConstant.forInt(frame.numStack); // size of expression stack - newValues[p++] = CiConstant.forInt(frame.numLocks); // number of locks - - // fill the rest of the local variables with zeros - while (p < newValues.length) { - newValues[p++] = CiValue.IllegalValue; - } - - // ... and return a new frame that points to the start of the handler method - return new CiFrame((CiFrame) frame.caller, handlerMethod, /*bci*/ 0, false, newValues, handlerMethod.maxLocals(), 0, 0); - } - return frame; - } - -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.examples/src/com/oracle/max/graal/examples/inlining/InliningExample.java --- a/graal/com.oracle.max.graal.examples/src/com/oracle/max/graal/examples/inlining/InliningExample.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,70 +0,0 @@ -/* - * Copyright (c) 2011, 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.examples.inlining; - - -public class InliningExample { - - public static void run() { - System.out.println(); - System.out.println(); - System.out.println("Running Inlining Example"); - long start = System.currentTimeMillis(); - System.out.println("result1=" + test()); - System.out.println("result2=" + testFib()); - System.out.println("time=" + (System.currentTimeMillis() - start) + "ms"); - } - - private static int test() { - return alwaysInline(30); - } - - public static int testFib() { - int sum = 0; - for (int i = 0; i < 100000000; ++i) { - sum += fib(5); - } - return sum; - } - - public static int alwaysInline(int value) { - if (value == 0) { - return neverInline(value); - } - return alwaysInline(value - 1); - } - - public static int neverInline(int value) { - if (value == 0) { - return 0; - } - return neverInline(value - 1); - } - - public static int fib(int val) { - if (val == 0 || val == 1) { - return 1; - } - return fib(val - 1) + fib(val - 2); - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.examples/src/com/oracle/max/graal/examples/inlining/InliningGuideImpl.java --- a/graal/com.oracle.max.graal.examples/src/com/oracle/max/graal/examples/inlining/InliningGuideImpl.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,43 +0,0 @@ -/* - * Copyright (c) 2011, 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.examples.inlining; - -import com.oracle.max.graal.extensions.*; -import com.sun.cri.ri.*; - - -public class InliningGuideImpl implements InliningGuide { - - @Override - public InliningHint getHint(int depth, RiMethod caller, int bci, RiMethod target) { - if (target.name().equals("neverInline")) { - return InliningHint.NEVER; - } else if (target.name().equals("alwaysInline") && depth < 50) { - return InliningHint.ALWAYS; - } else if (target.name().equals("fib") && depth < 5) { - return InliningHint.ALWAYS; - } - return InliningHint.NONE; - } - -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.examples/src/com/oracle/max/graal/examples/intrinsics/IntrinsifierImpl.java --- a/graal/com.oracle.max.graal.examples/src/com/oracle/max/graal/examples/intrinsics/IntrinsifierImpl.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,48 +0,0 @@ -/* - * Copyright (c) 2011, 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.examples.intrinsics; - -import java.util.*; - -import com.oracle.max.graal.extensions.*; -import com.oracle.max.graal.graph.*; -import com.oracle.max.graal.nodes.*; -import com.sun.cri.ci.*; -import com.sun.cri.ri.*; - - -public class IntrinsifierImpl implements Intrinsifier { - - @Override - public Graph intrinsicGraph(RiRuntime runtime, RiMethod caller, int bci, RiMethod method, List parameters) { - if (method.holder().name().equals("Lcom/oracle/max/graal/examples/intrinsics/SafeAddExample;") && method.name().equals("safeAdd")) { - CompilerGraph graph = new CompilerGraph(runtime); - ReturnNode returnNode = new ReturnNode(new SafeAddNode(new LocalNode(CiKind.Long, 0, graph), new LocalNode(CiKind.Long, 1, graph), graph), graph); - graph.start().setNext(returnNode); - graph.setReturn(returnNode); - return graph; - } - return null; - } - -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.examples/src/com/oracle/max/graal/examples/intrinsics/SafeAddExample.java --- a/graal/com.oracle.max.graal.examples/src/com/oracle/max/graal/examples/intrinsics/SafeAddExample.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,59 +0,0 @@ -/* - * Copyright (c) 2011, 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.examples.intrinsics; - - -public class SafeAddExample { - - public static final int N = 100000000; - - public static void run() { - System.out.println(); - System.out.println(); - System.out.println("Running SafeAdd Example"); - long start = System.currentTimeMillis(); - System.out.println("result=" + testSafeAdd()); - System.out.println("time=" + (System.currentTimeMillis() - start) + "ms"); - } - - private static int testSafeAdd() { - int sum = 0; - int j = N; - for (int i = -N; i < N; ++i) { - sum = safeAdd(sum, i); - sum = safeAdd(sum, j); - --j; - } - return sum; - } - - public static int safeAdd(int a, int b) { - int result = a + b; - if (b < 0 && result > a) { - throw new IllegalStateException("underflow when adding " + a + " and " + b); - } else if (b > 0 && result < a) { - throw new IllegalStateException("overflow when adding " + a + " and " + b); - } - return result; - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.examples/src/com/oracle/max/graal/examples/intrinsics/SafeAddNode.java --- a/graal/com.oracle.max.graal.examples/src/com/oracle/max/graal/examples/intrinsics/SafeAddNode.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,55 +0,0 @@ -/* - * Copyright (c) 2011, 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.examples.intrinsics; - -import com.oracle.max.graal.graph.*; -import com.oracle.max.graal.nodes.*; -import com.oracle.max.graal.nodes.calc.*; -import com.oracle.max.graal.nodes.spi.*; -import com.sun.cri.bytecode.*; -import com.sun.cri.ci.*; - -@NodeInfo(shortName = "[+]") -public final class SafeAddNode extends IntegerArithmeticNode { - public SafeAddNode(ValueNode x, ValueNode y, Graph graph) { - super(CiKind.Int, Bytecodes.LADD, x, y, graph); - } - - @SuppressWarnings("unchecked") - @Override - public T lookup(Class clazz) { - if (clazz == LIRGeneratorOp.class) { - return (T) GENERATOR_OP; - } - return super.lookup(clazz); - } - - private static final LIRGeneratorOp GENERATOR_OP = new LIRGeneratorOp() { - @Override - public void generate(Node n, LIRGeneratorTool generator) { - SafeAddNode add = (SafeAddNode) n; - generator.integerAdd(add, add.x(), add.y()); - generator.deoptimizeOn(Condition.OF); - } - }; -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.examples/src/com/oracle/max/graal/examples/opt/OptimizationExample.java --- a/graal/com.oracle.max.graal.examples/src/com/oracle/max/graal/examples/opt/OptimizationExample.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,46 +0,0 @@ -/* - * Copyright (c) 2011, 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.examples.opt; - -import com.oracle.max.graal.examples.intrinsics.*; - - -public class OptimizationExample { - - public static void run() { - System.out.println(); - System.out.println(); - System.out.println("Running Optimization Example"); - long start = System.currentTimeMillis(); - System.out.println("result=" + test(1000000000)); - System.out.println("time=" + (System.currentTimeMillis() - start) + "ms"); - } - - private static long test(int n) { - long sum = 0; - for (int i = 0; i < n; i = SafeAddExample.safeAdd(i, 1)) { - sum = sum + i; - } - return sum; - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.examples/src/com/oracle/max/graal/examples/opt/OptimizerImpl.java --- a/graal/com.oracle.max.graal.examples/src/com/oracle/max/graal/examples/opt/OptimizerImpl.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,100 +0,0 @@ -/* - * Copyright (c) 2011, 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.examples.opt; - -import com.oracle.max.graal.compiler.debug.*; -import com.oracle.max.graal.compiler.util.*; -import com.oracle.max.graal.examples.intrinsics.*; -import com.oracle.max.graal.extensions.*; -import com.oracle.max.graal.graph.*; -import com.oracle.max.graal.graph.collections.*; -import com.oracle.max.graal.nodes.*; -import com.oracle.max.graal.nodes.calc.*; -import com.sun.cri.ci.*; -import com.sun.cri.ri.*; - - -public class OptimizerImpl implements Optimizer { - - @Override - public void optimize(RiRuntime runtime, Graph graph) { - // iterate over all instanceof of SafeAddNode in the graph - for (SafeAddNode safeAdd : graph.getNodes(SafeAddNode.class)) { - if (!canOverflow(safeAdd)) { - // if an overflow is impossible: replace with normal add - IntegerAddNode add = new IntegerAddNode(CiKind.Int, safeAdd.x(), safeAdd.y(), graph); - safeAdd.replaceAndDelete(add); - } - } - } - - private boolean canOverflow(SafeAddNode safeAdd) { - // if this SafeAddNode always adds 1 ... - if (safeAdd.y().isConstant() && safeAdd.y().asConstant().asLong() == 1) { - // ... to a phi ... - if (safeAdd.x() instanceof PhiNode) { - PhiNode phi = (PhiNode) safeAdd.x(); - // ... that belongs to a loop and merges into itself ... - if (phi.merge() instanceof LoopBeginNode && phi.valueAt(1) == safeAdd) { - LoopBeginNode loopBegin = (LoopBeginNode) phi.merge(); - // ... then do the heavy analysis. - return canOverflow(phi, loopBegin); - } - } - } - return true; - } - - private boolean canOverflow(PhiNode phi, LoopBeginNode loopBegin) { - NodeBitMap nodes = LoopUtil.markUpCFG(loopBegin); - NodeBitMap exits = LoopUtil.computeLoopExits(loopBegin, nodes); - // look at all loop exits: - for (Node exit : exits) { - TTY.println("exit: " + exit); - Node pred = exit.predecessor(); - // if this exit is an If node ... - if (pred instanceof IfNode) { - IfNode ifNode = (IfNode) pred; - // ... which compares ... - if (ifNode.compare() instanceof CompareNode) { - CompareNode compare = (CompareNode) ifNode.compare(); - Condition cond = compare.condition(); - ValueNode x = compare.x(); - ValueNode y = compare.y(); - if (ifNode.trueSuccessor() == pred) { - cond = cond.negate(); - } - // ... the phi against a value, then this phi cannot overflow. - if (cond == Condition.LT && x == phi) { - return false; - } - if (cond == Condition.GT && y == phi) { - return false; - } - } - } - } - TTY.println("can overflow"); - return true; - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.examples/src/com/oracle/max/graal/examples/simple/SimpleExample.java --- a/graal/com.oracle.max.graal.examples/src/com/oracle/max/graal/examples/simple/SimpleExample.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2011, 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.examples.simple; - - -public class SimpleExample { - - public static void run() { - System.out.println(mulAdd(1, 2, 3)); - System.out.println(divAdd(1, 2, 3)); - } - - private static int mulAdd(int a, int b, int c) { - return a * b + c; - } - - private static int divAdd(int a, int b, int c) { - return a / b + c; - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.extensions/.checkstyle --- a/graal/com.oracle.max.graal.extensions/.checkstyle Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,9 +0,0 @@ - - - - - - - - - diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.extensions/.checkstyle_checks.xml --- a/graal/com.oracle.max.graal.extensions/.checkstyle_checks.xml Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,191 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.extensions/.classpath --- a/graal/com.oracle.max.graal.extensions/.classpath Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,8 +0,0 @@ - - - - - - - - diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.extensions/.project --- a/graal/com.oracle.max.graal.extensions/.project Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,29 +0,0 @@ - - - com.oracle.max.graal.extensions - - - - - - 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 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.extensions/.settings/JavaSourceCodeFormatting.xml --- a/graal/com.oracle.max.graal.extensions/.settings/JavaSourceCodeFormatting.xml Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,264 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.extensions/.settings/org.eclipse.jdt.core.prefs --- a/graal/com.oracle.max.graal.extensions/.settings/org.eclipse.jdt.core.prefs Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,355 +0,0 @@ -#Tue Jul 13 10:33:43 PDT 2010 -eclipse.preferences.version=1 -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.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=warning -org.eclipse.jdt.core.compiler.problem.deadCode=ignore -org.eclipse.jdt.core.compiler.problem.deprecation=warning -org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled -org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled -org.eclipse.jdt.core.compiler.problem.discouragedReference=warning -org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore -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=warning -org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning -org.eclipse.jdt.core.compiler.problem.forbiddenReference=error -org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning -org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning -org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=ignore -org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=warning -org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore -org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning -org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore -org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=ignore -org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=error -org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=disabled -org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning -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=warning -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=warning -org.eclipse.jdt.core.compiler.problem.redundantNullCheck=warning -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=ignore -org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore -org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=warning -org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore -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.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=16 -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=0 -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_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_header=false -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_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=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=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 diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.extensions/.settings/org.eclipse.jdt.ui.prefs --- a/graal/com.oracle.max.graal.extensions/.settings/org.eclipse.jdt.ui.prefs Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,64 +0,0 @@ -#Thu Feb 18 11:36:17 PST 2010 -eclipse.preferences.version=1 -editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true -formatter_profile=_MaxineJavaCodeStyle -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.keywordthis=false -org.eclipse.jdt.ui.ondemandthreshold=0 -org.eclipse.jdt.ui.overrideannotation=true -org.eclipse.jdt.ui.staticondemandthreshold=0 -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_type_abstract_if_missing_method=false -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 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.extensions/LICENSE --- a/graal/com.oracle.max.graal.extensions/LICENSE Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,347 +0,0 @@ -The GNU General Public License (GPL) - -Version 2, June 1991 - -Copyright (C) 1989, 1991 Free Software Foundation, Inc. -59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -Everyone is permitted to copy and distribute verbatim copies of this license -document, but changing it is not allowed. - -Preamble - -The licenses for most software are designed to take away your freedom to share -and change it. By contrast, the GNU General Public License is intended to -guarantee your freedom to share and change free software--to make sure the -software is free for all its users. This General Public License applies to -most of the Free Software Foundation's software and to any other program whose -authors commit to using it. (Some other Free Software Foundation software is -covered by the GNU Library General Public License instead.) You can apply it to -your programs, too. - -When we speak of free software, we are referring to freedom, not price. Our -General Public Licenses are designed to make sure that you have the freedom to -distribute copies of free software (and charge for this service if you wish), -that you receive source code or can get it if you want it, that you can change -the software or use pieces of it in new free programs; and that you know you -can do these things. - -To protect your rights, we need to make restrictions that forbid anyone to deny -you these rights or to ask you to surrender the rights. These restrictions -translate to certain responsibilities for you if you distribute copies of the -software, or if you modify it. - -For example, if you distribute copies of such a program, whether gratis or for -a fee, you must give the recipients all the rights that you have. You must -make sure that they, too, receive or can get the source code. And you must -show them these terms so they know their rights. - -We protect your rights with two steps: (1) copyright the software, and (2) -offer you this license which gives you legal permission to copy, distribute -and/or modify the software. - -Also, for each author's protection and ours, we want to make certain that -everyone understands that there is no warranty for this free software. If the -software is modified by someone else and passed on, we want its recipients to -know that what they have is not the original, so that any problems introduced -by others will not reflect on the original authors' reputations. - -Finally, any free program is threatened constantly by software patents. We -wish to avoid the danger that redistributors of a free program will -individually obtain patent licenses, in effect making the program proprietary. -To prevent this, we have made it clear that any patent must be licensed for -everyone's free use or not licensed at all. - -The precise terms and conditions for copying, distribution and modification -follow. - -TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - -0. This License applies to any program or other work which contains a notice -placed by the copyright holder saying it may be distributed under the terms of -this General Public License. The "Program", below, refers to any such program -or work, and a "work based on the Program" means either the Program or any -derivative work under copyright law: that is to say, a work containing the -Program or a portion of it, either verbatim or with modifications and/or -translated into another language. (Hereinafter, translation is included -without limitation in the term "modification".) Each licensee is addressed as -"you". - -Activities other than copying, distribution and modification are not covered by -this License; they are outside its scope. The act of running the Program is -not restricted, and the output from the Program is covered only if its contents -constitute a work based on the Program (independent of having been made by -running the Program). Whether that is true depends on what the Program does. - -1. You may copy and distribute verbatim copies of the Program's source code as -you receive it, in any medium, provided that you conspicuously and -appropriately publish on each copy an appropriate copyright notice and -disclaimer of warranty; keep intact all the notices that refer to this License -and to the absence of any warranty; and give any other recipients of the -Program a copy of this License along with the Program. - -You may charge a fee for the physical act of transferring a copy, and you may -at your option offer warranty protection in exchange for a fee. - -2. You may modify your copy or copies of the Program or any portion of it, thus -forming a work based on the Program, and copy and distribute such modifications -or work under the terms of Section 1 above, provided that you also meet all of -these conditions: - - a) You must cause the modified files to carry prominent notices stating - that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in whole or - in part contains or is derived from the Program or any part thereof, to be - licensed as a whole at no charge to all third parties under the terms of - this License. - - c) If the modified program normally reads commands interactively when run, - you must cause it, when started running for such interactive use in the - most ordinary way, to print or display an announcement including an - appropriate copyright notice and a notice that there is no warranty (or - else, saying that you provide a warranty) and that users may redistribute - the program under these conditions, and telling the user how to view a copy - of this License. (Exception: if the Program itself is interactive but does - not normally print such an announcement, your work based on the Program is - not required to print an announcement.) - -These requirements apply to the modified work as a whole. If identifiable -sections of that work are not derived from the Program, and can be reasonably -considered independent and separate works in themselves, then this License, and -its terms, do not apply to those sections when you distribute them as separate -works. But when you distribute the same sections as part of a whole which is a -work based on the Program, the distribution of the whole must be on the terms -of this License, whose permissions for other licensees extend to the entire -whole, and thus to each and every part regardless of who wrote it. - -Thus, it is not the intent of this section to claim rights or contest your -rights to work written entirely by you; rather, the intent is to exercise the -right to control the distribution of derivative or collective works based on -the Program. - -In addition, mere aggregation of another work not based on the Program with the -Program (or with a work based on the Program) on a volume of a storage or -distribution medium does not bring the other work under the scope of this -License. - -3. You may copy and distribute the Program (or a work based on it, under -Section 2) in object code or executable form under the terms of Sections 1 and -2 above provided that you also do one of the following: - - a) Accompany it with the complete corresponding machine-readable source - code, which must be distributed under the terms of Sections 1 and 2 above - on a medium customarily used for software interchange; or, - - b) Accompany it with a written offer, valid for at least three years, to - give any third party, for a charge no more than your cost of physically - performing source distribution, a complete machine-readable copy of the - corresponding source code, to be distributed under the terms of Sections 1 - and 2 above on a medium customarily used for software interchange; or, - - c) Accompany it with the information you received as to the offer to - distribute corresponding source code. (This alternative is allowed only - for noncommercial distribution and only if you received the program in - object code or executable form with such an offer, in accord with - Subsection b above.) - -The source code for a work means the preferred form of the work for making -modifications to it. For an executable work, complete source code means all -the source code for all modules it contains, plus any associated interface -definition files, plus the scripts used to control compilation and installation -of the executable. However, as a special exception, the source code -distributed need not include anything that is normally distributed (in either -source or binary form) with the major components (compiler, kernel, and so on) -of the operating system on which the executable runs, unless that component -itself accompanies the executable. - -If distribution of executable or object code is made by offering access to copy -from a designated place, then offering equivalent access to copy the source -code from the same place counts as distribution of the source code, even though -third parties are not compelled to copy the source along with the object code. - -4. You may not copy, modify, sublicense, or distribute the Program except as -expressly provided under this License. Any attempt otherwise to copy, modify, -sublicense or distribute the Program is void, and will automatically terminate -your rights under this License. However, parties who have received copies, or -rights, from you under this License will not have their licenses terminated so -long as such parties remain in full compliance. - -5. You are not required to accept this License, since you have not signed it. -However, nothing else grants you permission to modify or distribute the Program -or its derivative works. These actions are prohibited by law if you do not -accept this License. Therefore, by modifying or distributing the Program (or -any work based on the Program), you indicate your acceptance of this License to -do so, and all its terms and conditions for copying, distributing or modifying -the Program or works based on it. - -6. Each time you redistribute the Program (or any work based on the Program), -the recipient automatically receives a license from the original licensor to -copy, distribute or modify the Program subject to these terms and conditions. -You may not impose any further restrictions on the recipients' exercise of the -rights granted herein. You are not responsible for enforcing compliance by -third parties to this License. - -7. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), conditions -are imposed on you (whether by court order, agreement or otherwise) that -contradict the conditions of this License, they do not excuse you from the -conditions of this License. If you cannot distribute so as to satisfy -simultaneously your obligations under this License and any other pertinent -obligations, then as a consequence you may not distribute the Program at all. -For example, if a patent license would not permit royalty-free redistribution -of the Program by all those who receive copies directly or indirectly through -you, then the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Program. - -If any portion of this section is held invalid or unenforceable under any -particular circumstance, the balance of the section is intended to apply and -the section as a whole is intended to apply in other circumstances. - -It is not the purpose of this section to induce you to infringe any patents or -other property right claims or to contest validity of any such claims; this -section has the sole purpose of protecting the integrity of the free software -distribution system, which is implemented by public license practices. Many -people have made generous contributions to the wide range of software -distributed through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing to -distribute software through any other system and a licensee cannot impose that -choice. - -This section is intended to make thoroughly clear what is believed to be a -consequence of the rest of this License. - -8. If the distribution and/or use of the Program is restricted in certain -countries either by patents or by copyrighted interfaces, the original -copyright holder who places the Program under this License may add an explicit -geographical distribution limitation excluding those countries, so that -distribution is permitted only in or among countries not thus excluded. In -such case, this License incorporates the limitation as if written in the body -of this License. - -9. The Free Software Foundation may publish revised and/or new versions of the -General Public License from time to time. Such new versions will be similar in -spirit to the present version, but may differ in detail to address new problems -or concerns. - -Each version is given a distinguishing version number. If the Program -specifies a version number of this License which applies to it and "any later -version", you have the option of following the terms and conditions either of -that version or of any later version published by the Free Software Foundation. -If the Program does not specify a version number of this License, you may -choose any version ever published by the Free Software Foundation. - -10. If you wish to incorporate parts of the Program into other free programs -whose distribution conditions are different, write to the author to ask for -permission. For software which is copyrighted by the Free Software Foundation, -write to the Free Software Foundation; we sometimes make exceptions for this. -Our decision will be guided by the two goals of preserving the free status of -all derivatives of our free software and of promoting the sharing and reuse of -software generally. - -NO WARRANTY - -11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR -THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE -STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE -PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND -PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, -YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - -12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL -ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE -PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY -GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR -INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA -BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A -FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER -OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. - -END OF TERMS AND CONDITIONS - -How to Apply These Terms to Your New Programs - -If you develop a new program, and you want it to be of the greatest possible -use to the public, the best way to achieve this is to make it free software -which everyone can redistribute and change under these terms. - -To do so, attach the following notices to the program. It is safest to attach -them to the start of each source file to most effectively convey the exclusion -of warranty; and each file should have at least the "copyright" line and a -pointer to where the full notice is found. - - One line to give the program's name and a brief idea of what it does. - - Copyright (C) - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the Free - Software Foundation; either version 2 of the License, or (at your option) - any later version. - - This program 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 for - more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., 59 - Temple Place, Suite 330, Boston, MA 02111-1307 USA - -Also add information on how to contact you by electronic and paper mail. - -If the program is interactive, make it output a short notice like this when it -starts in an interactive mode: - - Gnomovision version 69, Copyright (C) year name of author Gnomovision comes - with ABSOLUTELY NO WARRANTY; for details type 'show w'. This is free - software, and you are welcome to redistribute it under certain conditions; - type 'show c' for details. - -The hypothetical commands 'show w' and 'show c' should show the appropriate -parts of the General Public License. Of course, the commands you use may be -called something other than 'show w' and 'show c'; they could even be -mouse-clicks or menu items--whatever suits your program. - -You should also get your employer (if you work as a programmer) or your school, -if any, to sign a "copyright disclaimer" for the program, if necessary. Here -is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the program - 'Gnomovision' (which makes passes at compilers) written by James Hacker. - - signature of Ty Coon, 1 April 1989 - - Ty Coon, President of Vice - -This General Public License does not permit incorporating your program into -proprietary programs. If your program is a subroutine library, you may -consider it more useful to permit linking proprietary applications with the -library. If this is what you want to do, use the GNU Library General Public -License instead of this License. - - -"CLASSPATH" EXCEPTION TO THE GPL - -Certain source files distributed by Sun Microsystems, Inc. are subject to -the following clarification and special exception to the GPL, but only where -Sun has expressly included in the particular source file's header the words -"Sun designates this particular file as subject to the "Classpath" exception -as provided by Sun in the LICENSE file that accompanied this code." - - Linking this library statically or dynamically with other modules is making - a combined work based on this library. Thus, the terms and conditions of - the GNU General Public License cover the whole combination. - - As a special exception, the copyright holders of this library give you - permission to link this library with independent modules to produce an - executable, regardless of the license terms of these independent modules, - and to copy and distribute the resulting executable under terms of your - choice, provided that you also meet, for each linked independent module, - the terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. If - you modify this library, you may extend this exception to your version of - the library, but you are not obligated to do so. If you do not wish to do - so, delete this exception statement from your version. diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.extensions/src/com/oracle/max/graal/extensions/FrameModifier.java --- a/graal/com.oracle.max.graal.extensions/src/com/oracle/max/graal/extensions/FrameModifier.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,31 +0,0 @@ -/* - * Copyright (c) 2011, 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.extensions; - -import com.sun.cri.ci.*; -import com.sun.cri.ri.*; - - -public interface FrameModifier { - CiFrame getFrame(RiRuntime runtime, CiFrame frame); -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.extensions/src/com/oracle/max/graal/extensions/InliningGuide.java --- a/graal/com.oracle.max.graal.extensions/src/com/oracle/max/graal/extensions/InliningGuide.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,30 +0,0 @@ -/* - * Copyright (c) 2011, 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.extensions; - -import com.sun.cri.ri.*; - - -public interface InliningGuide { - InliningHint getHint(int depth, RiMethod caller, int bci, RiMethod target); -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.extensions/src/com/oracle/max/graal/extensions/InliningHint.java --- a/graal/com.oracle.max.graal.extensions/src/com/oracle/max/graal/extensions/InliningHint.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,32 +0,0 @@ -/* - * Copyright (c) 2011, 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.extensions; - - -public enum InliningHint { - NONE, - NEVER, - LESS, - MORE, - ALWAYS -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.extensions/src/com/oracle/max/graal/extensions/Intrinsifier.java --- a/graal/com.oracle.max.graal.extensions/src/com/oracle/max/graal/extensions/Intrinsifier.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,33 +0,0 @@ -/* - * Copyright (c) 2011, 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.extensions; - -import java.util.*; - -import com.oracle.max.graal.graph.*; -import com.sun.cri.ri.*; - - -public interface Intrinsifier { - Graph intrinsicGraph(RiRuntime runtime, RiMethod caller, int bci, RiMethod method, List parameters); -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.extensions/src/com/oracle/max/graal/extensions/Optimizer.java --- a/graal/com.oracle.max.graal.extensions/src/com/oracle/max/graal/extensions/Optimizer.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,31 +0,0 @@ -/* - * Copyright (c) 2011, 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.extensions; - -import com.oracle.max.graal.graph.*; -import com.sun.cri.ri.*; - - -public interface Optimizer { - void optimize(RiRuntime runtime, Graph graph); -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.graphviz/.checkstyle --- a/graal/com.oracle.max.graal.graphviz/.checkstyle Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,10 +0,0 @@ - - - - - - - - - - diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.graphviz/.classpath --- a/graal/com.oracle.max.graal.graphviz/.classpath Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,9 +0,0 @@ - - - - - - - - - diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.graphviz/.project --- a/graal/com.oracle.max.graal.graphviz/.project Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,23 +0,0 @@ - - - com.oracle.max.graal.graphviz - - - - - - org.eclipse.jdt.core.javabuilder - - - - - net.sf.eclipsecs.core.CheckstyleBuilder - - - - - - org.eclipse.jdt.core.javanature - net.sf.eclipsecs.core.CheckstyleNature - - diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.graphviz/.settings/org.eclipse.jdt.core.prefs --- a/graal/com.oracle.max.graal.graphviz/.settings/org.eclipse.jdt.core.prefs Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,270 +0,0 @@ -#Wed Apr 27 22:10:44 CEST 2011 -eclipse.preferences.version=1 -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.problem.assertIdentifier=error -org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -org.eclipse.jdt.core.compiler.source=1.6 -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_enum_constant=16 -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=0 -org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16 -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_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_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=insert -org.eclipse.jdt.core.formatter.comment.line_length=120 -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.format_guardian_clause_on_one_line=false -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_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_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=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=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_tabs_only_for_leading_indentations=false -org.eclipse.jdt.core.formatter.wrap_before_binary_operator=false diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.graphviz/.settings/org.eclipse.jdt.ui.prefs --- a/graal/com.oracle.max.graal.graphviz/.settings/org.eclipse.jdt.ui.prefs Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,4 +0,0 @@ -#Wed Apr 27 22:10:44 CEST 2011 -eclipse.preferences.version=1 -formatter_profile=_C1XJavaCodeStyle -formatter_settings_version=11 diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.graphviz/src/com/oracle/max/graal/graphviz/GraphvizPrinter.java --- a/graal/com.oracle.max.graal.graphviz/src/com/oracle/max/graal/graphviz/GraphvizPrinter.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,203 +0,0 @@ -/* - * Copyright (c) 2011, 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.graphviz; - -import java.awt.Color; -import java.io.OutputStream; -import java.io.PrintStream; -import java.util.HashMap; -import java.util.HashSet; - -import com.oracle.max.graal.graph.Graph; -import com.oracle.max.graal.graph.Node; -import com.oracle.max.graal.graph.NodeInputsIterable; -import com.oracle.max.graal.graph.NodeSuccessorsIterable; - -/** - * Generates a representation of {@link Node Nodes} or entire {@link Graph Graphs} in the DOT language that can be - * visualized with Graphviz. - */ -public class GraphvizPrinter { - - public static final Color NODE_BGCOLOR = Color.WHITE; - private static final String NODE_BGCOLOR_STRING = formatColorString(NODE_BGCOLOR); - - private static String formatColorString(Color c) { - return String.format("#%02x%02x%02x%02x", c.getRed(), c.getGreen(), c.getBlue(), c.getAlpha()); - } - - private final PrintStream out; - private final HashSet> omittedClasses = new HashSet>(); - private final HashMap, String> classColors = new HashMap, String>(); - - /** - * Creates a new {@link GraphvizPrinter} that writes to the specified output stream. - */ - public GraphvizPrinter(OutputStream out) { - this.out = new PrintStream(out); - } - - public void addOmittedClass(Class clazz) { - omittedClasses.add(clazz); - } - - public void addClassColor(Class clazz, String color) { - classColors.put(clazz, color); - } - - /** - * Opens a graph with the specified title (label). Call this before printing any nodes, but not more than once - * without calling {@link #end()} first. - * - * @param title - * The graph's label. - */ - public void begin(String title) { - out.println("digraph g {"); - if (title != null) { - out.println(" label=\"" + title + "\";"); - } - } - - /** - * Closes the graph. No nodes should be printed afterwards. Another graph can be opened with {@link #begin(String)}, - * but many Graphviz output plugins ignore additional graphs in their input. - */ - public void end() { - out.println("}"); - } - - /** - * Prints all nodes and edges in the specified graph. - */ - public void print(Graph graph, boolean shortNames) { - // graph.getNodes() returns all the graph's nodes, not just "roots" - for (Node n : graph.getNodes()) { - printNode(n, shortNames); - } - } - - /** - * Prints a single node and edges for all its inputs and successors. - */ - public void printNode(Node node, boolean shortNames) { - if (omittedClasses.contains(node.getClass())) { - return; - } - int id = node.id(); - String name = "n" + id; - NodeInputsIterable inputs = node.inputs(); - NodeSuccessorsIterable successors = node.successors(); - - String color = classColors.get(node.getClass()); - - if (shortNames) { - printNode(name, node.id(), excapeLabel(node.shortName()), color, inputs.explicitCount(), successors.explicitCount()); - } else { - printNode(name, node.id(), excapeLabel(node.toString()), color, inputs.explicitCount(), successors.explicitCount()); - } - - int i = 0; - for (Node successor : successors) { - if (successor != Node.Null && !omittedClasses.contains(successor.getClass())) { - printControlEdge(id, i, successor.id()); - } - i++; - } - - i = 0; - for (Node input : inputs) { - if (input != Node.Null && !omittedClasses.contains(input.getClass())) { - if (node.getClass().getSimpleName().equals("FrameState") && input.getClass().getSimpleName().equals("Local")) { - continue; - } - printDataEdge(id, i, input.id()); - } - i++; - } - } - - private void printNode(String name, Number number, String label, String color, int ninputs, int nsuccessors) { - int minWidth = Math.min(1 + label.length() / 3, 10); - minWidth = Math.max(minWidth, Math.max(ninputs + 1, nsuccessors + 1)); - out.println(name + " [shape=plaintext,"); - out.println(" label=< "); - - printPort("predecessors", "rosybrown1"); - - for (int i = 1; i < minWidth - ninputs; i++) { - printEmptyPort(); - } - - for (int i = 0; i < ninputs; i++) { - printPort("in" + i, "lightgrey"); - } - - if (number != null) { - label = "" + number + " " + label; - } - - out.println(" "); - - for (int i = 0; i < nsuccessors; i++) { - printPort("succ" + i, "rosybrown1"); - } - - for (int i = 1; i < minWidth - nsuccessors; i++) { - printEmptyPort(); - } - - printPort("usages", "lightgrey"); - - out.println("
" + label + "
>]; "); - } - - private static String excapeLabel(String label) { - label = label.replace("&", "&"); - label = label.replace("<", "<"); - label = label.replace(">", ">"); - label = label.replace("\"", """); - return label; - } - - private void printPort(String name, String color) { - out.print("
"); - } - - private void printEmptyPort() { - out.print("
"); - } - - private void printControlEdge(int from, int fromPort, int to) { - out.println("n" + from + ":succ" + fromPort + ":s -> n" + to + ":predecessors:n [color=red, weight=2];"); - } - - private void printDataEdge(int from, int fromPort, int to) { - out.println("n" + to + ":usages:s -> n" + from + ":in" + fromPort + ":n [color=black,dir=back];"); - } - -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.graphviz/src/com/oracle/max/graal/graphviz/GraphvizRunner.java --- a/graal/com.oracle.max.graal.graphviz/src/com/oracle/max/graal/graphviz/GraphvizRunner.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,91 +0,0 @@ -/* - * Copyright (c) 2011, 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.graphviz; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; - -/** - * Provides functionality to process graphs in the DOT language with a Graphviz tool and obtain the generated output. - */ -public class GraphvizRunner { - - public static final String DOT_LAYOUT = "dot"; - - /** - * Processes data from an input stream with a Graphviz tool such as {@code dot}, writing output in the specified - * format to the given output stream. The method waits for the executed tool to finish and then returns its exit - * code. - * - * @param layout - * The Graphviz layouter to use (e.g. "dot"). - * @param in - * Stream to read input from. - * @param out - * Stream to write output to. - * @param format - * Desired output format (-T parameter). - * @return Exit code of the called utility. - * @throws IOException - * When the process can not be started (e.g. Graphviz missing) or reading/writing a stream fails. - */ - public static int process(String layout, InputStream in, OutputStream out, String format) throws IOException { - byte[] buffer = new byte[4096]; - - // create and start process - ProcessBuilder pb = new ProcessBuilder("dot", "-T", format, "-K", layout); - Process p = pb.start(); - - // write data from in to stdin - OutputStream stdin = p.getOutputStream(); - transfer(buffer, in, stdin); - stdin.close(); - in.close(); - - // read output from stdout and write to out - InputStream stdout = p.getInputStream(); - transfer(buffer, stdout, out); - stdout.close(); - - // wait for process to terminate - for (;;) { - try { - return p.waitFor(); - } catch (InterruptedException e) { - // ignore - } - } - } - - /** - * Reads all data from an {@link InputStream} and writes it to an {@link OutputStream}, using the provided buffer. - */ - private static void transfer(byte[] buffer, InputStream in, OutputStream out) throws IOException { - int count; - while ((count = in.read(buffer, 0, buffer.length)) != -1) { - out.write(buffer, 0, count); - } - in.close(); - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.graphviz/test/com/oracle/graal/graph/vis/GraphvizTest.java --- a/graal/com.oracle.max.graal.graphviz/test/com/oracle/graal/graph/vis/GraphvizTest.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,117 +0,0 @@ -/* - * Copyright (c) 2011, 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.graal.graph.vis; - -import static org.junit.Assert.assertEquals; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.OutputStream; - -import org.junit.Test; - -import com.oracle.max.graal.graph.Graph; -import com.oracle.max.graal.graph.Node; -import com.oracle.max.graal.graph.NodeInputList; -import com.oracle.max.graal.graph.NodeSuccessorList; -import com.oracle.max.graal.graphviz.GraphvizPrinter; -import com.oracle.max.graal.graphviz.GraphvizRunner; - -/** - * Tests for the Graphviz graph generator. Needs Graphviz (more specifically, dot) installed to verify produced output. - */ -public class GraphvizTest { - - @Test - public void testSimpleGraph() throws IOException { - Graph g = new Graph(); - - DummyNode start = new DummyNode("start", 0, 1, g); - - DummyNode ifnode = new DummyNode("if", 2, 2, g); - start.setSuccessor(0, ifnode); - - // branch 1 - DummyNode nop = new DummyNode("nop", 0, 1, g); - ifnode.setSuccessor(0, nop); - - // branch 2 - DummyNode a = new DummyNode("a", 0, 1, g); - DummyNode b = new DummyNode("b", 0, 1, g); - DummyNode plus = new DummyNode("+", 2, 1, g); - plus.setInput(0, a); - plus.setInput(1, b); - ifnode.setSuccessor(1, plus); - - DummyNode end = new DummyNode("end", 0, 1, g); - plus.setSuccessor(0, end); - nop.setSuccessor(0, end); - - ByteArrayOutputStream out = new ByteArrayOutputStream(); - GraphvizPrinter printer = new GraphvizPrinter(out); - printer.begin("Simple test"); - printer.print(g, false); - printer.end(); - - int exitCode = GraphvizRunner.process(GraphvizRunner.DOT_LAYOUT, new ByteArrayInputStream(out.toByteArray()), new NullOutputStream(), "xdot"); - assertEquals(0, exitCode); - } - - private static class DummyNode extends Node { - - @Input private final NodeInputList inputs; - - @Successor private final NodeSuccessorList successors; - - public DummyNode(String name, int inputCount, int successorCount, Graph graph) { - super(graph); - this.name = name; - inputs = new NodeInputList(this, inputCount); - successors = new NodeSuccessorList(this, successorCount); - } - - public void setInput(int idx, Node n) { - inputs.set(idx, n); - } - - public void setSuccessor(int idx, Node n) { - successors.set(idx, n); - } - - private final String name; - - @Override - public String toString() { - return name; - } - } - - private static class NullOutputStream extends OutputStream { - - @Override - public void write(int b) throws IOException { - } - } - -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.nodes/.checkstyle --- a/graal/com.oracle.max.graal.nodes/.checkstyle Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,9 +0,0 @@ - - - - - - - - - diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.nodes/.checkstyle_checks.xml --- a/graal/com.oracle.max.graal.nodes/.checkstyle_checks.xml Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,191 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.nodes/.classpath --- a/graal/com.oracle.max.graal.nodes/.classpath Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,8 +0,0 @@ - - - - - - - - diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.nodes/.project --- a/graal/com.oracle.max.graal.nodes/.project Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,29 +0,0 @@ - - - com.oracle.max.graal.nodes - - - - - - 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 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.nodes/.settings/JavaSourceCodeFormatting.xml --- a/graal/com.oracle.max.graal.nodes/.settings/JavaSourceCodeFormatting.xml Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,264 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.nodes/.settings/org.eclipse.jdt.core.prefs --- a/graal/com.oracle.max.graal.nodes/.settings/org.eclipse.jdt.core.prefs Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,355 +0,0 @@ -#Tue Jul 13 10:33:43 PDT 2010 -eclipse.preferences.version=1 -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.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=warning -org.eclipse.jdt.core.compiler.problem.deadCode=ignore -org.eclipse.jdt.core.compiler.problem.deprecation=warning -org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled -org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled -org.eclipse.jdt.core.compiler.problem.discouragedReference=warning -org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore -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=warning -org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning -org.eclipse.jdt.core.compiler.problem.forbiddenReference=error -org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning -org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning -org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=ignore -org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=warning -org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore -org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning -org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore -org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=ignore -org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=error -org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=disabled -org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning -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=warning -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=warning -org.eclipse.jdt.core.compiler.problem.redundantNullCheck=warning -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=ignore -org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore -org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=warning -org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore -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.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=16 -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=0 -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_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_header=false -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_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=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=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 diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.nodes/.settings/org.eclipse.jdt.ui.prefs --- a/graal/com.oracle.max.graal.nodes/.settings/org.eclipse.jdt.ui.prefs Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,64 +0,0 @@ -#Thu Feb 18 11:36:17 PST 2010 -eclipse.preferences.version=1 -editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true -formatter_profile=_MaxineJavaCodeStyle -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.keywordthis=false -org.eclipse.jdt.ui.ondemandthreshold=0 -org.eclipse.jdt.ui.overrideannotation=true -org.eclipse.jdt.ui.staticondemandthreshold=0 -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_type_abstract_if_missing_method=false -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 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.nodes/LICENSE --- a/graal/com.oracle.max.graal.nodes/LICENSE Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,347 +0,0 @@ -The GNU General Public License (GPL) - -Version 2, June 1991 - -Copyright (C) 1989, 1991 Free Software Foundation, Inc. -59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -Everyone is permitted to copy and distribute verbatim copies of this license -document, but changing it is not allowed. - -Preamble - -The licenses for most software are designed to take away your freedom to share -and change it. By contrast, the GNU General Public License is intended to -guarantee your freedom to share and change free software--to make sure the -software is free for all its users. This General Public License applies to -most of the Free Software Foundation's software and to any other program whose -authors commit to using it. (Some other Free Software Foundation software is -covered by the GNU Library General Public License instead.) You can apply it to -your programs, too. - -When we speak of free software, we are referring to freedom, not price. Our -General Public Licenses are designed to make sure that you have the freedom to -distribute copies of free software (and charge for this service if you wish), -that you receive source code or can get it if you want it, that you can change -the software or use pieces of it in new free programs; and that you know you -can do these things. - -To protect your rights, we need to make restrictions that forbid anyone to deny -you these rights or to ask you to surrender the rights. These restrictions -translate to certain responsibilities for you if you distribute copies of the -software, or if you modify it. - -For example, if you distribute copies of such a program, whether gratis or for -a fee, you must give the recipients all the rights that you have. You must -make sure that they, too, receive or can get the source code. And you must -show them these terms so they know their rights. - -We protect your rights with two steps: (1) copyright the software, and (2) -offer you this license which gives you legal permission to copy, distribute -and/or modify the software. - -Also, for each author's protection and ours, we want to make certain that -everyone understands that there is no warranty for this free software. If the -software is modified by someone else and passed on, we want its recipients to -know that what they have is not the original, so that any problems introduced -by others will not reflect on the original authors' reputations. - -Finally, any free program is threatened constantly by software patents. We -wish to avoid the danger that redistributors of a free program will -individually obtain patent licenses, in effect making the program proprietary. -To prevent this, we have made it clear that any patent must be licensed for -everyone's free use or not licensed at all. - -The precise terms and conditions for copying, distribution and modification -follow. - -TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - -0. This License applies to any program or other work which contains a notice -placed by the copyright holder saying it may be distributed under the terms of -this General Public License. The "Program", below, refers to any such program -or work, and a "work based on the Program" means either the Program or any -derivative work under copyright law: that is to say, a work containing the -Program or a portion of it, either verbatim or with modifications and/or -translated into another language. (Hereinafter, translation is included -without limitation in the term "modification".) Each licensee is addressed as -"you". - -Activities other than copying, distribution and modification are not covered by -this License; they are outside its scope. The act of running the Program is -not restricted, and the output from the Program is covered only if its contents -constitute a work based on the Program (independent of having been made by -running the Program). Whether that is true depends on what the Program does. - -1. You may copy and distribute verbatim copies of the Program's source code as -you receive it, in any medium, provided that you conspicuously and -appropriately publish on each copy an appropriate copyright notice and -disclaimer of warranty; keep intact all the notices that refer to this License -and to the absence of any warranty; and give any other recipients of the -Program a copy of this License along with the Program. - -You may charge a fee for the physical act of transferring a copy, and you may -at your option offer warranty protection in exchange for a fee. - -2. You may modify your copy or copies of the Program or any portion of it, thus -forming a work based on the Program, and copy and distribute such modifications -or work under the terms of Section 1 above, provided that you also meet all of -these conditions: - - a) You must cause the modified files to carry prominent notices stating - that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in whole or - in part contains or is derived from the Program or any part thereof, to be - licensed as a whole at no charge to all third parties under the terms of - this License. - - c) If the modified program normally reads commands interactively when run, - you must cause it, when started running for such interactive use in the - most ordinary way, to print or display an announcement including an - appropriate copyright notice and a notice that there is no warranty (or - else, saying that you provide a warranty) and that users may redistribute - the program under these conditions, and telling the user how to view a copy - of this License. (Exception: if the Program itself is interactive but does - not normally print such an announcement, your work based on the Program is - not required to print an announcement.) - -These requirements apply to the modified work as a whole. If identifiable -sections of that work are not derived from the Program, and can be reasonably -considered independent and separate works in themselves, then this License, and -its terms, do not apply to those sections when you distribute them as separate -works. But when you distribute the same sections as part of a whole which is a -work based on the Program, the distribution of the whole must be on the terms -of this License, whose permissions for other licensees extend to the entire -whole, and thus to each and every part regardless of who wrote it. - -Thus, it is not the intent of this section to claim rights or contest your -rights to work written entirely by you; rather, the intent is to exercise the -right to control the distribution of derivative or collective works based on -the Program. - -In addition, mere aggregation of another work not based on the Program with the -Program (or with a work based on the Program) on a volume of a storage or -distribution medium does not bring the other work under the scope of this -License. - -3. You may copy and distribute the Program (or a work based on it, under -Section 2) in object code or executable form under the terms of Sections 1 and -2 above provided that you also do one of the following: - - a) Accompany it with the complete corresponding machine-readable source - code, which must be distributed under the terms of Sections 1 and 2 above - on a medium customarily used for software interchange; or, - - b) Accompany it with a written offer, valid for at least three years, to - give any third party, for a charge no more than your cost of physically - performing source distribution, a complete machine-readable copy of the - corresponding source code, to be distributed under the terms of Sections 1 - and 2 above on a medium customarily used for software interchange; or, - - c) Accompany it with the information you received as to the offer to - distribute corresponding source code. (This alternative is allowed only - for noncommercial distribution and only if you received the program in - object code or executable form with such an offer, in accord with - Subsection b above.) - -The source code for a work means the preferred form of the work for making -modifications to it. For an executable work, complete source code means all -the source code for all modules it contains, plus any associated interface -definition files, plus the scripts used to control compilation and installation -of the executable. However, as a special exception, the source code -distributed need not include anything that is normally distributed (in either -source or binary form) with the major components (compiler, kernel, and so on) -of the operating system on which the executable runs, unless that component -itself accompanies the executable. - -If distribution of executable or object code is made by offering access to copy -from a designated place, then offering equivalent access to copy the source -code from the same place counts as distribution of the source code, even though -third parties are not compelled to copy the source along with the object code. - -4. You may not copy, modify, sublicense, or distribute the Program except as -expressly provided under this License. Any attempt otherwise to copy, modify, -sublicense or distribute the Program is void, and will automatically terminate -your rights under this License. However, parties who have received copies, or -rights, from you under this License will not have their licenses terminated so -long as such parties remain in full compliance. - -5. You are not required to accept this License, since you have not signed it. -However, nothing else grants you permission to modify or distribute the Program -or its derivative works. These actions are prohibited by law if you do not -accept this License. Therefore, by modifying or distributing the Program (or -any work based on the Program), you indicate your acceptance of this License to -do so, and all its terms and conditions for copying, distributing or modifying -the Program or works based on it. - -6. Each time you redistribute the Program (or any work based on the Program), -the recipient automatically receives a license from the original licensor to -copy, distribute or modify the Program subject to these terms and conditions. -You may not impose any further restrictions on the recipients' exercise of the -rights granted herein. You are not responsible for enforcing compliance by -third parties to this License. - -7. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), conditions -are imposed on you (whether by court order, agreement or otherwise) that -contradict the conditions of this License, they do not excuse you from the -conditions of this License. If you cannot distribute so as to satisfy -simultaneously your obligations under this License and any other pertinent -obligations, then as a consequence you may not distribute the Program at all. -For example, if a patent license would not permit royalty-free redistribution -of the Program by all those who receive copies directly or indirectly through -you, then the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Program. - -If any portion of this section is held invalid or unenforceable under any -particular circumstance, the balance of the section is intended to apply and -the section as a whole is intended to apply in other circumstances. - -It is not the purpose of this section to induce you to infringe any patents or -other property right claims or to contest validity of any such claims; this -section has the sole purpose of protecting the integrity of the free software -distribution system, which is implemented by public license practices. Many -people have made generous contributions to the wide range of software -distributed through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing to -distribute software through any other system and a licensee cannot impose that -choice. - -This section is intended to make thoroughly clear what is believed to be a -consequence of the rest of this License. - -8. If the distribution and/or use of the Program is restricted in certain -countries either by patents or by copyrighted interfaces, the original -copyright holder who places the Program under this License may add an explicit -geographical distribution limitation excluding those countries, so that -distribution is permitted only in or among countries not thus excluded. In -such case, this License incorporates the limitation as if written in the body -of this License. - -9. The Free Software Foundation may publish revised and/or new versions of the -General Public License from time to time. Such new versions will be similar in -spirit to the present version, but may differ in detail to address new problems -or concerns. - -Each version is given a distinguishing version number. If the Program -specifies a version number of this License which applies to it and "any later -version", you have the option of following the terms and conditions either of -that version or of any later version published by the Free Software Foundation. -If the Program does not specify a version number of this License, you may -choose any version ever published by the Free Software Foundation. - -10. If you wish to incorporate parts of the Program into other free programs -whose distribution conditions are different, write to the author to ask for -permission. For software which is copyrighted by the Free Software Foundation, -write to the Free Software Foundation; we sometimes make exceptions for this. -Our decision will be guided by the two goals of preserving the free status of -all derivatives of our free software and of promoting the sharing and reuse of -software generally. - -NO WARRANTY - -11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR -THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE -STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE -PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND -PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, -YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - -12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL -ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE -PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY -GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR -INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA -BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A -FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER -OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. - -END OF TERMS AND CONDITIONS - -How to Apply These Terms to Your New Programs - -If you develop a new program, and you want it to be of the greatest possible -use to the public, the best way to achieve this is to make it free software -which everyone can redistribute and change under these terms. - -To do so, attach the following notices to the program. It is safest to attach -them to the start of each source file to most effectively convey the exclusion -of warranty; and each file should have at least the "copyright" line and a -pointer to where the full notice is found. - - One line to give the program's name and a brief idea of what it does. - - Copyright (C) - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the Free - Software Foundation; either version 2 of the License, or (at your option) - any later version. - - This program 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 for - more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., 59 - Temple Place, Suite 330, Boston, MA 02111-1307 USA - -Also add information on how to contact you by electronic and paper mail. - -If the program is interactive, make it output a short notice like this when it -starts in an interactive mode: - - Gnomovision version 69, Copyright (C) year name of author Gnomovision comes - with ABSOLUTELY NO WARRANTY; for details type 'show w'. This is free - software, and you are welcome to redistribute it under certain conditions; - type 'show c' for details. - -The hypothetical commands 'show w' and 'show c' should show the appropriate -parts of the General Public License. Of course, the commands you use may be -called something other than 'show w' and 'show c'; they could even be -mouse-clicks or menu items--whatever suits your program. - -You should also get your employer (if you work as a programmer) or your school, -if any, to sign a "copyright disclaimer" for the program, if necessary. Here -is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the program - 'Gnomovision' (which makes passes at compilers) written by James Hacker. - - signature of Ty Coon, 1 April 1989 - - Ty Coon, President of Vice - -This General Public License does not permit incorporating your program into -proprietary programs. If your program is a subroutine library, you may -consider it more useful to permit linking proprietary applications with the -library. If this is what you want to do, use the GNU Library General Public -License instead of this License. - - -"CLASSPATH" EXCEPTION TO THE GPL - -Certain source files distributed by Sun Microsystems, Inc. are subject to -the following clarification and special exception to the GPL, but only where -Sun has expressly included in the particular source file's header the words -"Sun designates this particular file as subject to the "Classpath" exception -as provided by Sun in the LICENSE file that accompanied this code." - - Linking this library statically or dynamically with other modules is making - a combined work based on this library. Thus, the terms and conditions of - the GNU General Public License cover the whole combination. - - As a special exception, the copyright holders of this library give you - permission to link this library with independent modules to produce an - executable, regardless of the license terms of these independent modules, - and to copy and distribute the resulting executable under terms of your - choice, provided that you also meet, for each linked independent module, - the terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. If - you modify this library, you may extend this exception to your version of - the library, but you are not obligated to do so. If you do not wish to do - so, delete this exception statement from your version. diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/AnchorNode.java --- a/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/AnchorNode.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,48 +0,0 @@ -/* - * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.nodes; - -import com.oracle.max.graal.graph.*; -import com.oracle.max.graal.nodes.spi.*; -import com.sun.cri.ci.*; - -/** - * The {@code Anchor} instruction represents the end of a block with an unconditional jump to another block. - */ -public final class AnchorNode extends FixedWithNextNode { - - @Input private final NodeInputList guards = new NodeInputList(this); - - public AnchorNode(Graph graph) { - super(CiKind.Illegal, graph); - } - - public void addGuard(GuardNode x) { - guards.add(x); - } - - @Override - public void accept(ValueVisitor v) { - v.visitAnchor(this); - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/BooleanNode.java --- a/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/BooleanNode.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,35 +0,0 @@ -/* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.nodes; - -import com.oracle.max.graal.graph.*; -import com.oracle.max.graal.nodes.calc.*; -import com.sun.cri.ci.*; - - -public abstract class BooleanNode extends FloatingNode { - - public BooleanNode(CiKind kind, Graph graph) { - super(kind, graph); - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/CastNode.java --- a/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/CastNode.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,67 +0,0 @@ -/* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.nodes; - -import com.oracle.max.graal.graph.*; -import com.oracle.max.graal.nodes.calc.*; -import com.oracle.max.graal.nodes.spi.*; -import com.sun.cri.ci.*; - - -public final class CastNode extends FloatingNode { - @Input private ValueNode value; - - public ValueNode value() { - return value; - } - - public void setValue(ValueNode x) { - updateUsages(value, x); - value = x; - } - - public CastNode(CiKind kind, ValueNode n, Graph graph) { - super(kind, graph); - setValue(n); - } - - @Override - public void accept(ValueVisitor v) { - } - - - @SuppressWarnings("unchecked") - @Override - public T lookup(Class clazz) { - if (clazz == LIRGeneratorOp.class) { - return (T) new LIRGeneratorOp() { - @Override - public void generate(Node n, LIRGeneratorTool generator) { - CastNode conv = (CastNode) n; - conv.setOperand(generator.load(conv.value())); - } - }; - } - return super.lookup(clazz); - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/CompilerGraph.java --- a/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/CompilerGraph.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,66 +0,0 @@ -/* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.nodes; - -import com.oracle.max.graal.graph.*; -import com.sun.cri.ci.*; -import com.sun.cri.ri.*; - - -public class CompilerGraph extends Graph { - - private RiRuntime runtime; - private ReturnNode returnSingleton; - private UnwindNode unwindSingleton; - private CiAssumptions assumptions = new CiAssumptions(); - - public CompilerGraph(RiRuntime runtime) { - this.runtime = runtime; - } - - public void setReturn(ReturnNode returnNode) { - assert returnSingleton == null; - returnSingleton = returnNode; - } - - public ReturnNode getReturn() { - return returnSingleton; - } - - public void setUnwind(UnwindNode unwind) { - assert unwindSingleton == null; - unwindSingleton = unwind; - } - - public UnwindNode getUnwind() { - return unwindSingleton; - } - - public RiRuntime runtime() { - return runtime; - } - - public CiAssumptions assumptions() { - return assumptions; - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/ConstantNode.java --- a/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/ConstantNode.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,178 +0,0 @@ -/* - * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.nodes; - -import com.oracle.max.graal.graph.*; -import com.oracle.max.graal.nodes.spi.*; -import com.sun.cri.ci.*; -import com.sun.cri.ri.*; - -/** - * The {@code Constant} instruction represents a constant such as an integer value, - * long, float, object reference, address, etc. - */ -public final class ConstantNode extends BooleanNode { - - @Data public final CiConstant value; - - /** - * Constructs a new instruction representing the specified constant. - * @param value the constant - * @param graph - */ - public ConstantNode(CiConstant value, Graph graph) { - super(value.kind.stackKind(), graph); - this.value = value; - } - - @Override - public void accept(ValueVisitor v) { - v.visitConstant(this); - } - - /** - * Creates an instruction for a double constant. - * @param d the double value for which to create the instruction - * @param graph - * @return an instruction representing the double - */ - public static ConstantNode forDouble(double d, Graph graph) { - return new ConstantNode(CiConstant.forDouble(d), graph); - } - - /** - * Creates an instruction for a float constant. - * @param f the float value for which to create the instruction - * @return an instruction representing the float - */ - public static ConstantNode forFloat(float f, Graph graph) { - return new ConstantNode(CiConstant.forFloat(f), graph); - } - - /** - * Creates an instruction for an long constant. - * @param i the long value for which to create the instruction - * @return an instruction representing the long - */ - public static ConstantNode forLong(long i, Graph graph) { - return new ConstantNode(CiConstant.forLong(i), graph); - } - - /** - * Creates an instruction for an integer constant. - * @param i the integer value for which to create the instruction - * @return an instruction representing the integer - */ - public static ConstantNode forInt(int i, Graph graph) { - return new ConstantNode(CiConstant.forInt(i), graph); - } - - /** - * Creates an instruction for a boolean constant. - * @param i the boolean value for which to create the instruction - * @return an instruction representing the boolean - */ - public static ConstantNode forBoolean(boolean i, Graph graph) { - return new ConstantNode(CiConstant.forBoolean(i), graph); - } - - /** - * Creates an instruction for an address (jsr/ret address) constant. - * @param i the address value for which to create the instruction - * @return an instruction representing the address - */ - public static ConstantNode forJsr(int i, Graph graph) { - return new ConstantNode(CiConstant.forJsr(i), graph); - } - - /** - * Creates an instruction for an object constant. - * @param o the object value for which to create the instruction - * @return an instruction representing the object - */ - public static ConstantNode forObject(Object o, Graph graph) { - return new ConstantNode(CiConstant.forObject(o), graph); - } - - /** - * Creates an instruction for a word constant. - * @param val the word value for which to create the instruction - * @return an instruction representing the word - */ - public static ConstantNode forWord(long val, Graph graph) { - return new ConstantNode(CiConstant.forWord(val), graph); - } - - public static ConstantNode defaultForKind(CiKind kind, Graph graph) { - switch(kind) { - case Boolean: - return ConstantNode.forBoolean(false, graph); - case Byte: - case Char: - case Short: - case Int: - return ConstantNode.forInt(0, graph); - case Double: - return ConstantNode.forDouble(0.0, graph); - case Float: - return ConstantNode.forFloat(0.0f, graph); - case Long: - return ConstantNode.forLong(0L, graph); - case Object: - return ConstantNode.forObject(null, graph); - case Word: - return ConstantNode.forWord(0L, graph); - default: - return null; - } - } - - @Override - public String toString() { - return super.toString() + "(" + value + ")"; - } - - @Override - public int valueNumber() { - return 0x50000000 | value.hashCode(); - } - - @Override - public RiType declaredType() { - RiRuntime runtime = ((CompilerGraph) graph()).runtime(); - if (kind.isPrimitive()) { - return runtime.asRiType(kind); - } - return runtime.getTypeOf(asConstant()); - } - - @Override - public RiType exactType() { - return declaredType(); - } - - @Override - public String shortName() { - return value.name(); - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/ControlSplitNode.java --- a/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/ControlSplitNode.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,121 +0,0 @@ -/* - * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.nodes; - -import java.util.*; - -import com.oracle.max.graal.graph.*; -import com.sun.cri.ci.*; - -/** - * The {@code BlockEnd} instruction is a base class for all instructions that end a basic - * block, including branches, switches, throws, and goto's. - */ -public abstract class ControlSplitNode extends FixedNode { - - @Successor private final NodeSuccessorList blockSuccessors; - - public FixedNode blockSuccessor(int index) { - return blockSuccessors.get(index); - } - - public void setBlockSuccessor(int index, FixedNode x) { - blockSuccessors.set(index, x); - } - - public int blockSuccessorCount() { - return blockSuccessors.size(); - } - - protected final double[] branchProbability; - - /** - * Constructs a new block end with the specified value type. - * @param kind the type of the value produced by this instruction - * @param successors the list of successor blocks. If {@code null}, a new one will be created. - */ - public ControlSplitNode(CiKind kind, List blockSuccessors, double[] branchProbability, Graph graph) { - this(kind, blockSuccessors.size(), branchProbability, graph); - for (int i = 0; i < blockSuccessors.size(); i++) { - setBlockSuccessor(i, blockSuccessors.get(i)); - } - } - - public ControlSplitNode(CiKind kind, int blockSuccessorCount, double[] branchProbability, Graph graph) { - super(kind, graph); - this.blockSuccessors = new NodeSuccessorList(this, blockSuccessorCount); - assert branchProbability.length == blockSuccessorCount; - this.branchProbability = branchProbability; - } - - public double probability(int successorIndex) { - return branchProbability[successorIndex]; - } - - public void setProbability(int successorIndex, double x) { - branchProbability[successorIndex] = x; - } - - /** - * Gets the successor corresponding to the default (fall through) case. - * @return the default successor - */ - public FixedNode defaultSuccessor() { - return blockSuccessor(blockSuccessorCount() - 1); - } - - public Iterable blockSuccessors() { - return new Iterable() { - @Override - public Iterator iterator() { - return new Iterator() { - int i = 0; - @Override - public void remove() { - throw new UnsupportedOperationException(); - } - @Override - public FixedNode next() { - return ControlSplitNode.this.blockSuccessor(i++); - } - - @Override - public boolean hasNext() { - return i < ControlSplitNode.this.blockSuccessorCount(); - } - }; - } - }; - } - - @Override - public Map getDebugProperties() { - Map properties = super.getDebugProperties(); - StringBuilder str = new StringBuilder(); - for (int i = 0; i < branchProbability.length; i++) { - str.append(i == 0 ? "" : ", ").append(String.format("%7.5f", branchProbability[i])); - } - properties.put("branchProbability", str.toString()); - return properties; - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/DeoptimizeNode.java --- a/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/DeoptimizeNode.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,74 +0,0 @@ -/* - * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.nodes; - -import java.util.*; - -import com.oracle.max.graal.graph.*; -import com.oracle.max.graal.nodes.spi.*; -import com.sun.cri.ci.*; - -@NodeInfo(shortName = "Deopt") -public class DeoptimizeNode extends FixedNode { - - public static enum DeoptAction { - None, // just interpret, do not invalidate nmethod - Recompile, // recompile the nmethod; need not invalidate - InvalidateReprofile, // invalidate the nmethod, reset IC, maybe recompile - InvalidateRecompile, // invalidate the nmethod, recompile (probably) - InvalidateStopCompiling, // invalidate the nmethod and do not compile - } - - private String message; - private final DeoptAction action; - - public DeoptimizeNode(DeoptAction action, Graph graph) { - super(CiKind.Illegal, graph); - this.action = action; - } - - public void setMessage(String message) { - this.message = message; - } - - public String message() { - return message; - } - - public DeoptAction action() { - return action; - } - - @Override - public void accept(ValueVisitor v) { - v.visitDeoptimize(this); - } - - @Override - public Map getDebugProperties() { - Map properties = super.getDebugProperties(); - properties.put("message", message); - properties.put("action", action); - return properties; - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/EndNode.java --- a/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/EndNode.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,71 +0,0 @@ -/* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.nodes; - -import java.util.*; - -import com.oracle.max.graal.graph.*; -import com.oracle.max.graal.nodes.spi.*; -import com.sun.cri.ci.*; - - -public final class EndNode extends FixedNode { - - public EndNode(Graph graph) { - super(CiKind.Illegal, graph); - } - - @Override - public void accept(ValueVisitor v) { - v.visitEndNode(this); - } - - public MergeNode merge() { - if (usages().size() == 0) { - return null; - } else { - assert usages().size() == 1; - return (MergeNode) usages().iterator().next(); - } - } - - @Override - public boolean verify() { - assertTrue(usages().size() <= 1, "at most one usage"); - return true; - } - - @Override - public Iterable< ? extends Node> dataUsages() { - return Collections.emptyList(); - } - - @Override - public Iterable< ? extends Node> cfgSuccessors() { - MergeNode merge = this.merge(); - if (merge == null) { - return Collections.emptyList(); - } - return Arrays.asList(merge); - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/FixedGuardNode.java --- a/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/FixedGuardNode.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,70 +0,0 @@ -/* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.nodes; - -import com.oracle.max.graal.graph.*; -import com.oracle.max.graal.nodes.DeoptimizeNode.DeoptAction; -import com.oracle.max.graal.nodes.spi.*; -import com.sun.cri.ci.*; - -public final class FixedGuardNode extends FixedWithNextNode implements Canonicalizable { - - @Input private final NodeInputList conditions = new NodeInputList(this); - - public FixedGuardNode(BooleanNode node, Graph graph) { - this(graph); - addNode(node); - } - - public FixedGuardNode(Graph graph) { - super(CiKind.Illegal, graph); - } - - @Override - public void accept(ValueVisitor v) { - v.visitFixedGuard(this); - } - - public void addNode(BooleanNode x) { - conditions.add(x); - } - - @Override - public Node canonical(NotifyReProcess reProcess) { - for (BooleanNode n : conditions.snapshot()) { - if (n instanceof ConstantNode) { - ConstantNode c = (ConstantNode) n; - if (c.asConstant().asBoolean()) { - conditions.remove(n); - } else { - return new DeoptimizeNode(DeoptAction.InvalidateRecompile, graph()); - } - } - } - - if (conditions.isEmpty()) { - return next(); - } - return this; - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/FixedNode.java --- a/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/FixedNode.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,57 +0,0 @@ -/* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.nodes; - -import java.util.*; - -import com.oracle.max.graal.graph.*; -import com.sun.cri.ci.*; - -public abstract class FixedNode extends ValueNode { - - private double probability; - - public FixedNode(CiKind kind, Graph graph) { - super(kind, graph); - } - - public double probability() { - return probability; - } - - public void setProbability(double probability) { - this.probability = probability; - } - - protected void copyInto(FixedNode newNode) { - newNode.setProbability(probability); - } - - @Override - public Map getDebugProperties() { - Map properties = super.getDebugProperties(); - properties.put("probability", String.format(Locale.ENGLISH, "%7.5f", probability)); - return properties; - } - -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/FixedWithNextNode.java --- a/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/FixedWithNextNode.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,50 +0,0 @@ -/* - * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.nodes; - -import com.oracle.max.graal.graph.*; -import com.sun.cri.ci.*; - -public abstract class FixedWithNextNode extends FixedNode { - - @Successor private FixedNode next; - - public FixedNode next() { - return next; - } - - public void setNext(FixedNode x) { - updatePredecessors(next, x); - next = x; - } - - public static final int SYNCHRONIZATION_ENTRY_BCI = -1; - - /** - * Constructs a new instruction with the specified value type. - * @param kind the value type for this instruction - */ - public FixedWithNextNode(CiKind kind, Graph graph) { - super(kind, graph); - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/FrameState.java --- a/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/FrameState.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,671 +0,0 @@ -/* - * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.nodes; - -import java.util.*; - -import com.oracle.max.graal.graph.*; -import com.oracle.max.graal.nodes.PhiNode.PhiType; -import com.oracle.max.graal.nodes.calc.*; -import com.oracle.max.graal.nodes.spi.*; -import com.oracle.max.graal.nodes.virtual.*; -import com.sun.cri.ci.*; -import com.sun.cri.ri.*; - -/** - * The {@code FrameState} class encapsulates the frame state (i.e. local variables and - * operand stack) at a particular point in the abstract interpretation. - */ -public final class FrameState extends ValueNode implements FrameStateAccess { - - protected final int localsSize; - - protected final int stackSize; - - protected final int locksSize; - - private boolean rethrowException; - - public static final int BEFORE_BCI = -2; - public static final int AFTER_BCI = -3; - - @Input private FrameState outerFrameState; - - @Input private final NodeInputList values; - - @Input private final NodeInputList virtualObjectMappings; - - public FrameState outerFrameState() { - return outerFrameState; - } - - public void setOuterFrameState(FrameState x) { - updateUsages(this.outerFrameState, x); - this.outerFrameState = x; - } - - @Override - public void setValueAt(int i, ValueNode x) { - values.set(i, x); - } - - /** - * The bytecode index to which this frame state applies. This will be {@code -1} - * iff this state is mutable. - */ - public final int bci; - - public final RiMethod method; - - /** - * Creates a {@code FrameState} for the given scope and maximum number of stack and local variables. - * - * @param bci the bytecode index of the frame state - * @param localsSize number of locals - * @param stackSize size of the stack - * @param lockSize number of locks - */ - public FrameState(RiMethod method, int bci, int localsSize, int stackSize, int locksSize, boolean rethrowException, Graph graph) { - super(CiKind.Illegal, graph); - this.method = method; - this.bci = bci; - this.localsSize = localsSize; - this.stackSize = stackSize; - this.locksSize = locksSize; - this.values = new NodeInputList(this, localsSize + stackSize + locksSize); - this.virtualObjectMappings = new NodeInputList(this); - this.rethrowException = rethrowException; - //GraalMetrics.FrameStatesCreated++; - //GraalMetrics.FrameStateValuesCreated += localsSize + stackSize + locksSize; - } - - public FrameState(RiMethod method, int bci, ValueNode[] locals, ValueNode[] stack, int stackSize, ArrayList locks, boolean rethrowException, Graph graph) { - this(method, bci, locals.length, stackSize, locks.size(), rethrowException, graph); - for (int i = 0; i < locals.length; i++) { - setValueAt(i, locals[i]); - } - for (int i = 0; i < stackSize; i++) { - setValueAt(localsSize + i, stack[i]); - } - for (int i = 0; i < locks.size(); i++) { - setValueAt(locals.length + stackSize + i, locks.get(i)); - } - } - - public boolean rethrowException() { - return rethrowException; - } - - public RiMethod method() { - return method; - } - - public void addVirtualObjectMapping(Node virtualObject) { - assert virtualObject instanceof VirtualObjectFieldNode || virtualObject instanceof PhiNode : virtualObject; - virtualObjectMappings.add(virtualObject); - } - - public int virtualObjectMappingCount() { - return virtualObjectMappings.size(); - } - - public Node virtualObjectMappingAt(int i) { - return virtualObjectMappings.get(i); - } - - public Iterable virtualObjectMappings() { - return virtualObjectMappings; - } - - /** - * Gets a copy of this frame state. - */ - public FrameState duplicate(int bci) { - return duplicate(bci, false); - } - - public FrameState duplicate(int bci, boolean duplicateOuter) { - FrameState other = new FrameState(method, bci, localsSize, stackSize, locksSize, rethrowException, graph()); - other.values.setAll(values); - other.virtualObjectMappings.setAll(virtualObjectMappings); - FrameState outerFrameState = outerFrameState(); - if (duplicateOuter && outerFrameState != null) { - outerFrameState = outerFrameState.duplicate(outerFrameState.bci, duplicateOuter); - } - other.setOuterFrameState(outerFrameState); - return other; - } - - @Override - public FrameState duplicateWithException(int bci, ValueNode exceptionObject) { - return duplicateModified(bci, true, CiKind.Void, exceptionObject); - } - - /** - * Creates a copy of this frame state with one stack element of type popKind popped from the stack and the - * values in pushedValues pushed on the stack. The pushedValues are expected to be in slot encoding: a long - * or double is followed by a null slot. - */ - public FrameState duplicateModified(int bci, boolean rethrowException, CiKind popKind, ValueNode... pushedValues) { - int popSlots = popKind.sizeInSlots(); - int pushSlots = pushedValues.length; - FrameState other = new FrameState(method, bci, localsSize, stackSize - popSlots + pushSlots, locksSize(), rethrowException, graph()); - for (int i = 0; i < localsSize; i++) { - other.setValueAt(i, localAt(i)); - } - for (int i = 0; i < stackSize - popSlots; i++) { - other.setValueAt(localsSize + i, stackAt(i)); - } - int slot = localsSize + stackSize - popSlots; - for (int i = 0; i < pushSlots; i++) { - other.setValueAt(slot++, pushedValues[i]); - } - for (int i = 0; i < locksSize; i++) { - other.setValueAt(localsSize + other.stackSize + i, lockAt(i)); - } - other.virtualObjectMappings.setAll(virtualObjectMappings); - other.setOuterFrameState(outerFrameState()); - return other; - } - - public boolean isCompatibleWith(FrameStateAccess other) { - if (stackSize() != other.stackSize() || localsSize() != other.localsSize() || locksSize() != other.locksSize()) { - return false; - } - for (int i = 0; i < stackSize(); i++) { - ValueNode x = stackAt(i); - ValueNode y = other.stackAt(i); - if (x != y && ValueUtil.typeMismatch(x, y)) { - return false; - } - } - for (int i = 0; i < locksSize(); i++) { - if (lockAt(i) != other.lockAt(i)) { - return false; - } - } - if (other.outerFrameState() != outerFrameState()) { - return false; - } - return true; - } - - public boolean equals(FrameStateAccess other) { - if (stackSize() != other.stackSize() || localsSize() != other.localsSize() || locksSize() != other.locksSize()) { - return false; - } - for (int i = 0; i < stackSize(); i++) { - ValueNode x = stackAt(i); - ValueNode y = other.stackAt(i); - if (x != y) { - return false; - } - } - for (int i = 0; i < locksSize(); i++) { - if (lockAt(i) != other.lockAt(i)) { - return false; - } - } - if (other.outerFrameState() != outerFrameState()) { - return false; - } - return true; - } - - /** - * Gets the size of the local variables. - */ - public int localsSize() { - return localsSize; - } - - /** - * Gets the current size (height) of the stack. - */ - public int stackSize() { - return stackSize; - } - - /** - * Gets number of locks held by this frame state. - */ - public int locksSize() { - return locksSize; - } - - /** - * Invalidates the local variable at the specified index. If the specified index refers to a doubleword local, then - * invalidates the high word as well. - * - * @param i the index of the local to invalidate - */ - public void invalidateLocal(int i) { - // note that for double word locals, the high slot should already be null - // unless the local is actually dead and the high slot is being reused; - // in either case, it is not necessary to null the high slot - setValueAt(i, null); - } - - /** - * Stores a given local variable at the specified index. If the value is a {@linkplain CiKind#isDoubleWord() double word}, - * then the next local variable index is also overwritten. - * - * @param i the index at which to store - * @param x the instruction which produces the value for the local - */ - public void storeLocal(int i, ValueNode x) { - assert i < localsSize : "local variable index out of range: " + i; - invalidateLocal(i); - setValueAt(i, x); - if (ValueUtil.isDoubleWord(x)) { - // (tw) if this was a double word then kill i+1 - setValueAt(i + 1, null); - } - if (i > 0) { - // if there was a double word at i - 1, then kill it - ValueNode p = localAt(i - 1); - if (ValueUtil.isDoubleWord(p)) { - setValueAt(i - 1, null); - } - } - } - - /** - * Gets the value in the local variables at the specified index. - * - * @param i the index into the locals - * @return the instruction that produced the value for the specified local - */ - public ValueNode localAt(int i) { - assert i < localsSize : "local variable index out of range: " + i; - return valueAt(i); - } - - /** - * Get the value on the stack at the specified stack index. - * - * @param i the index into the stack, with {@code 0} being the bottom of the stack - * @return the instruction at the specified position in the stack - */ - public ValueNode stackAt(int i) { - assert i >= 0 && i < (localsSize + stackSize); - return valueAt(localsSize + i); - } - - /** - * Retrieves the lock at the specified index in the lock stack. - * @param i the index into the lock stack - * @return the instruction which produced the object at the specified location in the lock stack - */ - public ValueNode lockAt(int i) { - assert i >= 0; - return valueAt(localsSize + stackSize + i); - } - - /** - * Inserts a phi statement into the stack at the specified stack index. - * @param block the block begin for which we are creating the phi - * @param i the index into the stack for which to create a phi - */ - public PhiNode setupPhiForStack(MergeNode block, int i) { - ValueNode p = stackAt(i); - if (p != null) { - if (p instanceof PhiNode) { - PhiNode phi = (PhiNode) p; - if (phi.merge() == block) { - return phi; - } - } - PhiNode phi = new PhiNode(p.kind, block, PhiType.Value, graph()); - setValueAt(localsSize + i, phi); - return phi; - } - return null; - } - - /** - * Inserts a phi statement for the local at the specified index. - * @param block the block begin for which we are creating the phi - * @param i the index of the local variable for which to create the phi - */ - public PhiNode setupPhiForLocal(MergeNode block, int i) { - ValueNode p = localAt(i); - if (p instanceof PhiNode) { - PhiNode phi = (PhiNode) p; - if (phi.merge() == block) { - return phi; - } - } - PhiNode phi = new PhiNode(p.kind, block, PhiType.Value, graph()); - storeLocal(i, phi); - return phi; - } - - /** - * Gets the value at a specified index in the set of operand stack and local values represented by this frame. - * This method should only be used to iterate over all the values in this frame, irrespective of whether - * they are on the stack or in local variables. - * To iterate the stack slots, the {@link #stackAt(int)} and {@link #stackSize()} methods should be used. - * To iterate the local variables, the {@link #localAt(int)} and {@link #localsSize()} methods should be used. - * - * @param i a value in the range {@code [0 .. valuesSize()]} - * @return the value at index {@code i} which may be {@code null} - */ - public ValueNode valueAt(int i) { - assert i < (localsSize + stackSize + locksSize); - return values.isEmpty() ? null : values.get(i); - } - - /** - * The number of operand stack slots and local variables in this frame. - * This method should typically only be used in conjunction with {@link #valueAt(int)}. - * To iterate the stack slots, the {@link #stackAt(int)} and {@link #stackSize()} methods should be used. - * To iterate the local variables, the {@link #localAt(int)} and {@link #localsSize()} methods should be used. - * - * @return the number of local variables in this frame - */ - public int valuesSize() { - return localsSize + stackSize; - } - - private void checkSize(FrameStateAccess other) { - if (other.stackSize() != stackSize()) { - throw new CiBailout("stack sizes do not match"); - } else if (other.localsSize() != localsSize) { - throw new CiBailout("local sizes do not match"); - } - } - - public void merge(MergeNode block, FrameStateAccess other) { - checkSize(other); - for (int i = 0; i < valuesSize(); i++) { - ValueNode x = valueAt(i); - if (x != null) { - ValueNode y = other.valueAt(i); - if (x != y || ((x instanceof PhiNode) && ((PhiNode) x).merge() == block)) { - if (ValueUtil.typeMismatch(x, y)) { - if ((x instanceof PhiNode) && ((PhiNode) x).merge() == block) { - x.replaceAtUsages(null); - x.delete(); - } - setValueAt(i, null); - continue; - } - PhiNode phi = null; - if (i < localsSize) { - // this a local - phi = setupPhiForLocal(block, i); - } else { - // this is a stack slot - phi = setupPhiForStack(block, i - localsSize); - } - - if (phi.valueCount() == 0) { - int size = block.phiPredecessorCount(); - for (int j = 0; j < size; ++j) { - phi.addInput(x); - } - phi.addInput((x == y) ? phi : y); - } else { - phi.addInput((x == y) ? phi : y); - } - - assert phi.valueCount() == block.phiPredecessorCount() + (block instanceof LoopBeginNode ? 0 : 1) : "valueCount=" + phi.valueCount() + " predSize= " + block.phiPredecessorCount(); - } - } - } - } - - public MergeNode block() { - for (Node n : usages()) { - if (n instanceof MergeNode) { - return (MergeNode) n; - } - } - return null; - } - - public StateSplit stateSplit() { - for (Node n : usages()) { - if (n instanceof StateSplit) { - return (StateSplit) n; - } - } - return null; - } - - public Iterable innerFrameStates() { - final Iterator iterator = usages().iterator(); - return new Iterable() { - @Override - public Iterator iterator() { - return new Iterator() { - private Node next; - @Override - public void remove() { - throw new UnsupportedOperationException(); - } - @Override - public FrameState next() { - forward(); - if (!hasNext()) { - throw new NoSuchElementException(); - } - FrameState res = (FrameState) next; - next = null; - return res; - } - @Override - public boolean hasNext() { - forward(); - return next != null; - } - private void forward() { - while (!(next instanceof FrameState) && iterator.hasNext()) { - next = iterator.next(); - } - } - }; - } - }; - } - - /** - * The interface implemented by a client of {@link FrameState#forEachPhi(MergeNode, PhiProcedure)} and - * {@link FrameState#forEachLivePhi(MergeNode, PhiProcedure)}. - */ - public static interface PhiProcedure { - boolean doPhi(PhiNode phi); - } - - /** - * Checks whether this frame state has any {@linkplain PhiNode phi} statements. - */ - public boolean hasPhis() { - for (int i = 0; i < valuesSize(); i++) { - ValueNode value = valueAt(i); - if (value instanceof PhiNode) { - return true; - } - } - return false; - } - - /** - * The interface implemented by a client of {@link FrameState#forEachLiveStateValue(ValueProcedure)}. - */ - public static interface ValueProcedure { - void doValue(ValueNode value); - } - - /** - * Traverses all {@linkplain ValueNode#isLive() live values} of this frame state. - * - * @param proc the call back called to process each live value traversed - */ - public void forEachLiveStateValue(ValueProcedure proc) { - HashSet vobjs = null; - FrameState current = this; - do { - for (int i = 0; i < current.valuesSize(); i++) { - ValueNode value = current.valueAt(i); - if (value instanceof VirtualObjectNode) { - if (vobjs == null) { - vobjs = new HashSet(); - } - vobjs.add((VirtualObjectNode) value); - } else if (value != null) { - proc.doValue(value); - } - } - current = current.outerFrameState(); - } while (current != null); - - if (vobjs != null) { - // collect all VirtualObjectField instances: - HashMap objectStates = new HashMap(); - current = this; - do { - for (int i = 0; i < current.virtualObjectMappingCount(); i++) { - VirtualObjectFieldNode field = (VirtualObjectFieldNode) current.virtualObjectMappingAt(i); - // null states occur for objects with 0 fields - if (field != null && !objectStates.containsKey(field.object())) { - objectStates.put(field.object(), field); - } - } - current = current.outerFrameState(); - } while (current != null); - - do { - HashSet vobjsCopy = new HashSet(vobjs); - for (VirtualObjectNode vobj : vobjsCopy) { - if (vobj.fields().length > 0) { - boolean[] fieldState = new boolean[vobj.fields().length]; - FloatingNode currentField = objectStates.get(vobj); - assert currentField != null : this; - do { - if (currentField instanceof VirtualObjectFieldNode) { - int index = ((VirtualObjectFieldNode) currentField).index(); - ValueNode value = ((VirtualObjectFieldNode) currentField).input(); - if (!fieldState[index]) { - fieldState[index] = true; - if (value instanceof VirtualObjectNode) { - vobjs.add((VirtualObjectNode) value); - } else { - proc.doValue(value); - } - } - currentField = ((VirtualObjectFieldNode) currentField).lastState(); - } else { - assert currentField instanceof PhiNode : currentField; - currentField = (FloatingNode) ((PhiNode) currentField).valueAt(0); - } - } while (currentField != null); - } - vobjs.remove(vobj); - } - } while (!vobjs.isEmpty()); - assert vobjs.isEmpty() : "at FrameState " + this; - } - } - - @Override - public String toString() { - return super.toString(); - } - - public String toDetailedString() { - StringBuilder sb = new StringBuilder(); - String nl = String.format("%n"); - sb.append("[bci: ").append(bci).append("]"); - if (rethrowException()) { - sb.append(" rethrows Exception"); - } - sb.append(nl); - for (int i = 0; i < localsSize(); ++i) { - ValueNode value = localAt(i); - sb.append(String.format(" local[%d] = %-8s : %s%n", i, value == null ? "bogus" : value.kind.javaName, value)); - } - for (int i = 0; i < stackSize(); ++i) { - ValueNode value = stackAt(i); - sb.append(String.format(" stack[%d] = %-8s : %s%n", i, value == null ? "bogus" : value.kind.javaName, value)); - } - for (int i = 0; i < locksSize(); ++i) { - ValueNode value = lockAt(i); - sb.append(String.format(" lock[%d] = %-8s : %s%n", i, value == null ? "bogus" : value.kind.javaName, value)); - } - return sb.toString(); - } - - @Override - public void accept(ValueVisitor v) { - v.visitFrameState(this); - } - - @Override - public String shortName() { - return "FrameState@" + bci; - } - - public void visitFrameState(FrameState i) { - // nothing to do for now - } - - @Override - public Map getDebugProperties() { - Map properties = super.getDebugProperties(); - properties.put("bci", bci); - properties.put("method", CiUtil.format("%H.%n(%p):%r", method, false)); - StringBuilder str = new StringBuilder(); - for (int i = 0; i < localsSize(); i++) { - str.append(i == 0 ? "" : ", ").append(localAt(i) == null ? "_" : localAt(i).id()); - } - properties.put("locals", str.toString()); - str = new StringBuilder(); - for (int i = 0; i < stackSize(); i++) { - str.append(i == 0 ? "" : ", ").append(stackAt(i) == null ? "_" : stackAt(i).id()); - } - properties.put("stack", str.toString()); - str = new StringBuilder(); - for (int i = 0; i < locksSize(); i++) { - str.append(i == 0 ? "" : ", ").append(lockAt(i) == null ? "_" : lockAt(i).id()); - } - properties.put("locks", str.toString()); - properties.put("rethrowException", rethrowException); - return properties; - } - - @Override - public void delete() { - FrameState outerFrameState = outerFrameState(); - super.delete(); - if (outerFrameState != null && outerFrameState.usages().isEmpty()) { - outerFrameState.delete(); - } - } - - @Override - public void setRethrowException(boolean b) { - rethrowException = b; - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/GuardNode.java --- a/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/GuardNode.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,76 +0,0 @@ -/* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.nodes; - -import com.oracle.max.graal.graph.*; -import com.oracle.max.graal.nodes.calc.*; -import com.oracle.max.graal.nodes.spi.*; -import com.sun.cri.ci.*; - -public final class GuardNode extends FloatingNode implements Canonicalizable { - - @Input private FixedNode anchor; - @Input private BooleanNode node; - - public FixedNode anchor() { - return anchor; - } - - public void setAnchor(FixedNode x) { - updateUsages(anchor, x); - anchor = x; - } - - /** - * The instruction that produces the tested boolean value. - */ - public BooleanNode node() { - return node; - } - - public void setNode(BooleanNode x) { - updateUsages(node, x); - node = x; - } - - public GuardNode(BooleanNode node, Graph graph) { - super(CiKind.Illegal, graph); - setNode(node); - } - - @Override - public void accept(ValueVisitor v) { - v.visitGuardNode(this); - } - - @Override - public Node canonical(NotifyReProcess reProcess) { - if (node() instanceof ConstantNode) { - ConstantNode c = (ConstantNode) node(); - if (c.asConstant().asBoolean()) { - return Node.Null; - } - } - return this; - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/IfNode.java --- a/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/IfNode.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,122 +0,0 @@ -/* - * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.nodes; - -import com.oracle.max.graal.graph.*; -import com.oracle.max.graal.nodes.spi.*; -import com.sun.cri.ci.*; - -/** - * The {@code If} instruction represents a branch that can go one of two directions depending on the outcome of a - * comparison. - */ -public final class IfNode extends ControlSplitNode implements Canonicalizable { - - @Input private BooleanNode compare; - - public BooleanNode compare() { - return compare; - } - - public void setCompare(BooleanNode x) { - updateUsages(compare, x); - compare = x; - } - - public IfNode(BooleanNode condition, double probability, Graph graph) { - super(CiKind.Illegal, 2, new double[] {probability, 1 - probability}, graph); - setCompare(condition); - } - - /** - * Gets the block corresponding to the true successor. - * - * @return the true successor - */ - public FixedNode trueSuccessor() { - return blockSuccessor(0); - } - - /** - * Gets the block corresponding to the false successor. - * - * @return the false successor - */ - public FixedNode falseSuccessor() { - return blockSuccessor(1); - } - - public void setTrueSuccessor(FixedNode node) { - setBlockSuccessor(0, node); - } - - public void setFalseSuccessor(FixedNode node) { - setBlockSuccessor(1, node); - } - - /** - * Gets the block corresponding to the specified outcome of the branch. - * - * @param istrue {@code true} if the true successor is requested, {@code false} otherwise - * @return the corresponding successor - */ - public FixedNode successor(boolean istrue) { - return blockSuccessor(istrue ? 0 : 1); - } - - @Override - public void accept(ValueVisitor v) { - v.visitIf(this); - } - - @Override - public boolean verify() { - assertTrue(compare() != null); - assertTrue(trueSuccessor() != null); - assertTrue(falseSuccessor() != null); - return true; - } - - @Override - public Node canonical(NotifyReProcess reProcess) { - if (compare() instanceof ConstantNode) { - ConstantNode c = (ConstantNode) compare(); - if (c.asConstant().asBoolean()) { - return trueSuccessor(); - } else { - return falseSuccessor(); - } - } - if (trueSuccessor() instanceof EndNode && falseSuccessor() instanceof EndNode) { - EndNode trueEnd = (EndNode) trueSuccessor(); - EndNode falseEnd = (EndNode) falseSuccessor(); - MergeNode merge = trueEnd.merge(); - if (merge == falseEnd.merge() && merge.phis().size() == 0 && merge.endCount() == 2) { - FixedNode next = merge.next(); - merge.setNext(null); // disconnect to avoid next from having 2 preds - return next; - } - } - return this; - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/InvokeNode.java --- a/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/InvokeNode.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,163 +0,0 @@ -/* - * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.nodes; - -import java.util.*; - -import com.oracle.max.graal.graph.*; -import com.oracle.max.graal.nodes.extended.*; -import com.oracle.max.graal.nodes.spi.*; -import com.sun.cri.bytecode.*; -import com.sun.cri.ci.*; -import com.sun.cri.ri.*; - -/** - * The {@code Invoke} instruction represents all kinds of method calls. - */ -public final class InvokeNode extends AbstractMemoryCheckpointNode implements ExceptionExit { - - @Successor private FixedNode exceptionEdge; - - @Input private final NodeInputList arguments; - - @Override - public FixedNode exceptionEdge() { - return exceptionEdge; - } - - public void setExceptionEdge(FixedNode x) { - updatePredecessors(exceptionEdge, x); - exceptionEdge = x; - } - - private final int argumentCount; - - private boolean canInline = true; - - public boolean canInline() { - return canInline; - } - - public void setCanInline(boolean b) { - canInline = b; - } - - public NodeInputList arguments() { - return arguments; - } - - public final int opcode; - public final RiMethod target; - public final RiType returnType; - public final int bci; // XXX needed because we can not compute the bci from the sateBefore bci of this Invoke was optimized from INVOKEINTERFACE to INVOKESPECIAL - - /** - * Constructs a new Invoke instruction. - * - * @param opcode the opcode of the invoke - * @param result the result type - * @param args the list of instructions producing arguments to the invocation, including the receiver object - * @param isStatic {@code true} if this call is static (no receiver object) - * @param target the target method being called - */ - public InvokeNode(int bci, int opcode, CiKind result, ValueNode[] args, RiMethod target, RiType returnType, Graph graph) { - super(result, graph); - arguments = new NodeInputList(this, args.length); - this.opcode = opcode; - this.target = target; - this.returnType = returnType; - this.bci = bci; - - this.argumentCount = args.length; - for (int i = 0; i < args.length; i++) { - arguments().set(i, args[i]); - } - } - - /** - * Gets the opcode of this invoke instruction. - * @return the opcode - */ - public int opcode() { - return opcode; - } - - /** - * Checks whether this is an invocation of a static method. - * @return {@code true} if the invocation is a static invocation - */ - public boolean isStatic() { - return opcode == Bytecodes.INVOKESTATIC; - } - - @Override - public RiType declaredType() { - return returnType; - } - - /** - * Gets the instruction that produces the receiver object for this invocation, if any. - * @return the instruction that produces the receiver object for this invocation if any, {@code null} if this - * invocation does not take a receiver object - */ - public ValueNode receiver() { - assert !isStatic(); - return arguments().get(0); - } - - /** - * Gets the target method for this invocation instruction. - * @return the target method - */ - public RiMethod target() { - return target; - } - - /** - * Checks whether this invocation has a receiver object. - * @return {@code true} if this invocation has a receiver object; {@code false} otherwise, if this is a - * static call - */ - public boolean hasReceiver() { - return !isStatic(); - } - - @Override - public void accept(ValueVisitor v) { - v.visitInvoke(this); - } - - @Override - public String toString() { - return super.toString() + target; - } - - @Override - public Map getDebugProperties() { - Map properties = super.getDebugProperties(); - properties.put("opcode", Bytecodes.nameOf(opcode)); - properties.put("target", CiUtil.format("%H.%n(%p):%r", target, false)); - properties.put("bci", bci); - return properties; - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/LocalNode.java --- a/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/LocalNode.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,95 +0,0 @@ -/* - * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.nodes; - -import java.util.*; - -import com.oracle.max.graal.graph.*; -import com.oracle.max.graal.nodes.calc.*; -import com.oracle.max.graal.nodes.spi.*; -import com.sun.cri.ci.*; -import com.sun.cri.ri.*; - -/** - * The {@code Local} instruction is a placeholder for an incoming argument - * to a function call. - */ -public final class LocalNode extends FloatingNode { - - @Input private StartNode start; - - public StartNode start() { - return start; - } - - public void setStart(StartNode x) { - updateUsages(start, x); - start = x; - } - - private final int index; - private RiType declaredType; - - public LocalNode(CiKind kind, int javaIndex, Graph graph) { - super(kind, graph); - this.index = javaIndex; - setStart(graph.start()); - } - - /** - * Gets the index of this local. - * @return the index - */ - public int index() { - return index; - } - - /** - * Sets the declared type of this local, e.g. derived from the signature of the method. - * @param declaredType the declared type of the local variable - */ - public void setDeclaredType(RiType declaredType) { - this.declaredType = declaredType; - } - - /** - * Computes the declared type of the result of this instruction, if possible. - * @return the declared type of the result of this instruction, if it is known; {@code null} otherwise - */ - @Override - public RiType declaredType() { - return declaredType; - } - - @Override - public void accept(ValueVisitor v) { - v.visitLocal(this); - } - - @Override - public Map getDebugProperties() { - Map properties = super.getDebugProperties(); - properties.put("index", index()); - return properties; - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/LoopBeginNode.java --- a/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/LoopBeginNode.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,146 +0,0 @@ -/* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.nodes; - -import java.util.*; - -import com.oracle.max.graal.graph.*; -import com.oracle.max.graal.nodes.loop.*; -import com.oracle.max.graal.nodes.spi.*; -import com.sun.cri.ci.*; - -public class LoopBeginNode extends MergeNode { - - private double loopFrequency; - - public LoopBeginNode(Graph graph) { - super(graph); - loopFrequency = 1; - } - - public double loopFrequency() { - return loopFrequency; - } - - public void setLoopFrequency(double loopFrequency) { - this.loopFrequency = loopFrequency; - } - - public LoopEndNode loopEnd() { - for (Node usage : usages()) { - if (usage instanceof LoopEndNode) { - LoopEndNode end = (LoopEndNode) usage; - if (end.loopBegin() == this) { - return end; - } - } - } - return null; - } - - @Override - public void accept(ValueVisitor v) { - v.visitLoopBegin(this); - } - - @Override - public int phiPredecessorCount() { - return 2; - } - - @Override - public int phiPredecessorIndex(Node pred) { - if (pred == forwardEdge()) { - return 0; - } else if (pred == this.loopEnd()) { - return 1; - } - throw ValueUtil.shouldNotReachHere("unknown pred : " + pred + "(sp=" + forwardEdge() + ", le=" + this.loopEnd() + ")"); - } - - @Override - public Node phiPredecessorAt(int index) { - if (index == 0) { - return forwardEdge(); - } else if (index == 1) { - return loopEnd(); - } - throw ValueUtil.shouldNotReachHere(); - } - - public Collection inductionVariables() { - return ValueUtil.filter(this.usages(), InductionVariableNode.class); - } - - @Override - public Iterable phiPredecessors() { - return Arrays.asList(new Node[]{this.forwardEdge(), this.loopEnd()}); - } - - public EndNode forwardEdge() { - return this.endAt(0); - } - - public LoopCounterNode loopCounter() { - return loopCounter(CiKind.Long); - } - - public LoopCounterNode loopCounter(CiKind kind) { - for (Node usage : usages()) { - if (usage instanceof LoopCounterNode && ((LoopCounterNode) usage).kind == kind) { - return (LoopCounterNode) usage; - } - } - return new LoopCounterNode(kind, this, graph()); - } - - @Override - public boolean verify() { - assertTrue(loopEnd() != null); - assertTrue(forwardEdge() != null); - return true; - } - - @Override - public String toString() { - return "LoopBegin: " + super.toString(); - } - - @Override - public Iterable< ? extends Node> dataUsages() { - final Iterator< ? extends Node> dataUsages = super.dataUsages().iterator(); - return new Iterable() { - @Override - public Iterator iterator() { - return new StateSplit.FilteringIterator(dataUsages, LoopEndNode.class); - } - }; - } - - @Override - public Map getDebugProperties() { - Map properties = super.getDebugProperties(); - properties.put("loopFrequency", String.format("%7.1f", loopFrequency)); - return properties; - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/LoopEndNode.java --- a/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/LoopEndNode.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,58 +0,0 @@ -/* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.nodes; - -import java.util.*; - -import com.oracle.max.graal.graph.*; -import com.oracle.max.graal.nodes.spi.*; -import com.sun.cri.ci.*; - - -public class LoopEndNode extends FixedNode { - - @Input private LoopBeginNode loopBegin; - - public LoopBeginNode loopBegin() { - return loopBegin; - } - - public void setLoopBegin(LoopBeginNode x) { - updateUsages(this.loopBegin, x); - this.loopBegin = x; - } - - public LoopEndNode(Graph graph) { - super(CiKind.Illegal, graph); - } - - @Override - public void accept(ValueVisitor v) { - v.visitLoopEnd(this); - } - - @Override - public Iterable< ? extends Node> dataInputs() { - return Collections.emptyList(); - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/MaterializeNode.java --- a/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/MaterializeNode.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,32 +0,0 @@ -/* - * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.nodes; - -import com.oracle.max.graal.graph.*; -import com.oracle.max.graal.nodes.calc.*; - -public final class MaterializeNode extends ConditionalNode { - public MaterializeNode(BooleanNode value, Graph graph) { - super(value, ConstantNode.forInt(1, graph), ConstantNode.forInt(0, graph), graph); - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/MergeNode.java --- a/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/MergeNode.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,183 +0,0 @@ -/* - * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.nodes; - -import java.util.*; - -import com.oracle.max.graal.graph.*; -import com.oracle.max.graal.nodes.spi.*; -import com.sun.cri.ci.*; - -/** - * Denotes the beginning of a basic block, and holds information - * about the basic block, including the successor and - * predecessor blocks, exception handlers, liveness information, etc. - */ -public class MergeNode extends StateSplit { - - @Input private final NodeInputList ends = new NodeInputList(this); - - public MergeNode(Graph graph) { - super(CiKind.Illegal, graph); - } - - @Override - public boolean needsStateAfter() { - return false; - } - - @Override - public void accept(ValueVisitor v) { - v.visitMerge(this); - } - - public int endIndex(EndNode end) { - return ends.indexOf(end); - } - - public void addEnd(EndNode end) { - ends.add(end); - } - - public int endCount() { - return ends.size(); - } - - public EndNode endAt(int index) { - return ends.get(index); - } - - public Iterable phiPredecessors() { - return ends; - } - - @Override - public Iterable cfgPredecessors() { - return ends; - } - - @Override - public Iterable< ? extends Node> dataInputs() { - return Collections.emptyList(); - } - - @Override - public String toString() { - StringBuilder builder = new StringBuilder(); - builder.append("merge #"); - builder.append(id()); - builder.append(" ["); - - builder.append("]"); - - builder.append(" -> "); - boolean hasSucc = false; - for (Node s : this.successors()) { - if (hasSucc) { - builder.append(", "); - } - builder.append("#"); - if (s != null) { - builder.append(s.id()); - } else { - builder.append("null"); - } - hasSucc = true; - } - return builder.toString(); - } - - /** - * Determines if a given instruction is a phi whose {@linkplain PhiNode#merge() join block} is a given block. - * - * @param value the instruction to test - * @param block the block that may be the join block of {@code value} if {@code value} is a phi - * @return {@code true} if {@code value} is a phi and its join block is {@code block} - */ - private boolean isPhiAtBlock(ValueNode value) { - return value instanceof PhiNode && ((PhiNode) value).merge() == this; - } - - - /** - * Formats a given instruction as a value in a {@linkplain FrameState frame state}. If the instruction is a phi defined at a given - * block, its {@linkplain PhiNode#valueCount() inputs} are appended to the returned string. - * - * @param index the index of the value in the frame state - * @param value the frame state value - * @param block if {@code value} is a phi, then its inputs are formatted if {@code block} is its - * {@linkplain PhiNode#merge() join point} - * @return the instruction representation as a string - */ - public String stateString(int index, ValueNode value) { - StringBuilder sb = new StringBuilder(30); - sb.append(String.format("%2d %s", index, ValueUtil.valueString(value))); - if (value instanceof PhiNode) { - PhiNode phi = (PhiNode) value; - // print phi operands - if (phi.merge() == this) { - sb.append(" ["); - for (int j = 0; j < phi.valueCount(); j++) { - sb.append(' '); - ValueNode operand = phi.valueAt(j); - if (operand != null) { - sb.append(ValueUtil.valueString(operand)); - } else { - sb.append("NULL"); - } - } - sb.append("] "); - } - } - return sb.toString(); - } - - public void removeEnd(EndNode pred) { - int predIndex = ends.indexOf(pred); - assert predIndex != -1; - ends.remove(predIndex); - - for (Node usage : usages()) { - if (usage instanceof PhiNode) { - ((PhiNode) usage).removeInput(predIndex); - } - } - } - - public int phiPredecessorCount() { - return endCount(); - } - - public int phiPredecessorIndex(Node pred) { - EndNode end = (EndNode) pred; - return endIndex(end); - } - - public Node phiPredecessorAt(int index) { - return endAt(index); - } - - public Collection phis() { - return ValueUtil.filter(this.usages(), PhiNode.class); - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/PhiNode.java --- a/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/PhiNode.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,181 +0,0 @@ -/* - * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.nodes; - -import java.util.*; - -import com.oracle.max.graal.graph.*; -import com.oracle.max.graal.nodes.StateSplit.FilteringIterator; -import com.oracle.max.graal.nodes.calc.*; -import com.oracle.max.graal.nodes.spi.*; -import com.sun.cri.ci.*; - -/** - * The {@code Phi} instruction represents the merging of dataflow in the instruction graph. It refers to a join block - * and a variable. - */ -public final class PhiNode extends FloatingNode implements Canonicalizable { - - @Input private MergeNode merge; - - @Input private final NodeInputList values = new NodeInputList(this); - - public MergeNode merge() { - return merge; - } - - public void setMerge(MergeNode x) { - updateUsages(merge, x); - merge = x; - } - - public static enum PhiType { - Value, // normal value phis - Memory, // memory phis - Virtual // phis used for VirtualObjectField merges - } - - private final PhiType type; - - public PhiNode(CiKind kind, MergeNode merge, PhiType type, Graph graph) { - super(kind, graph); - this.type = type; - setMerge(merge); - } - - private PhiNode(CiKind kind, PhiType type, Graph graph) { - super(kind, graph); - this.type = type; - } - - public PhiType type() { - return type; - } - - @Override - public boolean verify() { - assertTrue(merge() != null); - assertTrue(merge().phiPredecessorCount() == valueCount(), merge().phiPredecessorCount() + "==" + valueCount()); - return true; - } - - /** - * Get the instruction that produces the value associated with the i'th predecessor of the join block. - * - * @param i the index of the predecessor - * @return the instruction that produced the value in the i'th predecessor - */ - public ValueNode valueAt(int i) { - return values.get(i); - } - - public void setValueAt(int i, ValueNode x) { - values.set(i, x); - } - - /** - * Get the number of inputs to this phi (i.e. the number of predecessors to the join block). - * - * @return the number of inputs in this phi - */ - public int valueCount() { - return values.size(); - } - - @Override - public void accept(ValueVisitor v) { - v.visitPhi(this); - } - - @Override - public String shortName() { - StringBuilder str = new StringBuilder(); - for (int i = 0; i < valueCount(); ++i) { - if (i != 0) { - str.append(' '); - } - str.append(valueAt(i) == null ? "-" : valueAt(i).id()); - } - if (type == PhiType.Value) { - return "Phi: (" + str + ")"; - } else { - return type + "Phi: (" + str + ")"; - } - } - - public void addInput(ValueNode x) { - values.add(x); - } - - public void removeInput(int index) { - values.remove(index); - } - - @Override - public Iterable< ? extends Node> dataInputs() { - final Iterator< ? extends Node> input = super.dataInputs().iterator(); - return new Iterable() { - - @Override - public Iterator iterator() { - return new FilteringIterator(input, MergeNode.class); - } - }; - } - - @Override - public Node canonical(NotifyReProcess reProcess) { - if (valueCount() != 2 || merge().endCount() != 2) { - return this; - } - if (merge().phis().size() > 1) { // XXX (gd) disable canonicalization of multiple conditional while we are not able to fuse them and the potentially leftover If in the backend - return this; - } - Node end0 = merge().endAt(0); - Node end1 = merge().endAt(1); - Node endPred0 = end0.predecessor(); - Node endPred1 = end1.predecessor(); - if (endPred0 != endPred1 || !(endPred0 instanceof IfNode)) { - return this; - } - IfNode ifNode = (IfNode) endPred0; - boolean inverted = ifNode.trueSuccessor() == end1; - ValueNode trueValue = valueAt(inverted ? 1 : 0); - ValueNode falseValue = valueAt(inverted ? 0 : 1); - if ((trueValue.kind != CiKind.Int && trueValue.kind != CiKind.Long) || (falseValue.kind != CiKind.Int && falseValue.kind != CiKind.Long)) { - return this; - } - if ((!(trueValue instanceof ConstantNode) && trueValue.usages().size() == 1) || (!(falseValue instanceof ConstantNode) && falseValue.usages().size() == 1)) { - return this; - } - BooleanNode compare = ifNode.compare(); - while (compare instanceof NegateBooleanNode) { - compare = ((NegateBooleanNode) compare).value(); - } - if (!(compare instanceof CompareNode || compare instanceof IsNonNullNode || compare instanceof NegateBooleanNode || compare instanceof ConstantNode)) { - return this; - } - reProcess.reProccess(ifNode); - return new ConditionalNode(ifNode.compare(), trueValue, falseValue, graph()); - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/PlaceholderNode.java --- a/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/PlaceholderNode.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.nodes; - -import com.oracle.max.graal.graph.*; -import com.oracle.max.graal.nodes.spi.*; -import com.sun.cri.ci.*; - - -public class PlaceholderNode extends StateSplit { - - public PlaceholderNode(Graph graph) { - super(CiKind.Void, graph); - } - - @Override - public void accept(ValueVisitor v) { - //assert false; - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/ReturnNode.java --- a/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/ReturnNode.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,65 +0,0 @@ -/* - * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.nodes; - -import com.oracle.max.graal.graph.*; -import com.oracle.max.graal.nodes.spi.*; -import com.sun.cri.ci.*; - -/** - * The {@code Return} class definition. - */ -public final class ReturnNode extends FixedNode { - - @Input private ValueNode result; - - public ValueNode result() { - return result; - } - - public void setResult(ValueNode x) { - updateUsages(this.result, x); - this.result = x; - } - - /** - * Constructs a new Return instruction. - * @param result the instruction producing the result for this return; {@code null} if this - * is a void return - * @param graph - */ - public ReturnNode(ValueNode result, Graph graph) { - super(result == null ? CiKind.Void : result.kind, graph); - setResult(result); - } - - // for copying - private ReturnNode(CiKind kind, Graph graph) { - super(kind, graph); - } - - @Override - public void accept(ValueVisitor v) { - v.visitReturn(this); - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/StateSplit.java --- a/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/StateSplit.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,124 +0,0 @@ -/* - * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.nodes; - -import java.util.*; - -import com.oracle.max.graal.graph.*; -import com.sun.cri.ci.*; - -/** - * The {@code StateSplit} class is the abstract base class of all instructions - * that store an immutable copy of the frame state. - */ -public abstract class StateSplit extends FixedWithNextNode { - - @Input private FrameState stateAfter; - - public FrameState stateAfter() { - return stateAfter; - } - - public void setStateAfter(FrameState x) { - updateUsages(stateAfter, x); - stateAfter = x; - } - - /** - * Creates a new state split with the specified value type. - * @param kind the type of the value that this instruction produces - * @param graph - */ - public StateSplit(CiKind kind, Graph graph) { - super(kind, graph); - } - - public boolean needsStateAfter() { - return true; - } - - @Override - public void delete() { - FrameState stateAfter = stateAfter(); - super.delete(); - if (stateAfter != null) { - if (stateAfter.usages().isEmpty()) { - stateAfter.delete(); - } - } - } - - @Override - public Iterable< ? extends Node> dataInputs() { - final Iterator< ? extends Node> dataInputs = super.dataInputs().iterator(); - return new Iterable() { - @Override - public Iterator iterator() { - return new FilteringIterator(dataInputs, FrameState.class); - } - }; - } - - public static final class FilteringIterator implements Iterator { - - private final Iterator< ? extends Node> input; - private Node next; - private Class< ? > clazz; - - public FilteringIterator(Iterator< ? extends Node> input, Class clazz) { - this.input = input; - this.clazz = clazz; - } - - @Override - public void remove() { - throw new UnsupportedOperationException(); - } - - @Override - public Node next() { - forward(); - if (!hasNext()) { - throw new NoSuchElementException(); - } - Node res = next; - next = null; - return res; - } - - @Override - public boolean hasNext() { - forward(); - return next != null; - } - - private void forward() { - while (next == null && input.hasNext()) { - next = input.next(); - if (clazz.isInstance(next)) { - next = null; - } - } - } - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/UnwindNode.java --- a/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/UnwindNode.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,55 +0,0 @@ -/* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.nodes; - -import com.oracle.max.graal.graph.*; -import com.oracle.max.graal.nodes.spi.*; -import com.sun.cri.ci.*; - -/** - * Unwind takes an exception object, destroys the current stack frame and passes the exception object to the system's exception dispatch code. - */ -public final class UnwindNode extends FixedNode { - - @Input private ValueNode exception; - - public ValueNode exception() { - return exception; - } - - public void setException(ValueNode x) { - assert x == null || x.kind == CiKind.Object; - updateUsages(this.exception, x); - this.exception = x; - } - - public UnwindNode(ValueNode exception, Graph graph) { - super(CiKind.Object, graph); - setException(exception); - } - - @Override - public void accept(ValueVisitor v) { - v.visitUnwind(this); - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/ValueNode.java --- a/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/ValueNode.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,190 +0,0 @@ -/* - * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.nodes; - -import java.util.*; - -import com.oracle.max.graal.graph.*; -import com.oracle.max.graal.nodes.spi.*; -import com.oracle.max.graal.nodes.virtual.*; -import com.sun.cri.ci.*; -import com.sun.cri.ri.*; - -/** - * This class represents a value within the HIR graph, including local variables, phis, and - * all other instructions. - */ -public abstract class ValueNode extends Node { - - /** - * The kind of this value. This is {@link CiKind#Void} for instructions that produce no value. - * This kind is guaranteed to be a {@linkplain CiKind#stackKind() stack kind}. - */ - @Data public final CiKind kind; - - protected CiValue operand = CiValue.IllegalValue; - - /** - * Creates a new value with the specified kind. - * @param kind the type of this value - * @param inputCount - * @param successorCount - * @param graph - */ - public ValueNode(CiKind kind, Graph graph) { - super(graph); - assert kind != null && kind == kind.stackKind() : kind + " != " + kind.stackKind(); - this.kind = kind; - } - - /** - * Checks whether this value is a constant (i.e. it is of type {@link ConstantNode}. - * @return {@code true} if this value is a constant - */ - public final boolean isConstant() { - return this instanceof ConstantNode; - } - - /** - * Checks whether this value represents the null constant. - * @return {@code true} if this value represents the null constant - */ - public final boolean isNullConstant() { - return this instanceof ConstantNode && ((ConstantNode) this).value.isNull(); - } - - /** - * Convert this value to a constant if it is a constant, otherwise return null. - * @return the {@link CiConstant} represented by this value if it is a constant; {@code null} - * otherwise - */ - public final CiConstant asConstant() { - if (this instanceof ConstantNode) { - return ((ConstantNode) this).value; - } - return null; - } - - /** - * Gets the LIR operand associated with this instruction. - * @return the LIR operand for this instruction - */ - public final CiValue operand() { - return operand; - } - - /** - * Sets the LIR operand associated with this instruction. - * @param operand the operand to associate with this instruction - */ - public final void setOperand(CiValue operand) { - assert this.operand.isIllegal() : "operand cannot be set twice"; - assert operand != null && operand.isLegal() : "operand must be legal"; - assert operand.kind.stackKind() == this.kind; - assert !(this instanceof VirtualObjectNode); - this.operand = operand; - } - - /** - * Clears the LIR operand associated with this instruction. - */ - public final void clearOperand() { - this.operand = CiValue.IllegalValue; - } - - /** - * Computes the exact type of the result of this instruction, if possible. - * @return the exact type of the result of this instruction, if it is known; {@code null} otherwise - */ - public RiType exactType() { - return null; // default: unknown exact type - } - - /** - * Computes the declared type of the result of this instruction, if possible. - * @return the declared type of the result of this instruction, if it is known; {@code null} otherwise - */ - public RiType declaredType() { - return null; // default: unknown declared type - } - - @Override - public String toString() { - StringBuilder builder = new StringBuilder(); - builder.append("#"); - builder.append(id()); - builder.append(' '); - if (id() < 10) { - builder.append(' '); - } - builder.append(getClass().getSimpleName()); - builder.append(" [").append(flagsToString()).append("]"); - return builder.toString(); - } - - public String flagsToString() { - StringBuilder sb = new StringBuilder(); - return sb.toString(); - } - - /** - * This method supports the visitor pattern by accepting a visitor and calling the - * appropriate {@code visit()} method. - * - * @param v the visitor to accept - */ - public void accept(ValueVisitor v) { - throw new IllegalStateException("No visit method for this node (" + this.getClass().getSimpleName() + ")"); - } - - public static final LoweringOp DELEGATE_TO_RUNTIME = new LoweringOp() { - @Override - public void lower(Node n, CiLoweringTool tool) { - tool.getRuntime().lower(n, tool); - } - }; - - public static final LIRGeneratorOp DELEGATE_TO_VALUE_VISITOR = new LIRGeneratorOp() { - @Override - public void generate(Node n, LIRGeneratorTool generator) { - ((ValueNode) n).accept(generator); - } - }; - - @SuppressWarnings("unchecked") - @Override - public T lookup(Class clazz) { - if (clazz == LIRGeneratorOp.class) { - return (T) DELEGATE_TO_VALUE_VISITOR; - } - return super.lookup(clazz); - } - - @Override - public Map getDebugProperties() { - Map properties = super.getDebugProperties(); - properties.put("kind", kind.toString()); - properties.put("operand", operand == null ? "null" : operand.toString()); - return properties; - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/ValueUtil.java --- a/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/ValueUtil.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,116 +0,0 @@ -/* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.nodes; - -import java.util.*; - -import com.oracle.max.graal.graph.*; -import com.sun.cri.ci.*; - - -public class ValueUtil { - - public static ValueNode assertKind(CiKind kind, ValueNode x) { - assert x != null && (x.kind == kind) : "kind=" + kind + ", value=" + x + ((x == null) ? "" : ", value.kind=" + x.kind); - return x; - } - - public static RuntimeException shouldNotReachHere(String msg) { - throw new InternalError("should not reach here: " + msg); - } - - public static RuntimeException shouldNotReachHere() { - throw new InternalError("should not reach here"); - } - - public static ValueNode assertLong(ValueNode x) { - assert x != null && (x.kind == CiKind.Long); - return x; - } - - public static ValueNode assertJsr(ValueNode x) { - assert x != null && (x.kind == CiKind.Jsr); - return x; - } - - public static ValueNode assertInt(ValueNode x) { - assert x != null && (x.kind == CiKind.Int); - return x; - } - - public static ValueNode assertFloat(ValueNode x) { - assert x != null && (x.kind == CiKind.Float); - return x; - } - - public static ValueNode assertObject(ValueNode x) { - assert x != null && (x.kind == CiKind.Object); - return x; - } - - public static ValueNode assertWord(ValueNode x) { - assert x != null && (x.kind == CiKind.Word); - return x; - } - - public static ValueNode assertDouble(ValueNode x) { - assert x != null && (x.kind == CiKind.Double); - return x; - } - - public static void assertHigh(ValueNode x) { - assert x == null; - } - - public static boolean typeMismatch(ValueNode x, ValueNode y) { - return y == null || x.kind != y.kind; - } - - public static boolean isDoubleWord(ValueNode x) { - return x != null && x.kind.isDoubleWord(); - } - - - @SuppressWarnings("unchecked") - public static Collection filter(Iterable nodes, Class clazz) { - ArrayList phis = new ArrayList(); - for (Node node : nodes) { - if (clazz.isInstance(node)) { - phis.add((T) node); - } - } - return phis; - } - - /** - * Converts a given instruction to a value string. The representation of an instruction as - * a value is formed by concatenating the {@linkplain com.sun.cri.ci.CiKind#typeChar character} denoting its - * {@linkplain ValueNode#kind kind} and its {@linkplain ValueNode#id()}. For example, {@code "i13"}. - * - * @param value the instruction to convert to a value string. If {@code value == null}, then "-" is returned. - * @return the instruction representation as a string - */ - public static String valueString(ValueNode value) { - return (value == null) ? "-" : ("" + value.kind.typeChar + value.id()); - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/calc/AndNode.java --- a/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/calc/AndNode.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,75 +0,0 @@ -/* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.nodes.calc; - -import com.oracle.max.graal.graph.*; -import com.oracle.max.graal.nodes.*; -import com.oracle.max.graal.nodes.spi.*; -import com.sun.cri.bytecode.*; -import com.sun.cri.ci.*; - -@NodeInfo(shortName = "&") -public final class AndNode extends LogicNode implements Canonicalizable { - - public AndNode(CiKind kind, ValueNode x, ValueNode y, Graph graph) { - super(kind, kind == CiKind.Int ? Bytecodes.IAND : Bytecodes.LAND, x, y, graph); - } - - @Override - public Node canonical(NotifyReProcess reProcess) { - if (x() == y()) { - return x(); - } - if (x().isConstant() && !y().isConstant()) { - swapOperands(); - } - if (x().isConstant()) { - if (kind == CiKind.Int) { - return ConstantNode.forInt(x().asConstant().asInt() & y().asConstant().asInt(), graph()); - } else { - assert kind == CiKind.Long; - return ConstantNode.forLong(x().asConstant().asLong() & y().asConstant().asLong(), graph()); - } - } else if (y().isConstant()) { - if (kind == CiKind.Int) { - int c = y().asConstant().asInt(); - if (c == -1) { - return x(); - } - if (c == 0) { - return ConstantNode.forInt(0, graph()); - } - } else { - assert kind == CiKind.Long; - long c = y().asConstant().asLong(); - if (c == -1) { - return x(); - } - if (c == 0) { - return ConstantNode.forLong(0, graph()); - } - } - } - return this; - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/calc/ArithmeticNode.java --- a/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/calc/ArithmeticNode.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,67 +0,0 @@ -/* - * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.nodes.calc; - -import com.oracle.max.graal.graph.*; -import com.oracle.max.graal.nodes.*; -import com.oracle.max.graal.nodes.spi.*; -import com.sun.cri.bytecode.*; -import com.sun.cri.ci.*; - -/** - * The {@code ArithmeticOp} class represents arithmetic operations such as addition, subtraction, etc. - */ -public abstract class ArithmeticNode extends BinaryNode { - - private final boolean isStrictFP; - - /** - * Creates a new arithmetic operation. - * @param opcode the bytecode opcode - * @param kind the result kind of the operation - * @param x the first input instruction - * @param y the second input instruction - * @param isStrictFP indicates this operation has strict rounding semantics - */ - public ArithmeticNode(CiKind kind, int opcode, ValueNode x, ValueNode y, boolean isStrictFP, Graph graph) { - super(kind, opcode, x, y, graph); - this.isStrictFP = isStrictFP; - } - - /** - * Checks whether this instruction has strict fp semantics. - * @return {@code true} if this instruction has strict fp semantics - */ - public boolean isStrictFP() { - return isStrictFP; - } - - @Override - public void accept(ValueVisitor v) { - v.visitArithmetic(this); - } - - public boolean isCommutative() { - return Bytecodes.isCommutative(opcode); - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/calc/BinaryNode.java --- a/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/calc/BinaryNode.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,80 +0,0 @@ -/* - * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.nodes.calc; - -import com.oracle.max.graal.graph.*; -import com.oracle.max.graal.nodes.*; -import com.sun.cri.bytecode.*; -import com.sun.cri.ci.*; - -/** - * The {@code Op2} class is the base of arithmetic and logic operations with two inputs. - */ -public abstract class BinaryNode extends FloatingNode { - - @Input private ValueNode x; - @Input private ValueNode y; - @Data public final int opcode; - - public ValueNode x() { - return x; - } - - public void setX(ValueNode x) { - updateUsages(this.x, x); - this.x = x; - } - - public ValueNode y() { - return y; - } - - public void setY(ValueNode x) { - updateUsages(y, x); - this.y = x; - } - - /** - * Creates a new Op2 instance. - * @param kind the result type of this instruction - * @param opcode the bytecode opcode - * @param x the first input instruction - * @param y the second input instruction - */ - public BinaryNode(CiKind kind, int opcode, ValueNode x, ValueNode y, Graph graph) { - super(kind, graph); - this.opcode = opcode; - setX(x); - setY(y); - } - - /** - * Swaps the operands of this instruction. This is only legal for commutative operations. - */ - public void swapOperands() { - assert Bytecodes.isCommutative(opcode); - ValueNode t = x(); - setX(y()); - setY(t); - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/calc/CompareNode.java --- a/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/calc/CompareNode.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,210 +0,0 @@ -/* - * Copyright (c) 2011, 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.nodes.calc; - -import java.util.*; - -import com.oracle.max.graal.graph.*; -import com.oracle.max.graal.nodes.*; -import com.oracle.max.graal.nodes.spi.*; -import com.sun.cri.ci.*; - -/* (tw/gd) For high-level optimization purpose the compare node should be a boolean *value* (it is currently only a helper node) - * But in the back-end the comparison should not always be materialized (for example in x86 the comparison result will not be in a register but in a flag) - * - * Compare should probably be made a value (so that it can be canonicalized for example) and in later stages some Compare usage should be transformed - * into variants that do not materialize the value (CompareIf, CompareGuard...) - * - */ -public final class CompareNode extends BooleanNode implements Canonicalizable { - - @Input private ValueNode x; - @Input private ValueNode y; - - @Data private Condition condition; - @Data private boolean unorderedIsTrue; - - public ValueNode x() { - return x; - } - - public void setX(ValueNode x) { - updateUsages(this.x, x); - this.x = x; - } - - public ValueNode y() { - return y; - } - - public void setY(ValueNode x) { - updateUsages(y, x); - this.y = x; - } - - /** - * Constructs a new Compare instruction. - * - * @param x the instruction producing the first input to the instruction - * @param condition the condition (comparison operation) - * @param y the instruction that produces the second input to this instruction - * @param graph - */ - public CompareNode(ValueNode x, Condition condition, ValueNode y, Graph graph) { - super(CiKind.Illegal, graph); - assert (x == null && y == null) || x.kind == y.kind; - this.condition = condition; - setX(x); - setY(y); - } - - /** - * Gets the condition (comparison operation) for this instruction. - * - * @return the condition - */ - public Condition condition() { - return condition; - } - - /** - * Checks whether unordered inputs mean true or false. - * - * @return {@code true} if unordered inputs produce true - */ - public boolean unorderedIsTrue() { - return unorderedIsTrue; - } - - public void setUnorderedIsTrue(boolean unorderedIsTrue) { - this.unorderedIsTrue = unorderedIsTrue; - } - - /** - * Swaps the operands to this if and mirrors the condition (e.g. > becomes <). - * - * @see Condition#mirror() - */ - public void swapOperands() { - condition = condition.mirror(); - ValueNode t = x(); - setX(y()); - setY(t); - } - - public void negate() { - condition = condition.negate(); - unorderedIsTrue = !unorderedIsTrue; - } - - @Override - public void accept(ValueVisitor v) { - } - - @Override - public String shortName() { - return "Comp " + condition.operator; - } - - @Override - public Map getDebugProperties() { - Map properties = super.getDebugProperties(); - properties.put("unorderedIsTrue", unorderedIsTrue()); - return properties; - } - - private Node optimizeMaterialize(CiConstant constant, MaterializeNode materializeNode) { - if (constant.kind == CiKind.Int) { - boolean isFalseCheck = (constant.asInt() == 0); - if (condition == Condition.EQ || condition == Condition.NE) { - if (condition == Condition.NE) { - isFalseCheck = !isFalseCheck; - } - BooleanNode result = materializeNode.condition(); - if (isFalseCheck) { - result = new NegateBooleanNode(result, graph()); - } - return result; - } - } - return this; - } - - private Node optimizeNormalizeCmp(CiConstant constant, NormalizeCompareNode normalizeNode) { - if (constant.kind == CiKind.Int && constant.asInt() == 0) { - Condition condition = condition(); - if (normalizeNode == y()) { - condition = condition.mirror(); - } - CompareNode result = new CompareNode(normalizeNode.x(), condition, normalizeNode.y(), graph()); - boolean isLess = condition == Condition.LE || condition == Condition.LT || condition == Condition.BE || condition == Condition.BT; - result.unorderedIsTrue = condition != Condition.EQ && (condition == Condition.NE || !(isLess ^ normalizeNode.isUnorderedLess())); - return result; - } - return this; - } - - @Override - public Node canonical(NotifyReProcess reProcess) { - if (x().isConstant() && !y().isConstant()) { // move constants to the left (y) - swapOperands(); - } else if (x().isConstant() && y().isConstant()) { - CiConstant constX = x().asConstant(); - CiConstant constY = y().asConstant(); - Boolean result = condition().foldCondition(constX, constY, ((CompilerGraph) graph()).runtime(), unorderedIsTrue()); - if (result != null) { - return ConstantNode.forBoolean(result, graph()); - } - } - - if (y().isConstant()) { - if (x() instanceof MaterializeNode) { - return optimizeMaterialize(y().asConstant(), (MaterializeNode) x()); - } else if (x() instanceof NormalizeCompareNode) { - return optimizeNormalizeCmp(y().asConstant(), (NormalizeCompareNode) x()); - } - } - - if (x() == y() && x().kind != CiKind.Float && x().kind != CiKind.Double) { - return ConstantNode.forBoolean(condition().check(1, 1), graph()); - } - if ((condition == Condition.NE || condition == Condition.EQ) && x().kind == CiKind.Object) { - ValueNode object = null; - if (x().isNullConstant()) { - object = y(); - } else if (y().isNullConstant()) { - object = x(); - } - if (object != null) { - IsNonNullNode nonNull = new IsNonNullNode(object, graph()); - if (condition == Condition.NE) { - return nonNull; - } else { - assert condition == Condition.EQ; - return new NegateBooleanNode(nonNull, graph()); - } - } - } - return this; - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/calc/Condition.java --- a/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/calc/Condition.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,262 +0,0 @@ -/* - * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.nodes.calc; - -import com.sun.cri.ci.*; -import com.sun.cri.ri.*; - -/** - * Condition codes used in conditionals. - */ -public enum Condition { - /** - * Equal. - */ - EQ("=="), - - /** - * Not equal. - */ - NE("!="), - - /** - * Signed less than. - */ - LT("<"), - - /** - * Signed less than or equal. - */ - LE("<="), - - /** - * Signed greater than. - */ - GT(">"), - - /** - * Signed greater than or equal. - */ - GE(">="), - - /** - * Unsigned greater than or equal ("above than or equal"). - */ - AE("|>=|"), - - /** - * Unsigned less than or equal ("below than or equal"). - */ - BE("|<=|"), - - /** - * Unsigned greater than ("above than"). - */ - AT("|>|"), - - /** - * Unsigned less than ("below than"). - */ - BT("|<|"), - - /** - * Operation produced an overflow. - */ - OF("overflow"), - - /** - * Operation did not produce an overflow. - */ - NOF("noOverflow"), - - TRUE("TRUE"); - - public final String operator; - - private Condition(String operator) { - this.operator = operator; - } - - public boolean check(int left, int right) { - switch (this) { - case EQ: return left == right; - case NE: return left != right; - case LT: return left < right; - case LE: return left <= right; - case GT: return left > right; - case GE: return left >= right; - case BT: return (left & 0xffffffffL) < (right & 0xffffffffL); - case BE: return (left & 0xffffffffL) <= (right & 0xffffffffL); - case AT: return (left & 0xffffffffL) > (right & 0xffffffffL); - case AE: return (left & 0xffffffffL) >= (right & 0xffffffffL); - } - throw new IllegalArgumentException(); - } - - /** - * Negate this conditional. - * @return the condition that represents the negation - */ - public final Condition negate() { - switch (this) { - case EQ: return NE; - case NE: return EQ; - case LT: return GE; - case LE: return GT; - case GT: return LE; - case GE: return LT; - case BT: return AE; - case BE: return AT; - case AT: return BE; - case AE: return BT; - case OF: return NOF; - case NOF: return OF; - } - throw new IllegalArgumentException(this.toString()); - } - - /** - * Mirror this conditional (i.e. commute "a op b" to "b op' a") - * @return the condition representing the equivalent commuted operation - */ - public final Condition mirror() { - switch (this) { - case EQ: return EQ; - case NE: return NE; - case LT: return GT; - case LE: return GE; - case GT: return LT; - case GE: return LE; - case BT: return AT; - case BE: return AE; - case AT: return BT; - case AE: return BE; - } - throw new IllegalArgumentException(); - } - - /** - * Checks if this conditional operation is commutative. - * @return {@code true} if this operation is commutative - */ - public final boolean isCommutative() { - return this == EQ || this == NE; - } - - /** - * Attempts to fold a comparison between two constants and return the result. - * @param lt the constant on the left side of the comparison - * @param rt the constant on the right side of the comparison - * @param runtime the RiRuntime (might be needed to compare runtime-specific types) - * @return {@link Boolean#TRUE} if the comparison is known to be true, - * {@link Boolean#FALSE} if the comparison is known to be false, {@code null} otherwise. - */ - public Boolean foldCondition(CiConstant lt, CiConstant rt, RiRuntime runtime, boolean unorderedIsTrue) { - switch (lt.kind) { - case Boolean: - case Int: { - int x = lt.asInt(); - int y = rt.asInt(); - switch (this) { - case EQ: return x == y; - case NE: return x != y; - case LT: return x < y; - case LE: return x <= y; - case GT: return x > y; - case GE: return x >= y; - case AE: return toUnsigned(x) >= toUnsigned(y); - case BE: return toUnsigned(x) <= toUnsigned(y); - case AT: return toUnsigned(x) > toUnsigned(y); - case BT: return toUnsigned(x) < toUnsigned(y); - } - break; - } - case Long: { - long x = lt.asLong(); - long y = rt.asLong(); - switch (this) { - case EQ: return x == y; - case NE: return x != y; - case LT: return x < y; - case LE: return x <= y; - case GT: return x > y; - case GE: return x >= y; - } - break; - } - case Object: { - switch (this) { - case EQ: return runtime.areConstantObjectsEqual(lt, rt); - case NE: return !runtime.areConstantObjectsEqual(lt, rt); - } - break; - } - case Float: { - float x = lt.asFloat(); - float y = rt.asFloat(); - if (Float.isNaN(x) || Float.isNaN(y)) { - return unorderedIsTrue; - } - switch (this) { - case EQ: return x == y; - case NE: return x != y; - case BT: - case LT: return x < y; - case BE: - case LE: return x <= y; - case AT: - case GT: return x > y; - case AE: - case GE: return x >= y; - } - } - case Double: { - double x = lt.asDouble(); - double y = rt.asDouble(); - if (Double.isNaN(x) || Double.isNaN(y)) { - return unorderedIsTrue; - } - switch (this) { - case EQ: return x == y; - case NE: return x != y; - case BT: - case LT: return x < y; - case BE: - case LE: return x <= y; - case AT: - case GT: return x > y; - case AE: - case GE: return x >= y; - } - } - } - return null; - } - - private long toUnsigned(int x) { - if (x < 0) { - return ((long) (x & 0x7FFFFFFF)) + ((long) Integer.MAX_VALUE) + 1; - } - return x; - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/calc/ConditionalNode.java --- a/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/calc/ConditionalNode.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,167 +0,0 @@ -/* - * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.nodes.calc; - -import com.oracle.max.graal.graph.*; -import com.oracle.max.graal.nodes.*; -import com.oracle.max.graal.nodes.PhiNode.PhiType; -import com.oracle.max.graal.nodes.spi.*; -import com.sun.cri.bytecode.*; -import com.sun.cri.ci.*; - -/** - * The {@code Conditional} class represents a comparison that yields one of two values. Note that these nodes are not - * built directly from the bytecode but are introduced by conditional expression elimination. - */ -public class ConditionalNode extends BinaryNode implements Canonicalizable { - - @Input private BooleanNode condition; - - public BooleanNode condition() { - return condition; - } - - public void setCondition(BooleanNode n) { - updateUsages(condition, n); - condition = n; - } - - /** - * Constructs a new IfOp. - * - * @param x the instruction producing the first value to be compared - * @param condition the condition of the comparison - * @param y the instruction producing the second value to be compared - * @param trueValue the value produced if the condition is true - * @param falseValue the value produced if the condition is false - */ - public ConditionalNode(BooleanNode condition, ValueNode trueValue, ValueNode falseValue, Graph graph) { - // TODO: return the appropriate bytecode IF_ICMPEQ, etc - super(trueValue.kind.meet(falseValue.kind), Bytecodes.ILLEGAL, trueValue, falseValue, graph); - setCondition(condition); - } - - // for copying - private ConditionalNode(CiKind kind, Graph graph) { - super(kind, Bytecodes.ILLEGAL, null, null, graph); - } - - public ValueNode trueValue() { - return x(); - } - - public ValueNode falseValue() { - return y(); - } - - public void setTrueValue(ValueNode value) { - setX(value); - } - - public void setFalseValue(ValueNode value) { - setY(value); - } - - @SuppressWarnings("unchecked") - @Override - public T lookup(Class clazz) { - if (clazz == LIRGeneratorOp.class) { - return (T) LIRGEN; - } - return super.lookup(clazz); - } - - public static class ConditionalStructure { - - public final IfNode ifNode; - public final PhiNode phi; - public final MergeNode merge; - - public ConditionalStructure(IfNode ifNode, PhiNode phi, MergeNode merge) { - this.ifNode = ifNode; - this.phi = phi; - this.merge = merge; - } - } - - public static ConditionalStructure createConditionalStructure(BooleanNode condition, ValueNode trueValue, ValueNode falseValue) { - return createConditionalStructure(condition, trueValue, falseValue, 0.5); - } - - public static ConditionalStructure createConditionalStructure(BooleanNode condition, ValueNode trueValue, ValueNode falseValue, double trueProbability) { - Graph graph = condition.graph(); - CiKind kind = trueValue.kind.meet(falseValue.kind); - IfNode ifNode = new IfNode(condition, trueProbability, graph); - EndNode trueEnd = new EndNode(graph); - EndNode falseEnd = new EndNode(graph); - ifNode.setTrueSuccessor(trueEnd); - ifNode.setFalseSuccessor(falseEnd); - MergeNode merge = new MergeNode(graph); - merge.addEnd(trueEnd); - merge.addEnd(falseEnd); - PhiNode phi = new PhiNode(kind, merge, PhiType.Value, graph); - phi.addInput(trueValue); - phi.addInput(falseValue); - return new ConditionalStructure(ifNode, phi, merge); - } - - private static final LIRGeneratorOp LIRGEN = new LIRGeneratorOp() { - - @Override - public void generate(Node n, LIRGeneratorTool generator) { - generator.visitConditional((ConditionalNode) n); - } - }; - - @Override - public Node canonical(NotifyReProcess reProcess) { - if (condition instanceof ConstantNode) { - ConstantNode c = (ConstantNode) condition; - if (c.asConstant().asBoolean()) { - return trueValue(); - } else { - return falseValue(); - } - } - if (trueValue() == falseValue()) { - return trueValue(); - } - if (!(this instanceof MaterializeNode) && trueValue() instanceof ConstantNode && falseValue() instanceof ConstantNode && trueValue().kind == CiKind.Int && falseValue().kind == CiKind.Int) { - int trueInt = trueValue().asConstant().asInt(); - int falseInt = falseValue().asConstant().asInt(); - if (trueInt == 0 && falseInt == 1) { - reProcess.reProccess(condition); // because we negate it - return new MaterializeNode(new NegateBooleanNode(condition, graph()), graph()); - } else if (trueInt == 1 && falseInt == 0) { - return new MaterializeNode(condition, graph()); - } - } else if (falseValue() instanceof ConstantNode && !(trueValue() instanceof ConstantNode)) { - ValueNode temp = trueValue(); - setTrueValue(falseValue()); - setFalseValue(temp); - condition = new NegateBooleanNode(condition, graph()); - setCondition(condition); - } - return this; - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/calc/ConvertNode.java --- a/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/calc/ConvertNode.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,64 +0,0 @@ -/* - * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.nodes.calc; - -import com.oracle.max.graal.graph.*; -import com.oracle.max.graal.nodes.*; -import com.oracle.max.graal.nodes.spi.*; -import com.sun.cri.ci.*; - -/** - * The {@code Convert} class represents a conversion between primitive types. - */ -public final class ConvertNode extends FloatingNode { - @Input private ValueNode value; - - @Data public final int opcode; - - public ValueNode value() { - return value; - } - - public void setValue(ValueNode x) { - updateUsages(value, x); - value = x; - } - - /** - * Constructs a new Convert instance. - * @param opcode the bytecode representing the operation - * @param value the instruction producing the input value - * @param kind the result type of this instruction - * @param graph - */ - public ConvertNode(int opcode, ValueNode value, CiKind kind, Graph graph) { - super(kind, graph); - this.opcode = opcode; - setValue(value); - } - - @Override - public void accept(ValueVisitor v) { - v.visitConvert(this); - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/calc/FloatAddNode.java --- a/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/calc/FloatAddNode.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,66 +0,0 @@ -/* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.nodes.calc; - -import com.oracle.max.graal.graph.*; -import com.oracle.max.graal.nodes.*; -import com.oracle.max.graal.nodes.spi.*; -import com.sun.cri.bytecode.*; -import com.sun.cri.ci.*; - -@NodeInfo(shortName = "+") -public final class FloatAddNode extends FloatArithmeticNode implements Canonicalizable { - - public FloatAddNode(CiKind kind, ValueNode x, ValueNode y, boolean isStrictFP, Graph graph) { - super(kind, kind == CiKind.Double ? Bytecodes.DADD : Bytecodes.FADD, x, y, isStrictFP, graph); - } - - @Override - public Node canonical(NotifyReProcess reProcess) { - if (x().isConstant() && !y().isConstant()) { - swapOperands(); - } - if (x().isConstant()) { - if (kind == CiKind.Float) { - return ConstantNode.forFloat(x().asConstant().asFloat() + y().asConstant().asFloat(), graph()); - } else { - assert kind == CiKind.Double; - return ConstantNode.forDouble(x().asConstant().asDouble() + y().asConstant().asDouble(), graph()); - } - } else if (y().isConstant()) { - if (kind == CiKind.Float) { - float c = y().asConstant().asFloat(); - if (c == 0.0f) { - return x(); - } - } else { - assert kind == CiKind.Double; - double c = y().asConstant().asDouble(); - if (c == 0.0) { - return x(); - } - } - } - return this; - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/calc/FloatArithmeticNode.java --- a/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/calc/FloatArithmeticNode.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,35 +0,0 @@ -/* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.nodes.calc; - -import com.oracle.max.graal.graph.*; -import com.oracle.max.graal.nodes.*; -import com.sun.cri.ci.*; - -public abstract class FloatArithmeticNode extends ArithmeticNode { - - public FloatArithmeticNode(CiKind kind, int opcode, ValueNode x, ValueNode y, boolean isStrictFP, Graph graph) { - super(kind, opcode, x, y, isStrictFP, graph); - } - -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/calc/FloatDivNode.java --- a/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/calc/FloatDivNode.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,50 +0,0 @@ -/* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.nodes.calc; - -import com.oracle.max.graal.graph.*; -import com.oracle.max.graal.nodes.*; -import com.oracle.max.graal.nodes.spi.*; -import com.sun.cri.bytecode.*; -import com.sun.cri.ci.*; - -@NodeInfo(shortName = "/") -public final class FloatDivNode extends FloatArithmeticNode implements Canonicalizable { - - public FloatDivNode(CiKind kind, ValueNode x, ValueNode y, boolean isStrictFP, Graph graph) { - super(kind, kind == CiKind.Double ? Bytecodes.DDIV : Bytecodes.FDIV, x, y, isStrictFP, graph); - } - - @Override - public Node canonical(NotifyReProcess reProcess) { - if (x().isConstant() && y().isConstant()) { - if (kind == CiKind.Float) { - return ConstantNode.forFloat(x().asConstant().asFloat() / y().asConstant().asFloat(), graph()); - } else { - assert kind == CiKind.Double; - return ConstantNode.forDouble(x().asConstant().asDouble() / y().asConstant().asDouble(), graph()); - } - } - return this; - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/calc/FloatMulNode.java --- a/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/calc/FloatMulNode.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,66 +0,0 @@ -/* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.nodes.calc; - -import com.oracle.max.graal.graph.*; -import com.oracle.max.graal.nodes.*; -import com.oracle.max.graal.nodes.spi.*; -import com.sun.cri.bytecode.*; -import com.sun.cri.ci.*; - -@NodeInfo(shortName = "*") -public final class FloatMulNode extends FloatArithmeticNode implements Canonicalizable { - - public FloatMulNode(CiKind kind, ValueNode x, ValueNode y, boolean isStrictFP, Graph graph) { - super(kind, kind == CiKind.Double ? Bytecodes.DMUL : Bytecodes.FMUL, x, y, isStrictFP, graph); - } - - @Override - public Node canonical(NotifyReProcess reProcess) { - if (x().isConstant() && !y().isConstant()) { - swapOperands(); - } - if (x().isConstant()) { - if (kind == CiKind.Float) { - return ConstantNode.forFloat(x().asConstant().asFloat() * y().asConstant().asFloat(), graph()); - } else { - assert kind == CiKind.Double; - return ConstantNode.forDouble(x().asConstant().asDouble() * y().asConstant().asDouble(), graph()); - } - } else if (y().isConstant()) { - if (kind == CiKind.Float) { - float c = y().asConstant().asFloat(); - if (c == 0.0f) { - return ConstantNode.forFloat(0.0f, graph()); - } - } else { - assert kind == CiKind.Double; - double c = y().asConstant().asDouble(); - if (c == 0.0) { - return ConstantNode.forDouble(0.0, graph()); - } - } - } - return this; - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/calc/FloatRemNode.java --- a/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/calc/FloatRemNode.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,50 +0,0 @@ -/* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.nodes.calc; - -import com.oracle.max.graal.graph.*; -import com.oracle.max.graal.nodes.*; -import com.oracle.max.graal.nodes.spi.*; -import com.sun.cri.bytecode.*; -import com.sun.cri.ci.*; - -@NodeInfo(shortName = "%") -public final class FloatRemNode extends FloatArithmeticNode implements Canonicalizable { - - public FloatRemNode(CiKind kind, ValueNode x, ValueNode y, boolean isStrictFP, Graph graph) { - super(kind, kind == CiKind.Double ? Bytecodes.DREM : Bytecodes.FREM, x, y, isStrictFP, graph); - } - - @Override - public Node canonical(NotifyReProcess reProcess) { - if (x().isConstant() && y().isConstant()) { - if (kind == CiKind.Float) { - return ConstantNode.forFloat(x().asConstant().asFloat() % y().asConstant().asFloat(), graph()); - } else { - assert kind == CiKind.Double; - return ConstantNode.forDouble(x().asConstant().asDouble() % y().asConstant().asDouble(), graph()); - } - } - return this; - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/calc/FloatSubNode.java --- a/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/calc/FloatSubNode.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,73 +0,0 @@ -/* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.nodes.calc; - -import com.oracle.max.graal.graph.*; -import com.oracle.max.graal.nodes.*; -import com.oracle.max.graal.nodes.spi.*; -import com.sun.cri.bytecode.*; -import com.sun.cri.ci.*; - -@NodeInfo(shortName = "-") -public final class FloatSubNode extends FloatArithmeticNode implements Canonicalizable { - - public FloatSubNode(CiKind kind, ValueNode x, ValueNode y, boolean isStrictFP, Graph graph) { - super(kind, kind == CiKind.Double ? Bytecodes.DSUB : Bytecodes.FSUB, x, y, isStrictFP, graph); - } - - @Override - public Node canonical(NotifyReProcess reProcess) { - if (x() == y()) { - if (kind == CiKind.Float) { - return ConstantNode.forFloat(0.0f, graph()); - } else { - assert kind == CiKind.Double; - return ConstantNode.forDouble(0.0, graph()); - } - } - if (x().isConstant() && y().isConstant()) { - if (kind == CiKind.Float) { - return ConstantNode.forFloat(x().asConstant().asFloat() - y().asConstant().asFloat(), graph()); - } else { - assert kind == CiKind.Double; - return ConstantNode.forDouble(x().asConstant().asDouble() - y().asConstant().asDouble(), graph()); - } - } else if (y().isConstant()) { - if (kind == CiKind.Float) { - float c = y().asConstant().asFloat(); - if (c == 0.0f) { - return x(); - } - return new FloatAddNode(kind, x(), ConstantNode.forFloat(-c, graph()), isStrictFP(), graph()); - } else { - assert kind == CiKind.Double; - double c = y().asConstant().asDouble(); - if (c == 0.0) { - return x(); - } - return new FloatAddNode(kind, x(), ConstantNode.forDouble(-c, graph()), isStrictFP(), graph()); - } - } - return this; - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/calc/FloatingNode.java --- a/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/calc/FloatingNode.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,33 +0,0 @@ -/* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.nodes.calc; - -import com.oracle.max.graal.graph.*; -import com.oracle.max.graal.nodes.*; -import com.sun.cri.ci.*; - -public abstract class FloatingNode extends ValueNode implements Node.ValueNumberable { - public FloatingNode(CiKind kind, Graph graph) { - super(kind, graph); - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/calc/IntegerAddNode.java --- a/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/calc/IntegerAddNode.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,66 +0,0 @@ -/* - * Copyright (c) 2011, 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.nodes.calc; - -import com.oracle.max.graal.graph.*; -import com.oracle.max.graal.nodes.*; -import com.oracle.max.graal.nodes.spi.*; -import com.sun.cri.bytecode.*; -import com.sun.cri.ci.*; - -@NodeInfo(shortName = "+") -public final class IntegerAddNode extends IntegerArithmeticNode implements Canonicalizable { - - public IntegerAddNode(CiKind kind, ValueNode x, ValueNode y, Graph graph) { - super(kind, kind == CiKind.Int ? Bytecodes.IADD : Bytecodes.LADD, x, y, graph); - } - - @Override - public Node canonical(NotifyReProcess reProcess) { - if (x().isConstant() && !y().isConstant()) { - swapOperands(); - } - if (x().isConstant()) { - if (kind == CiKind.Int) { - return ConstantNode.forInt(x().asConstant().asInt() + y().asConstant().asInt(), graph()); - } else { - assert kind == CiKind.Long; - return ConstantNode.forLong(x().asConstant().asLong() + y().asConstant().asLong(), graph()); - } - } else if (y().isConstant()) { - if (kind == CiKind.Int) { - int c = y().asConstant().asInt(); - if (c == 0) { - return x(); - } - } else { - assert kind == CiKind.Long; - long c = y().asConstant().asLong(); - if (c == 0) { - return x(); - } - } - } - return this; - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/calc/IntegerAddVectorNode.java --- a/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/calc/IntegerAddVectorNode.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,63 +0,0 @@ -/* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.nodes.calc; - -import java.util.*; - -import com.oracle.max.graal.graph.*; -import com.oracle.max.graal.nodes.*; -import com.oracle.max.graal.nodes.extended.*; -import com.oracle.max.graal.nodes.spi.*; -import com.sun.cri.ci.*; - - -public final class IntegerAddVectorNode extends AbstractVectorNode { - @Input private ValueNode value; - - public ValueNode value() { - return value; - } - - public void setValue(ValueNode x) { - updateUsages(value, x); - value = x; - } - - public IntegerAddVectorNode(AbstractVectorNode vector, ValueNode value, Graph graph) { - super(CiKind.Illegal, vector, graph); - setValue(value); - } - - @Override - public T lookup(Class clazz) { - if (clazz == LIRGeneratorOp.class) { - return null; - } - return super.lookup(clazz); - } - - @Override - public void addToLoop(LoopBeginNode loop, IdentityHashMap nodes) { - nodes.put(this, new IntegerAddNode(CiKind.Int, nodes.get(vector()), value(), graph())); - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/calc/IntegerArithmeticNode.java --- a/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/calc/IntegerArithmeticNode.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,64 +0,0 @@ -/* - * Copyright (c) 2011, 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.nodes.calc; - -import com.oracle.max.graal.graph.*; -import com.oracle.max.graal.nodes.*; -import com.sun.cri.ci.*; - - -public abstract class IntegerArithmeticNode extends ArithmeticNode { - - public IntegerArithmeticNode(CiKind kind, int opcode, ValueNode x, ValueNode y, Graph graph) { - super(kind, opcode, x, y, false, graph); - assert kind == CiKind.Int || kind == CiKind.Long; - } - - public static IntegerArithmeticNode add(ValueNode v1, ValueNode v2) { - assert v1.kind == v2.kind && v1.graph() == v2.graph(); - Graph graph = v1.graph(); - //TODO (gd) handle conversions here instead of strong assert ? - switch(v1.kind) { - case Int: - return new IntegerAddNode(CiKind.Int, v1, v2, graph); - case Long: - return new IntegerAddNode(CiKind.Long, v1, v2, graph); - default: - throw ValueUtil.shouldNotReachHere(); - } - } - - public static IntegerArithmeticNode mul(ValueNode v1, ValueNode v2) { - assert v1.kind == v2.kind && v1.graph() == v2.graph(); - Graph graph = v1.graph(); - //TODO (gd) handle conversions here instead of strong assert ? - switch(v1.kind) { - case Int: - return new IntegerMulNode(CiKind.Int, v1, v2, graph); - case Long: - return new IntegerMulNode(CiKind.Long, v1, v2, graph); - default: - throw ValueUtil.shouldNotReachHere(); - } - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/calc/IntegerDivNode.java --- a/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/calc/IntegerDivNode.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,59 +0,0 @@ -/* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.nodes.calc; - -import com.oracle.max.graal.graph.*; -import com.oracle.max.graal.nodes.*; -import com.oracle.max.graal.nodes.spi.*; -import com.sun.cri.bytecode.*; -import com.sun.cri.ci.*; - -@NodeInfo(shortName = "/") -public final class IntegerDivNode extends IntegerArithmeticNode implements Canonicalizable { - - public IntegerDivNode(CiKind kind, ValueNode x, ValueNode y, Graph graph) { - super(kind, kind == CiKind.Int ? Bytecodes.IDIV : Bytecodes.LDIV, x, y, graph); - } - - @Override - public Node canonical(NotifyReProcess reProcess) { - if (x().isConstant() && y().isConstant()) { - long yConst = y().asConstant().asLong(); - if (yConst == 0) { - return this; // this will trap, can not canonicalize - } - if (kind == CiKind.Int) { - return ConstantNode.forInt(x().asConstant().asInt() / (int) yConst, graph()); - } else { - assert kind == CiKind.Long; - return ConstantNode.forLong(x().asConstant().asLong() / yConst, graph()); - } - } else if (y().isConstant()) { - long c = y().asConstant().asLong(); - if (c == 1) { - return x(); - } - } - return this; - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/calc/IntegerMulNode.java --- a/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/calc/IntegerMulNode.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,64 +0,0 @@ -/* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.nodes.calc; - -import com.oracle.max.graal.graph.*; -import com.oracle.max.graal.nodes.*; -import com.oracle.max.graal.nodes.spi.*; -import com.sun.cri.bytecode.*; -import com.sun.cri.ci.*; - -@NodeInfo(shortName = "*") -public final class IntegerMulNode extends IntegerArithmeticNode implements Canonicalizable { - - public IntegerMulNode(CiKind kind, ValueNode x, ValueNode y, Graph graph) { - super(kind, kind == CiKind.Int ? Bytecodes.IMUL : Bytecodes.LMUL, x, y, graph); - } - - @Override - public Node canonical(NotifyReProcess reProcess) { - if (x().isConstant() && !y().isConstant()) { - swapOperands(); - } - if (x().isConstant()) { - if (kind == CiKind.Int) { - return ConstantNode.forInt(x().asConstant().asInt() * y().asConstant().asInt(), graph()); - } else { - assert kind == CiKind.Long; - return ConstantNode.forLong(x().asConstant().asLong() * y().asConstant().asLong(), graph()); - } - } else if (y().isConstant()) { - long c = y().asConstant().asLong(); - if (c == 1) { - return x(); - } - if (c == 0) { - return ConstantNode.forInt(0, graph()); - } - if (c > 0 && CiUtil.isPowerOf2(c)) { - return new LeftShiftNode(kind, x(), ConstantNode.forInt(CiUtil.log2(c), graph()), graph()); - } - } - return this; - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/calc/IntegerRemNode.java --- a/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/calc/IntegerRemNode.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,64 +0,0 @@ -/* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.nodes.calc; - -import com.oracle.max.graal.graph.*; -import com.oracle.max.graal.nodes.*; -import com.oracle.max.graal.nodes.spi.*; -import com.sun.cri.bytecode.*; -import com.sun.cri.ci.*; - -@NodeInfo(shortName = "%") -public final class IntegerRemNode extends IntegerArithmeticNode implements Canonicalizable { - - public IntegerRemNode(CiKind kind, ValueNode x, ValueNode y, Graph graph) { - super(kind, kind == CiKind.Int ? Bytecodes.IREM : Bytecodes.LREM, x, y, graph); - } - - @Override - public Node canonical(NotifyReProcess reProcess) { - if (x().isConstant() && y().isConstant()) { - long yConst = y().asConstant().asLong(); - if (yConst == 0) { - return this; // this will trap, can not canonicalize - } - if (kind == CiKind.Int) { - return ConstantNode.forInt(x().asConstant().asInt() % (int) yConst, graph()); - } else { - assert kind == CiKind.Long; - return ConstantNode.forLong(x().asConstant().asLong() % yConst, graph()); - } - } else if (y().isConstant()) { - long c = y().asConstant().asLong(); - if (c == 1 || c == -1) { - if (kind == CiKind.Int) { - return ConstantNode.forInt(0, graph()); - } else { - assert kind == CiKind.Long; - return ConstantNode.forLong(0, graph()); - } - } - } - return this; - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/calc/IntegerSubNode.java --- a/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/calc/IntegerSubNode.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,74 +0,0 @@ -/* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.nodes.calc; - -import com.oracle.max.graal.graph.*; -import com.oracle.max.graal.nodes.*; -import com.oracle.max.graal.nodes.spi.*; -import com.sun.cri.bytecode.*; -import com.sun.cri.ci.*; - -@NodeInfo(shortName = "-") -public final class IntegerSubNode extends IntegerArithmeticNode implements Canonicalizable { - - public IntegerSubNode(CiKind kind, ValueNode x, ValueNode y, Graph graph) { - super(kind, kind == CiKind.Int ? Bytecodes.ISUB : Bytecodes.LSUB, x, y, graph); - } - - @Override - public Node canonical(NotifyReProcess reProcess) { - if (x() == y()) { - if (kind == CiKind.Int) { - return ConstantNode.forInt(0, graph()); - } else { - assert kind == CiKind.Long; - return ConstantNode.forLong(0, graph()); - } - } - if (x().isConstant() && y().isConstant()) { - if (kind == CiKind.Int) { - return ConstantNode.forInt(x().asConstant().asInt() - y().asConstant().asInt(), graph()); - } else { - assert kind == CiKind.Long; - return ConstantNode.forLong(x().asConstant().asLong() - y().asConstant().asLong(), graph()); - } - } else if (y().isConstant()) { - long c = y().asConstant().asLong(); - if (c == 0) { - return x(); - } - if (kind == CiKind.Int) { - return new IntegerAddNode(kind, x(), ConstantNode.forInt((int) -c, graph()), graph()); - } else { - assert kind == CiKind.Long; - return new IntegerAddNode(kind, x(), ConstantNode.forLong(-c, graph()), graph()); - } - } else if (x().isConstant()) { - long c = x().asConstant().asLong(); - if (c == 0) { - return new NegateNode(y(), graph()); - } - } - return this; - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/calc/IsNonNullNode.java --- a/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/calc/IsNonNullNode.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,89 +0,0 @@ -/* - * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.nodes.calc; - -import com.oracle.max.graal.graph.*; -import com.oracle.max.graal.nodes.*; -import com.oracle.max.graal.nodes.java.*; -import com.oracle.max.graal.nodes.spi.*; -import com.sun.cri.ci.*; -import com.sun.cri.ri.*; - -/** - * The {@code NullCheck} class represents an explicit null check instruction. - */ -public final class IsNonNullNode extends BooleanNode implements Canonicalizable { - - @Input private ValueNode object; - - public ValueNode object() { - return object; - } - - public void setObject(ValueNode x) { - updateUsages(object, x); - object = x; - } - - /** - * Constructs a new NullCheck instruction. - * - * @param object the instruction producing the object to check against null - * @param graph - */ - public IsNonNullNode(ValueNode object, Graph graph) { - super(CiKind.Object, graph); - assert object == null || object.kind == CiKind.Object : object; - setObject(object); - } - - @Override - public void accept(ValueVisitor v) { - // Nothing to do. - } - - @Override - public RiType declaredType() { - // null check does not alter the type of the object - return object().declaredType(); - } - - @Override - public RiType exactType() { - // null check does not alter the type of the object - return object().exactType(); - } - - @Override - public Node canonical(NotifyReProcess reProcess) { - if (object() instanceof NewInstanceNode || object() instanceof NewArrayNode) { - return ConstantNode.forBoolean(true, graph()); - } - CiConstant constant = object().asConstant(); - if (constant != null) { - assert constant.kind == CiKind.Object; - return ConstantNode.forBoolean(constant.isNonNull(), graph()); - } - return this; - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/calc/LeftShiftNode.java --- a/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/calc/LeftShiftNode.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,88 +0,0 @@ -/* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.nodes.calc; - -import com.oracle.max.graal.graph.*; -import com.oracle.max.graal.nodes.*; -import com.oracle.max.graal.nodes.spi.*; -import com.sun.cri.bytecode.*; -import com.sun.cri.ci.*; - -@NodeInfo(shortName = "<<") -public final class LeftShiftNode extends ShiftNode implements Canonicalizable { - - public LeftShiftNode(CiKind kind, ValueNode x, ValueNode y, Graph graph) { - super(kind, kind == CiKind.Int ? Bytecodes.ISHL : Bytecodes.LSHL, x, y, graph); - } - - @Override - public Node canonical(NotifyReProcess reProcess) { - if (y().isConstant()) { - int amount = y().asConstant().asInt(); - int originalAmout = amount; - int mask; - if (kind == CiKind.Int) { - mask = 0x1f; - } else { - assert kind == CiKind.Long; - mask = 0x3f; - } - amount &= mask; - if (x().isConstant()) { - if (kind == CiKind.Int) { - return ConstantNode.forInt(x().asConstant().asInt() << amount, graph()); - } else { - assert kind == CiKind.Long; - return ConstantNode.forLong(x().asConstant().asLong() << amount, graph()); - } - } - if (amount == 0) { - return x(); - } - if (x() instanceof ShiftNode) { - ShiftNode other = (ShiftNode) x(); - if (other.y().isConstant()) { - int otherAmount = other.y().asConstant().asInt() & mask; - if (other instanceof LeftShiftNode) { - int total = amount + otherAmount; - if (total != (total & mask)) { - return ConstantNode.forInt(0, graph()); - } - return new LeftShiftNode(kind, other.x(), ConstantNode.forInt(total, graph()), graph()); - } else if ((other instanceof RightShiftNode || other instanceof UnsignedRightShiftNode) && otherAmount == amount) { - if (kind == CiKind.Long) { - return new AndNode(kind, other.x(), ConstantNode.forLong(-1L << amount, graph()), graph()); - } else { - assert kind == CiKind.Int; - return new AndNode(kind, other.x(), ConstantNode.forInt(-1 << amount, graph()), graph()); - } - } - } - } - if (originalAmout != amount) { - return new LeftShiftNode(kind, x(), ConstantNode.forInt(amount, graph()), graph()); - } - } - return this; - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/calc/LogicNode.java --- a/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/calc/LogicNode.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,49 +0,0 @@ -/* - * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.nodes.calc; - -import com.oracle.max.graal.graph.*; -import com.oracle.max.graal.nodes.*; -import com.oracle.max.graal.nodes.spi.*; -import com.sun.cri.ci.*; - -/** - * The {@code LogicOp} class definition. - */ -public abstract class LogicNode extends BinaryNode { - - /** - * Constructs a new logic operation instruction. - * @param opcode the opcode of the logic operation - * @param x the first input into this instruction - * @param y the second input into this instruction - */ - public LogicNode(CiKind kind, int opcode, ValueNode x, ValueNode y, Graph graph) { - super(kind, opcode, x, y, graph); - } - - @Override - public void accept(ValueVisitor v) { - v.visitLogic(this); - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/calc/NegateBooleanNode.java --- a/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/calc/NegateBooleanNode.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,61 +0,0 @@ -/* - * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.nodes.calc; - -import com.oracle.max.graal.graph.*; -import com.oracle.max.graal.nodes.*; -import com.oracle.max.graal.nodes.spi.*; -import com.sun.cri.ci.*; - -public final class NegateBooleanNode extends BooleanNode implements Canonicalizable { - - @Input private BooleanNode value; - - public BooleanNode value() { - return value; - } - - public void setValue(BooleanNode x) { - updateUsages(value, x); - value = x; - } - - public NegateBooleanNode(BooleanNode value, Graph graph) { - super(CiKind.Int, graph); - setValue(value); - } - - @Override - public void accept(ValueVisitor v) { - } - - @Override - public Node canonical(NotifyReProcess reProcess) { - if (value() instanceof NegateBooleanNode) { - return ((NegateBooleanNode) value()).value(); - } else if (value() instanceof ConstantNode) { - return ConstantNode.forBoolean(!value().asConstant().asBoolean(), graph()); - } - return this; - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/calc/NegateNode.java --- a/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/calc/NegateNode.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,86 +0,0 @@ -/* - * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.nodes.calc; - -import com.oracle.max.graal.graph.*; -import com.oracle.max.graal.nodes.*; -import com.oracle.max.graal.nodes.spi.*; -import com.sun.cri.ci.*; - -/** - * The {@code NegateOp} instruction negates its operand. - */ -public final class NegateNode extends FloatingNode implements Canonicalizable { - - @Input - private ValueNode x; - - public ValueNode x() { - return x; - } - - public void setX(ValueNode x) { - updateUsages(this.x, x); - this.x = x; - } - - /** - * Creates new NegateOp instance. - * - * @param x the instruction producing the value that is input to this instruction - */ - public NegateNode(ValueNode x, Graph graph) { - super(x.kind, graph); - setX(x); - } - - // for copying - private NegateNode(CiKind kind, Graph graph) { - super(kind, graph); - } - - @Override - public void accept(ValueVisitor v) { - v.visitNegate(this); - } - - @Override - public Node canonical(NotifyReProcess reProcess) { - if (x().isConstant()) { - switch (x().kind) { - case Int: - return ConstantNode.forInt(-x().asConstant().asInt(), graph()); - case Long: - return ConstantNode.forLong(-x().asConstant().asLong(), graph()); - case Float: - return ConstantNode.forFloat(-x().asConstant().asFloat(), graph()); - case Double: - return ConstantNode.forDouble(-x().asConstant().asDouble(), graph()); - } - } - if (x() instanceof NegateNode) { - return ((NegateNode) x()).x(); - } - return this; - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/calc/NormalizeCompareNode.java --- a/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/calc/NormalizeCompareNode.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,64 +0,0 @@ -/* - * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.nodes.calc; - -import java.util.*; - -import com.oracle.max.graal.graph.*; -import com.oracle.max.graal.nodes.*; -import com.oracle.max.graal.nodes.spi.*; -import com.sun.cri.bytecode.*; -import com.sun.cri.ci.*; - -/** - * Returns -1, 0, or 1 if either x > y, x == y, or x < y. - */ -public final class NormalizeCompareNode extends BinaryNode { - - /** - * Creates a new compare operation. - * @param opcode the bytecode opcode - * @param kind the result kind - * @param x the first input - * @param y the second input - */ - public NormalizeCompareNode(int opcode, CiKind kind, ValueNode x, ValueNode y, Graph graph) { - super(kind, opcode, x, y, graph); - } - - @Override - public void accept(ValueVisitor v) { - v.visitNormalizeCompare(this); - } - - @Override - public Map getDebugProperties() { - Map properties = super.getDebugProperties(); - properties.put("isUnorderedLess", isUnorderedLess()); - return properties; - } - - public boolean isUnorderedLess() { - return this.opcode == Bytecodes.FCMPL || this.opcode == Bytecodes.DCMPL; - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/calc/OrNode.java --- a/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/calc/OrNode.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,75 +0,0 @@ -/* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.nodes.calc; - -import com.oracle.max.graal.graph.*; -import com.oracle.max.graal.nodes.*; -import com.oracle.max.graal.nodes.spi.*; -import com.sun.cri.bytecode.*; -import com.sun.cri.ci.*; - -@NodeInfo(shortName = "|") -public final class OrNode extends LogicNode implements Canonicalizable { - - public OrNode(CiKind kind, ValueNode x, ValueNode y, Graph graph) { - super(kind, kind == CiKind.Int ? Bytecodes.IOR : Bytecodes.LOR, x, y, graph); - } - - @Override - public Node canonical(NotifyReProcess reProcess) { - if (x() == y()) { - return x(); - } - if (x().isConstant() && !y().isConstant()) { - swapOperands(); - } - if (x().isConstant()) { - if (kind == CiKind.Int) { - return ConstantNode.forInt(x().asConstant().asInt() | y().asConstant().asInt(), graph()); - } else { - assert kind == CiKind.Long; - return ConstantNode.forLong(x().asConstant().asLong() | y().asConstant().asLong(), graph()); - } - } else if (y().isConstant()) { - if (kind == CiKind.Int) { - int c = y().asConstant().asInt(); - if (c == -1) { - return ConstantNode.forInt(-1, graph()); - } - if (c == 0) { - return x(); - } - } else { - assert kind == CiKind.Long; - long c = y().asConstant().asLong(); - if (c == -1) { - return ConstantNode.forLong(-1, graph()); - } - if (c == 0) { - return x(); - } - } - } - return this; - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/calc/RightShiftNode.java --- a/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/calc/RightShiftNode.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,81 +0,0 @@ -/* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.nodes.calc; - -import com.oracle.max.graal.graph.*; -import com.oracle.max.graal.nodes.*; -import com.oracle.max.graal.nodes.spi.*; -import com.sun.cri.bytecode.*; -import com.sun.cri.ci.*; - -@NodeInfo(shortName = ">>") -public final class RightShiftNode extends ShiftNode implements Canonicalizable { - - public RightShiftNode(CiKind kind, ValueNode x, ValueNode y, Graph graph) { - super(kind, kind == CiKind.Int ? Bytecodes.ISHR : Bytecodes.LSHR, x, y, graph); - } - - @Override - public Node canonical(NotifyReProcess reProcess) { - if (y().isConstant()) { - int amount = y().asConstant().asInt(); - int originalAmout = amount; - int mask; - if (kind == CiKind.Int) { - mask = 0x1f; - } else { - assert kind == CiKind.Long; - mask = 0x3f; - } - amount &= mask; - if (x().isConstant()) { - if (kind == CiKind.Int) { - return ConstantNode.forInt(x().asConstant().asInt() >> amount, graph()); - } else { - assert kind == CiKind.Long; - return ConstantNode.forLong(x().asConstant().asLong() >> amount, graph()); - } - } - if (amount == 0) { - return x(); - } - if (x() instanceof ShiftNode) { - ShiftNode other = (ShiftNode) x(); - if (other.y().isConstant()) { - int otherAmount = other.y().asConstant().asInt() & mask; - if (other instanceof RightShiftNode) { - int total = amount + otherAmount; - if (total != (total & mask)) { - return ConstantNode.forInt(0, graph()); - } - return new RightShiftNode(kind, other.x(), ConstantNode.forInt(total, graph()), graph()); - } - } - } - if (originalAmout != amount) { - return new RightShiftNode(kind, x(), ConstantNode.forInt(amount, graph()), graph()); - } - } - return this; - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/calc/ShiftNode.java --- a/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/calc/ShiftNode.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,50 +0,0 @@ -/* - * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.nodes.calc; - -import com.oracle.max.graal.graph.*; -import com.oracle.max.graal.nodes.*; -import com.oracle.max.graal.nodes.spi.*; -import com.sun.cri.ci.*; - -/** - * The {@code ShiftOp} class represents shift operations. - */ -public abstract class ShiftNode extends BinaryNode { - - /** - * Creates a new shift operation. - * @param opcode the opcode of the shift - * @param x the first input value - * @param s the second input value - */ - public ShiftNode(CiKind kind, int opcode, ValueNode x, ValueNode s, Graph graph) { - super(kind, opcode, x, s, graph); - assert x == null || x.kind == kind; - } - - @Override - public void accept(ValueVisitor v) { - v.visitShift(this); - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/calc/UnsignedRightShiftNode.java --- a/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/calc/UnsignedRightShiftNode.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,88 +0,0 @@ -/* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.nodes.calc; - -import com.oracle.max.graal.graph.*; -import com.oracle.max.graal.nodes.*; -import com.oracle.max.graal.nodes.spi.*; -import com.sun.cri.bytecode.*; -import com.sun.cri.ci.*; - -@NodeInfo(shortName = ">>>") -public final class UnsignedRightShiftNode extends ShiftNode implements Canonicalizable { - - public UnsignedRightShiftNode(CiKind kind, ValueNode x, ValueNode y, Graph graph) { - super(kind, kind == CiKind.Int ? Bytecodes.IUSHR : Bytecodes.LUSHR, x, y, graph); - } - - @Override - public Node canonical(NotifyReProcess reProcess) { - if (y().isConstant()) { - int amount = y().asConstant().asInt(); - int originalAmout = amount; - int mask; - if (kind == CiKind.Int) { - mask = 0x1f; - } else { - assert kind == CiKind.Long; - mask = 0x3f; - } - amount &= mask; - if (x().isConstant()) { - if (kind == CiKind.Int) { - return ConstantNode.forInt(x().asConstant().asInt() >>> amount, graph()); - } else { - assert kind == CiKind.Long; - return ConstantNode.forLong(x().asConstant().asLong() >>> amount, graph()); - } - } - if (amount == 0) { - return x(); - } - if (x() instanceof ShiftNode) { - ShiftNode other = (ShiftNode) x(); - if (other.y().isConstant()) { - int otherAmount = other.y().asConstant().asInt() & mask; - if (other instanceof UnsignedRightShiftNode) { - int total = amount + otherAmount; - if (total != (total & mask)) { - return ConstantNode.forInt(0, graph()); - } - return new UnsignedRightShiftNode(kind, other.x(), ConstantNode.forInt(total, graph()), graph()); - } else if (other instanceof LeftShiftNode && otherAmount == amount) { - if (kind == CiKind.Long) { - return new AndNode(kind, other.x(), ConstantNode.forLong(-1L >>> amount, graph()), graph()); - } else { - assert kind == CiKind.Int; - return new AndNode(kind, other.x(), ConstantNode.forInt(-1 >>> amount, graph()), graph()); - } - } - } - } - if (originalAmout != amount) { - return new UnsignedRightShiftNode(kind, x(), ConstantNode.forInt(amount, graph()), graph()); - } - } - return this; - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/calc/XorNode.java --- a/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/calc/XorNode.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,74 +0,0 @@ -/* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.nodes.calc; - -import com.oracle.max.graal.graph.*; -import com.oracle.max.graal.nodes.*; -import com.oracle.max.graal.nodes.spi.*; -import com.sun.cri.bytecode.*; -import com.sun.cri.ci.*; - -@NodeInfo(shortName = "^") -public final class XorNode extends LogicNode implements Canonicalizable { - - public XorNode(CiKind kind, ValueNode x, ValueNode y, Graph graph) { - super(kind, kind == CiKind.Int ? Bytecodes.IXOR : Bytecodes.LXOR, x, y, graph); - } - - @Override - public Node canonical(NotifyReProcess reProcess) { - if (x() == y()) { - if (kind == CiKind.Int) { - return ConstantNode.forInt(0, graph()); - } else { - assert kind == CiKind.Long; - return ConstantNode.forLong(0L, graph()); - } - } - if (x().isConstant() && !y().isConstant()) { - swapOperands(); - } - if (x().isConstant()) { - if (kind == CiKind.Int) { - return ConstantNode.forInt(x().asConstant().asInt() ^ y().asConstant().asInt(), graph()); - } else { - assert kind == CiKind.Long; - return ConstantNode.forLong(x().asConstant().asLong() ^ y().asConstant().asLong(), graph()); - } - } else if (y().isConstant()) { - if (kind == CiKind.Int) { - int c = y().asConstant().asInt(); - if (c == 0) { - return x(); - } - } else { - assert kind == CiKind.Long; - long c = y().asConstant().asLong(); - if (c == 0) { - return x(); - } - } - } - return this; - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/extended/AbstractMemoryCheckpointNode.java --- a/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/extended/AbstractMemoryCheckpointNode.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,57 +0,0 @@ -/* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.nodes.extended; - -import java.util.*; - -import com.oracle.max.graal.graph.*; -import com.oracle.max.graal.nodes.*; -import com.sun.cri.ci.*; - - -public abstract class AbstractMemoryCheckpointNode extends StateSplit { - - @Input private final NodeInputList mergedNodes = new NodeInputList(this); - - private static final int SUCCESSOR_COUNT = 0; - private static final int INPUT_COUNT = 0; - - public AbstractMemoryCheckpointNode(Graph graph) { - this(CiKind.Illegal, graph); - } - - public AbstractMemoryCheckpointNode(CiKind result, Graph graph) { - super(result, graph); - } - - @Override - public Map getDebugProperties() { - Map debugProperties = super.getDebugProperties(); - debugProperties.put("memoryCheckpoint", "true"); - return debugProperties; - } - - public NodeInputList mergedNodes() { - return mergedNodes; - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/extended/AbstractVectorNode.java --- a/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/extended/AbstractVectorNode.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,83 +0,0 @@ -/* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.nodes.extended; - -import java.util.*; - -import com.oracle.max.graal.graph.*; -import com.oracle.max.graal.nodes.*; -import com.sun.cri.ci.*; - - -public abstract class AbstractVectorNode extends StateSplit { - @Input private AbstractVectorNode vector; - - public AbstractVectorNode vector() { - return vector; - } - - public void setVector(AbstractVectorNode x) { - updateUsages(vector, x); - vector = x; - } - - public AbstractVectorNode(CiKind kind, AbstractVectorNode vector, Graph graph) { - super(kind, graph); - setVector(vector); - } - - protected static AbstractVectorNode findCommonNode(AbstractVectorNode left, AbstractVectorNode right, List leftList, List rightList) { - Set occured = new HashSet(); - AbstractVectorNode common = null; - AbstractVectorNode cur = left; - while (cur != null) { - occured.add(cur); - cur = cur.vector(); - } - - cur = right; - while (cur != null) { - if (occured.contains(cur)) { - common = cur; - break; - } - cur = cur.vector(); - } - - fillUntil(left, cur, leftList); - fillUntil(right, cur, rightList); - return common; - } - - private static void fillUntil(AbstractVectorNode left, AbstractVectorNode until, List leftList) { - AbstractVectorNode cur = left; - while (cur != null && cur != until) { - leftList.add(cur); - cur = cur.vector(); - } - } - - public void addToLoop(LoopBeginNode loop, IdentityHashMap nodes) { - throw new IllegalStateException("unimplemented"); - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/extended/AccessNode.java --- a/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/extended/AccessNode.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,76 +0,0 @@ -/* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.nodes.extended; - -import com.oracle.max.graal.graph.*; -import com.oracle.max.graal.nodes.*; -import com.sun.cri.ci.*; - - -public abstract class AccessNode extends AbstractMemoryCheckpointNode { - @Input private ValueNode object; - @Input private GuardNode guard; - @Input private LocationNode location; - @Input private final NodeInputList dependencies = new NodeInputList(this); - - public ValueNode object() { - return object; - } - - public void setObject(ValueNode x) { - updateUsages(object, x); - object = x; - } - - public GuardNode guard() { - return guard; - } - - public void setGuard(GuardNode x) { - updateUsages(guard, x); - guard = x; - } - - public LocationNode location() { - return location; - } - - public void setLocation(LocationNode x) { - updateUsages(location, x); - location = x; - } - - public AccessNode(CiKind kind, ValueNode object, LocationNode location, Graph graph) { - super(kind, graph); - setLocation(location); - setObject(object); - } - - public void addDependency(Node x) { - dependencies.add(x); - } - - public NodeInputList dependencies() { - return dependencies; - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/extended/AccessVectorNode.java --- a/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/extended/AccessVectorNode.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,58 +0,0 @@ -/* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.nodes.extended; - -import com.oracle.max.graal.graph.*; -import com.oracle.max.graal.nodes.*; -import com.sun.cri.ci.*; - - -public abstract class AccessVectorNode extends AbstractVectorNode { - @Input private ValueNode object; - @Input private LocationNode location; - @Input private final NodeInputList dependencies = new NodeInputList(this); - - public ValueNode object() { - return object; - } - - public void setObject(ValueNode x) { - updateUsages(object, x); - object = x; - } - - public LocationNode location() { - return location; - } - - public void setLocation(LocationNode x) { - updateUsages(location, x); - location = x; - } - - public AccessVectorNode(CiKind kind, AbstractVectorNode vector, ValueNode object, LocationNode location, Graph graph) { - super(kind, vector, graph); - setObject(object); - setLocation(location); - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/extended/CreateVectorNode.java --- a/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/extended/CreateVectorNode.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,154 +0,0 @@ -/* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.nodes.extended; - -import java.util.*; - -import com.oracle.max.graal.graph.*; -import com.oracle.max.graal.nodes.*; -import com.oracle.max.graal.nodes.PhiNode.PhiType; -import com.oracle.max.graal.nodes.calc.*; -import com.oracle.max.graal.nodes.spi.*; -import com.sun.cri.ci.*; - - -public final class CreateVectorNode extends AbstractVectorNode { - @Input private ValueNode length; - - public ValueNode length() { - return length; - } - - public void setLength(ValueNode x) { - updateUsages(length, x); - length = x; - } - - private boolean reversed; - - public boolean reversed() { - return reversed; - } - - public void setReversed(boolean r) { - reversed = r; - } - - public CreateVectorNode(boolean reversed, ValueNode length, Graph graph) { - super(CiKind.Illegal, null, graph); - setLength(length); - setReversed(reversed); - } - - @Override - public Map getDebugProperties() { - Map debugProperties = super.getDebugProperties(); - debugProperties.put("reversed", reversed); - return debugProperties; - } - - @SuppressWarnings("unchecked") - @Override - public T lookup(Class clazz) { - if (clazz == LIRGeneratorOp.class) { - return null; - } else if (clazz == LoweringOp.class) { - return (T) LOWERING_OP; - } - return super.lookup(clazz); - } - - private LoopBeginNode createLoop(Map map) { - EndNode end = new EndNode(graph()); - LoopBeginNode loopBegin = new LoopBeginNode(graph()); - loopBegin.addEnd(end); - PhiNode loopVariable = new PhiNode(CiKind.Int, loopBegin, PhiType.Value, graph()); - - if (reversed) { - IntegerSubNode add = new IntegerSubNode(CiKind.Int, loopVariable, ConstantNode.forInt(1, graph()), graph()); - loopVariable.addInput(new IntegerSubNode(CiKind.Int, length(), ConstantNode.forInt(1, graph()), graph())); - loopVariable.addInput(add); - } else { - IntegerAddNode add = new IntegerAddNode(CiKind.Int, loopVariable, ConstantNode.forInt(1, graph()), graph()); - loopVariable.addInput(ConstantNode.forInt(0, graph())); - loopVariable.addInput(add); - } - - LoopEndNode loopEnd = new LoopEndNode(graph()); - loopEnd.setLoopBegin(loopBegin); - loopBegin.setStateAfter(stateAfter()); - CompareNode condition; - if (reversed) { - condition = new CompareNode(loopVariable, Condition.GE, ConstantNode.forInt(0, graph()), graph()); - } else { - condition = new CompareNode(loopVariable, Condition.LT, length(), graph()); - } - int expectedLength = 100; // TODO: it may be possible to get a more accurate estimate...? - if (length().isConstant()) { - expectedLength = length().asConstant().asInt(); - } - IfNode ifNode = new IfNode(condition, 1.0 / expectedLength, graph()); - loopBegin.setNext(ifNode); - ifNode.setTrueSuccessor(loopEnd); - this.replaceAtPredecessors(end); - ifNode.setFalseSuccessor(this); - map.put(this, loopVariable); - return loopBegin; - } - - private static final LoweringOp LOWERING_OP = new LoweringOp() { - @Override - public void lower(Node n, CiLoweringTool tool) { - CreateVectorNode vectorNode = (CreateVectorNode) n; - - IdentityHashMap nodes = new IdentityHashMap(); - LoopBeginNode begin = vectorNode.createLoop(nodes); - for (Node use : vectorNode.usages()) { - processUse(begin, use, nodes); - } - } - - private void processUse(LoopBeginNode loop, Node use, IdentityHashMap nodes) { - AbstractVectorNode vectorNode = (AbstractVectorNode) use; - if (nodes.containsKey(vectorNode)) { - return; - } - nodes.put(vectorNode, null); - - // Make sure inputs are evaluated. - for (Node input : use.inputs()) { - if (input instanceof AbstractVectorNode) { - AbstractVectorNode abstractVectorNodeInput = (AbstractVectorNode) input; - processUse(loop, abstractVectorNodeInput, nodes); - } - } - - vectorNode.addToLoop(loop, nodes); - - // Go on to usages. - for (Node usage : use.usages()) { - processUse(loop, usage, nodes); - } - } - }; -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/extended/LocationNode.java --- a/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/extended/LocationNode.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,114 +0,0 @@ -/* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.nodes.extended; - -import com.oracle.max.graal.graph.*; -import com.oracle.max.graal.nodes.*; -import com.oracle.max.graal.nodes.calc.*; -import com.oracle.max.graal.nodes.spi.*; -import com.sun.cri.ci.*; -import com.sun.cri.ci.CiAddress.Scale; - - -public final class LocationNode extends FloatingNode { - @Input private ValueNode index; - - @Data private int displacement; - @Data private boolean indexScalingEnabled = true; - @Data private CiKind valueKind; - @Data private Object locationIdentity; - - public ValueNode index() { - return index; - } - - public void setIndex(ValueNode x) { - updateUsages(index, x); - index = x; - } - - public static final Object UNSAFE_ACCESS_LOCATION = new Object(); - public static final Object FINAL_LOCATION = new Object(); - - public static Object getArrayLocation(CiKind elementKind) { - return elementKind; - } - - public int displacement() { - return displacement; - } - - /** - * @return whether scaling of the index by the value kind's size is enabled (the default) or disabled. - */ - public boolean indexScalingEnabled() { - return indexScalingEnabled; - } - - /** - * Enables or disables scaling of the index by the value kind's size. Has no effect if the index input is not used. - */ - public void setIndexScalingEnabled(boolean enable) { - this.indexScalingEnabled = enable; - } - - public static LocationNode create(Object identity, CiKind kind, int displacement, Graph graph) { - LocationNode result = new LocationNode(identity, kind, displacement, graph); - return graph.value(result); - } - - private LocationNode(Object identity, CiKind kind, int displacement, Graph graph) { - super(CiKind.Illegal, graph); - this.displacement = displacement; - this.valueKind = kind; - this.locationIdentity = identity; - } - - @Override - public T lookup(Class clazz) { - if (clazz == LIRGeneratorOp.class) { - return null; - } - return super.lookup(clazz); - } - - public CiKind getValueKind() { - return valueKind; - } - - public CiAddress createAddress(LIRGeneratorTool lirGenerator, ValueNode object) { - CiValue indexValue = CiValue.IllegalValue; - Scale indexScale = Scale.Times1; - if (this.index() != null) { - indexValue = lirGenerator.load(this.index()); - if (indexScalingEnabled) { - indexScale = Scale.fromInt(valueKind.sizeInBytes(lirGenerator.target().wordSize)); - } - } - return new CiAddress(valueKind, lirGenerator.load(object), indexValue, indexScale, displacement); - } - - public Object locationIdentity() { - return locationIdentity; - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/extended/LookupSwitchNode.java --- a/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/extended/LookupSwitchNode.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,72 +0,0 @@ -/* - * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.nodes.extended; - -import java.util.*; - -import com.oracle.max.graal.graph.*; -import com.oracle.max.graal.nodes.*; -import com.oracle.max.graal.nodes.spi.*; - -/** - * The {@code LookupSwitch} instruction represents a lookup switch bytecode, which has a sorted - * array of key values. - */ -public final class LookupSwitchNode extends SwitchNode { - - private static final int INPUT_COUNT = 0; - private static final int SUCCESSOR_COUNT = 0; - - final int[] keys; - - /** - * Constructs a new LookupSwitch instruction. - * @param value the instruction producing the value being switched on - * @param successors the list of successors - * @param keys the list of keys, sorted - * @param stateAfter the state after the switch - * @param graph - */ - public LookupSwitchNode(ValueNode value, List successors, int[] keys, double[] probability, Graph graph) { - super(value, successors, probability, INPUT_COUNT, SUCCESSOR_COUNT, graph); - this.keys = keys; - } - - /** - * Gets the key at the specified index. - * @param i the index - * @return the key at that index - */ - public int keyAt(int i) { - return keys[i]; - } - - public int keysLength() { - return keys.length; - } - - @Override - public void accept(ValueVisitor v) { - v.visitLookupSwitch(this); - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/extended/ReadNode.java --- a/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/extended/ReadNode.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,41 +0,0 @@ -/* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.nodes.extended; - -import com.oracle.max.graal.graph.*; -import com.oracle.max.graal.nodes.*; -import com.oracle.max.graal.nodes.spi.*; -import com.sun.cri.ci.*; - - -public final class ReadNode extends AccessNode implements Node.ValueNumberable { - - public ReadNode(CiKind kind, ValueNode object, LocationNode location, Graph graph) { - super(kind, object, location, graph); - } - - @Override - public void accept(ValueVisitor v) { - v.visitMemoryRead(this); - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/extended/ReadVectorNode.java --- a/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/extended/ReadVectorNode.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,58 +0,0 @@ -/* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.nodes.extended; - -import java.util.*; - -import com.oracle.max.graal.graph.*; -import com.oracle.max.graal.nodes.*; -import com.oracle.max.graal.nodes.spi.*; -import com.sun.cri.ci.*; - - -public final class ReadVectorNode extends AccessVectorNode { - - public ReadVectorNode(AbstractVectorNode vector, ValueNode object, LocationNode location, Graph graph) { - super(CiKind.Illegal, vector, object, location, graph); - } - - @Override - public T lookup(Class clazz) { - if (clazz == LIRGeneratorOp.class) { - return null; - } - return super.lookup(clazz); - } - - @Override - public void addToLoop(LoopBeginNode loop, IdentityHashMap nodes) { - LocationNode newLocation = LocationNode.create(LocationNode.getArrayLocation(location().getValueKind()), location().getValueKind(), location().displacement(), graph()); - ValueNode index = nodes.get(vector()); - assert index != null; - newLocation.setIndex(index); - ReadNode readNode = new ReadNode(location().getValueKind().stackKind(), object(), newLocation, graph()); - loop.loopEnd().replaceAtPredecessors(readNode); - readNode.setNext(loop.loopEnd()); - nodes.put(this, readNode); - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/extended/SwitchNode.java --- a/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/extended/SwitchNode.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,67 +0,0 @@ -/* - * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.nodes.extended; - -import java.util.*; - -import com.oracle.max.graal.graph.*; -import com.oracle.max.graal.nodes.*; -import com.sun.cri.ci.*; - -/** - * The {@code Switch} class is the base of both lookup and table switches. - */ -public abstract class SwitchNode extends ControlSplitNode { - - @Input private ValueNode value; - - public ValueNode value() { - return value; - } - - public void setValue(ValueNode x) { - updateUsages(value, x); - value = x; - } - - /** - * Constructs a new Switch. - * @param value the instruction that provides the value to be switched over - * @param successors the list of successors of this switch - * @param stateAfter the state after the switch - * @param graph - */ - public SwitchNode(ValueNode value, List successors, double[] probability, int inputCount, int successorCount, Graph graph) { - super(CiKind.Illegal, successors, probability, graph); - setValue(value); - } - - /** - * Gets the number of cases that this switch covers (excluding the default case). - * @return the number of cases - */ - public int numberOfCases() { - return blockSuccessorCount() - 1; - } - -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/extended/TableSwitchNode.java --- a/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/extended/TableSwitchNode.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,74 +0,0 @@ -/* - * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.nodes.extended; - -import java.util.*; - -import com.oracle.max.graal.graph.*; -import com.oracle.max.graal.nodes.*; -import com.oracle.max.graal.nodes.spi.*; - -/** - * The {@code TableSwitch} instruction represents a table switch. - */ -public final class TableSwitchNode extends SwitchNode { - - private static final int INPUT_COUNT = 0; - private static final int SUCCESSOR_COUNT = 0; - - final int lowKey; - - /** - * Constructs a new TableSwitch instruction. - * @param value the instruction producing the value being switched on - * @param successors the list of successors - * @param lowKey the lowest integer key in the table - * @param stateAfter the state after the switch - * @param graph - */ - public TableSwitchNode(ValueNode value, List successors, int lowKey, double[] probability, Graph graph) { - super(value, successors, probability, INPUT_COUNT, SUCCESSOR_COUNT, graph); - this.lowKey = lowKey; - } - - /** - * Gets the lowest key in the table switch (inclusive). - * @return the low key - */ - public int lowKey() { - return lowKey; - } - - /** - * Gets the highest key in the table switch (exclusive). - * @return the high key - */ - public int highKey() { - return lowKey + numberOfCases(); - } - - @Override - public void accept(ValueVisitor v) { - v.visitTableSwitch(this); - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/extended/ValueAnchorNode.java --- a/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/extended/ValueAnchorNode.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,54 +0,0 @@ -/* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.nodes.extended; - -import com.oracle.max.graal.graph.*; -import com.oracle.max.graal.nodes.*; -import com.oracle.max.graal.nodes.spi.*; -import com.sun.cri.ci.*; - -/** - * The ValueAnchor instruction keeps non-CFG nodes above a certain point in the graph. - */ -public final class ValueAnchorNode extends FixedWithNextNode { - @Input private ValueNode object; - - public ValueNode object() { - return object; - } - - public void setObject(ValueNode x) { - updateUsages(object, x); - object = x; - } - - public ValueAnchorNode(ValueNode object, Graph graph) { - super(CiKind.Illegal, graph); - setObject(object); - } - - @Override - public void accept(ValueVisitor v) { - v.visitValueAnchor(this); - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/extended/WriteMemoryCheckpointNode.java --- a/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/extended/WriteMemoryCheckpointNode.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,47 +0,0 @@ -/* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.nodes.extended; - -import com.oracle.max.graal.graph.*; -import com.oracle.max.graal.nodes.spi.*; -import com.sun.cri.ci.*; - - -public final class WriteMemoryCheckpointNode extends AbstractMemoryCheckpointNode { - - public WriteMemoryCheckpointNode(Graph graph) { - this(CiKind.Illegal, graph); - } - - public WriteMemoryCheckpointNode(CiKind result, Graph graph) { - super(result, graph); - } - - @Override - public T lookup(Class clazz) { - if (clazz == LIRGeneratorOp.class) { - return null; - } - return super.lookup(clazz); - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/extended/WriteNode.java --- a/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/extended/WriteNode.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,52 +0,0 @@ -/* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.nodes.extended; - -import com.oracle.max.graal.graph.*; -import com.oracle.max.graal.nodes.*; -import com.oracle.max.graal.nodes.spi.*; -import com.sun.cri.ci.*; - - -public final class WriteNode extends AccessNode { - @Input private ValueNode value; - - public ValueNode value() { - return value; - } - - public void setValue(ValueNode x) { - updateUsages(value, x); - value = x; - } - - public WriteNode(CiKind kind, ValueNode object, ValueNode value, LocationNode location, Graph graph) { - super(kind, object, location, graph); - setValue(value); - } - - @Override - public void accept(ValueVisitor v) { - v.visitMemoryWrite(this); - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/extended/WriteVectorNode.java --- a/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/extended/WriteVectorNode.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,70 +0,0 @@ -/* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.nodes.extended; - -import java.util.*; - -import com.oracle.max.graal.graph.*; -import com.oracle.max.graal.nodes.*; -import com.oracle.max.graal.nodes.spi.*; -import com.sun.cri.ci.*; - - -public final class WriteVectorNode extends AccessVectorNode { - @Input private AbstractVectorNode values; - - public AbstractVectorNode values() { - return values; - } - - public void setValues(AbstractVectorNode x) { - updateUsages(values, x); - values = x; - } - - public WriteVectorNode(AbstractVectorNode vector, ValueNode object, LocationNode location, AbstractVectorNode values, Graph graph) { - super(CiKind.Illegal, vector, object, location, graph); - setValues(values); - } - - @Override - public T lookup(Class clazz) { - if (clazz == LIRGeneratorOp.class) { - return null; - } - return super.lookup(clazz); - } - - @Override - public void addToLoop(LoopBeginNode loop, IdentityHashMap nodes) { - LocationNode newLocation = LocationNode.create(LocationNode.getArrayLocation(location().getValueKind()), location().getValueKind(), location().displacement(), graph()); - ValueNode index = nodes.get(vector()); - ValueNode value = nodes.get(values()); - assert index != null; - assert value != null; - newLocation.setIndex(index); - WriteNode writeNode = new WriteNode(location().getValueKind().stackKind(), object(), value, newLocation, graph()); - loop.loopEnd().replaceAtPredecessors(writeNode); - writeNode.setNext(loop.loopEnd()); - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/java/AccessArrayNode.java --- a/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/java/AccessArrayNode.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,56 +0,0 @@ -/* - * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.nodes.java; - -import com.oracle.max.graal.graph.*; -import com.oracle.max.graal.nodes.*; -import com.sun.cri.ci.*; - -/** - * This the base class of all array operations. - */ -public abstract class AccessArrayNode extends StateSplit { - - @Input private ValueNode array; - - public ValueNode array() { - return array; - } - - public void setArray(ValueNode x) { - updateUsages(array, x); - array = x; - } - - /** - * Creates a new AccessArray instruction. - * @param kind the type of the result of this instruction - * @param array the instruction that produces the array object value - * @param graph - */ - public AccessArrayNode(CiKind kind, ValueNode array, Graph graph) { - super(kind, graph); - setArray(array); - } - -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/java/AccessFieldNode.java --- a/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/java/AccessFieldNode.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,96 +0,0 @@ -/* - * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.nodes.java; - -import java.lang.reflect.*; -import java.util.*; - -import com.oracle.max.graal.graph.*; -import com.oracle.max.graal.nodes.*; -import com.sun.cri.ci.*; -import com.sun.cri.ri.*; - -/** - * The base class of all instructions that access fields. - */ -public abstract class AccessFieldNode extends StateSplit { - - @Input private ValueNode object; - - public ValueNode object() { - return object; - } - - public void setObject(ValueNode x) { - updateUsages(object, x); - object = x; - } - - protected final RiField field; - - /** - * Constructs a new access field object. - * @param kind the result kind of the access - * @param object the instruction producing the receiver object - * @param field the compiler interface representation of the field - * @param graph - */ - public AccessFieldNode(CiKind kind, ValueNode object, RiField field, Graph graph) { - super(kind, graph); - this.field = field; - setObject(object); - assert field.isResolved(); - assert field.holder().isInitialized(); - } - - /** - * Gets the compiler interface field for this field access. - * @return the compiler interface field for this field access - */ - public RiField field() { - return field; - } - - /** - * Checks whether this field access is an access to a static field. - * @return {@code true} if this field access is to a static field - */ - public boolean isStatic() { - return Modifier.isStatic(field.accessFlags()); - } - - /** - * Checks whether this field is declared volatile. - * @return {@code true} if the field is resolved and declared volatile - */ - public boolean isVolatile() { - return Modifier.isVolatile(field.accessFlags()); - } - - @Override - public Map getDebugProperties() { - Map properties = super.getDebugProperties(); - properties.put("field", field); - return properties; - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/java/AccessIndexedNode.java --- a/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/java/AccessIndexedNode.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,83 +0,0 @@ -/* - * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.nodes.java; - -import com.oracle.max.graal.graph.*; -import com.oracle.max.graal.nodes.*; -import com.sun.cri.ci.*; - -/** - * The {@code AccessIndexed} class is the base class of instructions that read or write - * elements of an array. - */ -public abstract class AccessIndexedNode extends AccessArrayNode { - - @Input private ValueNode index; - - @Input private ValueNode length; - - public ValueNode index() { - return index; - } - - public void setIndex(ValueNode x) { - updateUsages(index, x); - index = x; - } - - public ValueNode length() { - return length; - } - - public void setLength(ValueNode x) { - updateUsages(length, x); - length = x; - } - - private final CiKind elementType; - - /** - * Create an new AccessIndexed instruction. - * @param kind the result kind of the access - * @param array the instruction producing the array - * @param index the instruction producing the index - * @param length the instruction producing the length (used in bounds check elimination?) - * @param elementKind the type of the elements of the array - * @param graph - */ - protected AccessIndexedNode(CiKind kind, ValueNode array, ValueNode index, ValueNode length, CiKind elementKind, Graph graph) { - super(kind, array, graph); - setIndex(index); - setLength(length); - this.elementType = elementKind; - } - - /** - * Gets the element type of the array. - * @return the element type - */ - public CiKind elementKind() { - return elementType; - } - -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/java/AccessMonitorNode.java --- a/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/java/AccessMonitorNode.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,75 +0,0 @@ -/* - * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.nodes.java; - -import com.oracle.max.graal.graph.*; -import com.oracle.max.graal.nodes.*; -import com.oracle.max.graal.nodes.extended.*; -import com.sun.cri.ci.*; - -/** - * The {@code AccessMonitor} instruction is the base class of both monitor acquisition and release. - */ -public abstract class AccessMonitorNode extends AbstractMemoryCheckpointNode { - - @Input private ValueNode object; - @Input private ValueNode lockAddress; - - public ValueNode object() { - return object; - } - - public void setObject(ValueNode x) { - updateUsages(object, x); - object = x; - } - - public ValueNode lockAddress() { - return lockAddress; - } - - public void setLockAddress(ValueNode x) { - updateUsages(lockAddress, x); - lockAddress = x; - } - - /** - * The lock number of this monitor access. - */ - public final int lockNumber; - - /** - * Creates a new AccessMonitor instruction. - * - * @param object the instruction producing the object - * @param lockAddress the address of the on-stack lock object or {@code null} if the runtime does not place locks on the stack - * @param lockNumber the number of the lock being acquired - * @param graph - */ - public AccessMonitorNode(ValueNode object, ValueNode lockAddress, int lockNumber, Graph graph) { - super(CiKind.Illegal, graph); - this.lockNumber = lockNumber; - setObject(object); - setLockAddress(lockAddress); - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/java/ArrayLengthNode.java --- a/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/java/ArrayLengthNode.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,83 +0,0 @@ -/* - * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.nodes.java; - -import com.oracle.max.graal.graph.*; -import com.oracle.max.graal.nodes.*; -import com.oracle.max.graal.nodes.calc.*; -import com.oracle.max.graal.nodes.spi.*; -import com.sun.cri.ci.*; -import com.sun.cri.ri.*; - -/** - * The {@code ArrayLength} instruction gets the length of an array. - */ -public final class ArrayLengthNode extends FloatingNode implements Canonicalizable { - - @Input private ValueNode array; - - public ValueNode array() { - return array; - } - - public void setArray(ValueNode x) { - updateUsages(array, x); - array = x; - } - - /** - * Constructs a new ArrayLength instruction. - * - * @param array the instruction producing the array - * @param newFrameState the state after executing this instruction - */ - public ArrayLengthNode(ValueNode array, Graph graph) { - super(CiKind.Int, graph); - setArray(array); - } - - @Override - public void accept(ValueVisitor v) { - v.visitArrayLength(this); - } - - @Override - public Node canonical(NotifyReProcess reProcess) { - if (array() instanceof NewArrayNode) { - ValueNode length = ((NewArrayNode) array()).dimension(0); - assert length != null; - return length; - } - CiConstant constantValue = null; - if (array().isConstant()) { - constantValue = array().asConstant(); - if (constantValue != null && constantValue.isNonNull()) { - if (graph() instanceof CompilerGraph) { - RiRuntime runtime = ((CompilerGraph) graph()).runtime(); - return ConstantNode.forInt(runtime.getArrayLength(constantValue), graph()); - } - } - } - return this; - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/java/CheckCastNode.java --- a/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/java/CheckCastNode.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,90 +0,0 @@ -/* - * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.nodes.java; - -import com.oracle.max.graal.graph.*; -import com.oracle.max.graal.nodes.*; -import com.oracle.max.graal.nodes.spi.*; -import com.sun.cri.bytecode.*; -import com.sun.cri.ci.*; -import com.sun.cri.ri.*; - -/** - * The {@code CheckCast} instruction represents a {@link Bytecodes#CHECKCAST}. - */ -public final class CheckCastNode extends TypeCheckNode implements Canonicalizable { - - /** - * Creates a new CheckCast instruction. - * - * @param targetClass the class being cast to - * @param object the instruction producing the object - * @param graph - */ - public CheckCastNode(ValueNode targetClassInstruction, ValueNode object, Graph graph) { - super(targetClassInstruction, object, CiKind.Object, graph); - } - - /** - * Gets the declared type of the result of this instruction. - * - * @return the declared type of the result - */ - @Override - public RiType declaredType() { - return targetClass(); - } - - /** - * Gets the exact type of the result of this instruction. - * - * @return the exact type of the result - */ - @Override - public RiType exactType() { - return targetClass().isResolved() ? targetClass().exactType() : null; - } - - @Override - public void accept(ValueVisitor v) { - v.visitCheckCast(this); - } - - @Override - public Node canonical(NotifyReProcess reProcess) { - if (object().exactType() != null) { - return object(); - } - CiConstant constant = object().asConstant(); - if (constant != null) { - assert constant.kind == CiKind.Object; - if (constant.isNull()) { - return object(); - } else { - // this should never happen - non-null constants are always expected to provide an exactType - assert false; - } - } - return this; - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/java/ExceptionObjectNode.java --- a/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/java/ExceptionObjectNode.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,47 +0,0 @@ -/* - * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.nodes.java; - -import com.oracle.max.graal.graph.*; -import com.oracle.max.graal.nodes.*; -import com.oracle.max.graal.nodes.spi.*; -import com.sun.cri.ci.*; - -/** - * The {@code ExceptionObject} instruction represents the incoming exception object to an exception handler. - */ -public final class ExceptionObjectNode extends StateSplit { - - /** - * Constructs a new ExceptionObject instruction. - * @param graph - */ - public ExceptionObjectNode(Graph graph) { - super(CiKind.Object, graph); - } - - @Override - public void accept(ValueVisitor v) { - v.visitExceptionObject(this); - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/java/InstanceOfNode.java --- a/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/java/InstanceOfNode.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,67 +0,0 @@ -/* - * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.nodes.java; - -import com.oracle.max.graal.graph.*; -import com.oracle.max.graal.nodes.*; -import com.oracle.max.graal.nodes.spi.*; -import com.sun.cri.ci.*; - -/** - * The {@code InstanceOf} instruction represents an instanceof test. - */ -public final class InstanceOfNode extends TypeCheckNode implements Canonicalizable { - - /** - * Constructs a new InstanceOf instruction. - * - * @param targetClass the target class of the instanceof check - * @param object the instruction producing the object input to this instruction - * @param graph - */ - public InstanceOfNode(ConstantNode targetClassInstruction, ValueNode object, boolean nullIsTrue, Graph graph) { - super(targetClassInstruction, object, CiKind.Illegal, graph); - } - - @Override - public void accept(ValueVisitor v) { - } - - @Override - public Node canonical(NotifyReProcess reProcess) { - if (object().exactType() != null) { - return ConstantNode.forBoolean(object().exactType().isSubtypeOf(targetClass()), graph()); - } - CiConstant constant = object().asConstant(); - if (constant != null) { - assert constant.kind == CiKind.Object; - if (constant.isNull()) { - return ConstantNode.forBoolean(false, graph()); - } else { - // this should never happen - non-null constants are always expected to provide an exactType - assert false; - } - } - return this; - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/java/IsTypeNode.java --- a/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/java/IsTypeNode.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,100 +0,0 @@ -/* - * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.nodes.java; - -import java.util.*; - -import com.oracle.max.graal.graph.*; -import com.oracle.max.graal.nodes.*; -import com.oracle.max.graal.nodes.spi.*; -import com.sun.cri.ci.*; -import com.sun.cri.ri.*; - -/** - * The {@code TypeCheck} class represents an explicit type check instruction. - */ -public final class IsTypeNode extends BooleanNode implements Canonicalizable { - - @Input private ValueNode object; - - public ValueNode object() { - return object; - } - - public void setObject(ValueNode x) { - updateUsages(object, x); - object = x; - } - - private final RiType type; - - /** - * Constructs a new IsType instruction. - * - * @param object the instruction producing the object to check against the given type - * @param graph - */ - public IsTypeNode(ValueNode object, RiType type, Graph graph) { - super(CiKind.Object, graph); - assert type.isResolved(); - assert object == null || object.kind == CiKind.Object; - this.type = type; - setObject(object); - } - - public RiType type() { - return type; - } - - @Override - public void accept(ValueVisitor v) { - // Nothing to do. - } - - @Override - public RiType declaredType() { - // type check does not alter the type of the object - return object().declaredType(); - } - - @Override - public RiType exactType() { - return type; - } - - @Override - public Map getDebugProperties() { - Map properties = super.getDebugProperties(); - properties.put("type", type); - return properties; - } - - @Override - public Node canonical(NotifyReProcess reProcess) { - if (object().exactType() != null) { - return ConstantNode.forBoolean(object().exactType() == type(), graph()); - } - // constants return the correct exactType, so they are handled by the code above - return this; - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/java/LoadFieldNode.java --- a/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/java/LoadFieldNode.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,109 +0,0 @@ -/* - * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.nodes.java; - -import com.oracle.max.graal.graph.*; -import com.oracle.max.graal.nodes.*; -import com.oracle.max.graal.nodes.spi.*; -import com.sun.cri.ci.*; -import com.sun.cri.ri.*; - -/** - * The {@code LoadField} instruction represents a read of a static or instance field. - */ -public final class LoadFieldNode extends AccessFieldNode implements Canonicalizable { - - /** - * Creates a new LoadField instance. - * - * @param object the receiver object - * @param field the compiler interface field - * @param isStatic indicates if the field is static - * @param stateAfter the state after the field access - * @param graph - * @param isLoaded indicates if the class is loaded - */ - public LoadFieldNode(ValueNode object, RiField field, Graph graph) { - super(field.kind().stackKind(), object, field, graph); - } - - /** - * Gets the declared type of the field being accessed. - * - * @return the declared type of the field being accessed. - */ - @Override - public RiType declaredType() { - return field().type(); - } - - /** - * Gets the exact type of the field being accessed. If the field type is a primitive array or an instance class and - * the class is loaded and final, then the exact type is the same as the declared type. Otherwise it is {@code null} - * - * @return the exact type of the field if known; {@code null} otherwise - */ - @Override - public RiType exactType() { - RiType declared = declaredType(); - return declared != null && declared.isResolved() ? declared.exactType() : null; - } - - @Override - public void accept(ValueVisitor v) { - v.visitLoadField(this); - } - - @Override - public boolean needsStateAfter() { - return false; - } - - /** - * Gets a constant value to which this load can be reduced. - * - * @return {@code null} if this load cannot be reduced to a constant - */ - private CiConstant constantValue() { - if (isStatic()) { - return field.constantValue(null); - } else if (object().isConstant()) { - return field.constantValue(object().asConstant()); - } - return null; - } - - @Override - public Node canonical(NotifyReProcess reProcess) { - CiConstant constant = null; - if (isStatic()) { - constant = field().constantValue(null); - } else if (object().isConstant()) { - constant = field().constantValue(object().asConstant()); - } - if (constant != null) { - return new ConstantNode(constant, graph()); - } - return this; - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/java/LoadIndexedNode.java --- a/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/java/LoadIndexedNode.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,89 +0,0 @@ -/* - * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.nodes.java; - -import com.oracle.max.graal.graph.*; -import com.oracle.max.graal.nodes.*; -import com.oracle.max.graal.nodes.spi.*; -import com.sun.cri.ci.*; -import com.sun.cri.ri.*; - -/** - * The {@code LoadIndexed} instruction represents a read from an element of an array. - */ -public final class LoadIndexedNode extends AccessIndexedNode { - - /** - * Creates a new LoadIndexed instruction. - * @param array the instruction producing the array - * @param index the instruction producing the index - * @param length the instruction producing the length - * @param elementKind the element type - * @param graph - */ - public LoadIndexedNode(ValueNode array, ValueNode index, ValueNode length, CiKind elementKind, Graph graph) { - super(elementKind.stackKind(), array, index, length, elementKind, graph); - } - - /** - * Gets the declared type of this instruction's result. - * @return the declared type - */ - @Override - public RiType declaredType() { - RiType arrayType = array().declaredType(); - if (arrayType == null) { - return null; - } - return arrayType.componentType(); - } - - /** - * Gets the exact type of this instruction's result. - * @return the exact type - */ - @Override - public RiType exactType() { - RiType declared = declaredType(); - return declared != null && declared.isResolved() ? declared.exactType() : null; - } - - @Override - public void accept(ValueVisitor v) { - v.visitLoadIndexed(this); - } - - @Override - public boolean needsStateAfter() { - return false; - } - - @SuppressWarnings("unchecked") - @Override - public T lookup(Class clazz) { - if (clazz == LoweringOp.class) { - return (T) DELEGATE_TO_RUNTIME; - } - return super.lookup(clazz); - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/java/MathIntrinsicNode.java --- a/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/java/MathIntrinsicNode.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,62 +0,0 @@ -/* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.nodes.java; - -import com.oracle.max.graal.graph.*; -import com.oracle.max.graal.nodes.*; -import com.oracle.max.graal.nodes.calc.*; -import com.oracle.max.graal.nodes.spi.*; - -public class MathIntrinsicNode extends FloatingNode { - - @Input private ValueNode x; - @Data private final Operation operation; - - public enum Operation { - ABS, SQRT, - } - - public ValueNode x() { - return x; - } - - private void setX(ValueNode x) { - updateUsages(this.x, x); - this.x = x; - } - - public Operation operation() { - return operation; - } - - public MathIntrinsicNode(ValueNode x, Operation op, Graph graph) { - super(x.kind, graph); - setX(x); - this.operation = op; - } - - @Override - public void accept(ValueVisitor v) { - v.visitMathIntrinsic(this); - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/java/MonitorAddressNode.java --- a/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/java/MonitorAddressNode.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,63 +0,0 @@ -/* - * Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.nodes.java; - -import java.util.*; - -import com.oracle.max.graal.graph.*; -import com.oracle.max.graal.nodes.*; -import com.oracle.max.graal.nodes.spi.*; -import com.sun.cri.ci.*; - -/** - * Instruction that is used to refer to the address of an on-stack monitor. - */ -public final class MonitorAddressNode extends ValueNode { - - private int monitorIndex; - - public MonitorAddressNode(int monitorIndex, Graph graph) { - super(CiKind.Word, graph); - this.monitorIndex = monitorIndex; - } - - @Override - public void accept(ValueVisitor v) { - v.visitMonitorAddress(this); - } - - public int monitorIndex() { - return monitorIndex; - } - - public void setMonitorIndex(int monitorIndex) { - this.monitorIndex = monitorIndex; - } - - @Override - public Map getDebugProperties() { - Map properties = super.getDebugProperties(); - properties.put("monitorIndex", monitorIndex); - return properties; - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/java/MonitorEnterNode.java --- a/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/java/MonitorEnterNode.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,50 +0,0 @@ -/* - * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.nodes.java; - -import com.oracle.max.graal.graph.*; -import com.oracle.max.graal.nodes.*; -import com.oracle.max.graal.nodes.spi.*; - -/** - * The {@code MonitorEnter} instruction represents the acquisition of a monitor. - */ -public final class MonitorEnterNode extends AccessMonitorNode { - - /** - * Creates a new MonitorEnter instruction. - * - * @param object the instruction producing the object - * @param lockAddress the address of the on-stack lock object or {@code null} if the runtime does not place locks on the stack - * @param lockNumber the number of the lock - * @param graph - */ - public MonitorEnterNode(ValueNode object, ValueNode lockAddress, int lockNumber, Graph graph) { - super(object, lockAddress, lockNumber, graph); - } - - @Override - public void accept(ValueVisitor v) { - v.visitMonitorEnter(this); - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/java/MonitorExitNode.java --- a/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/java/MonitorExitNode.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,50 +0,0 @@ -/* - * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.nodes.java; - -import com.oracle.max.graal.graph.*; -import com.oracle.max.graal.nodes.*; -import com.oracle.max.graal.nodes.spi.*; - -/** - * The {@code MonitorExit} instruction represents a monitor release. - */ -public final class MonitorExitNode extends AccessMonitorNode { - - /** - * Creates a new MonitorExit instruction. - * - * @param object the instruction produces the object value - * @param lockAddress the address of the on-stack lock object or {@code null} if the runtime does not place locks on the stack - * @param lockNumber the number of the lock - * @param graph - */ - public MonitorExitNode(ValueNode object, ValueNode lockAddress, int lockNumber, Graph graph) { - super(object, lockAddress, lockNumber, graph); - } - - @Override - public void accept(ValueVisitor v) { - v.visitMonitorExit(this); - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/java/NewArrayNode.java --- a/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/java/NewArrayNode.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,180 +0,0 @@ -/* - * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.nodes.java; - -import java.util.*; - -import com.oracle.max.graal.graph.*; -import com.oracle.max.graal.nodes.*; -import com.oracle.max.graal.nodes.spi.*; -import com.oracle.max.graal.nodes.virtual.*; -import com.sun.cri.ci.*; - -/** - * The {@code NewArray} class is the base of all instructions that allocate arrays. - */ -public abstract class NewArrayNode extends FixedWithNextNode { - - @Input private ValueNode length; - - public static final int MaximumEscapeAnalysisArrayLength = 32; - - public ValueNode length() { - return length; - } - - public void setLength(ValueNode x) { - updateUsages(this.length, x); - this.length = x; - } - - /** - * Constructs a new NewArray instruction. - * @param length the instruction that produces the length for this allocation - * @param graph - */ - protected NewArrayNode(ValueNode length, Graph graph) { - super(CiKind.Object, graph); - setLength(length); - } - - /** - * The list of instructions which produce input for this instruction. - */ - public ValueNode dimension(int index) { - assert index == 0; - return length(); - } - - /** - * The rank of the array allocated by this instruction, i.e. how many array dimensions. - */ - public int dimensionCount() { - return 1; - } - - public abstract CiKind elementKind(); - - @Override - public Map getDebugProperties() { - Map properties = super.getDebugProperties(); - properties.put("exactType", exactType()); - return properties; - } - - @SuppressWarnings("unchecked") - @Override - public T lookup(Class clazz) { - if (clazz == EscapeOp.class) { - return (T) ESCAPE; - } - return super.lookup(clazz); - } - - private static final EscapeOp ESCAPE = new EscapeOp() { - - @Override - public boolean canAnalyze(Node node) { - NewArrayNode x = (NewArrayNode) node; - CiConstant length = x.dimension(0).asConstant(); - return length != null && length.asInt() >= 0 && length.asInt() < MaximumEscapeAnalysisArrayLength; - } - - @Override - public boolean escape(Node node, Node usage) { - if (usage instanceof LoadIndexedNode) { - LoadIndexedNode x = (LoadIndexedNode) usage; - assert x.array() == node; - CiConstant index = x.index().asConstant(); - CiConstant length = ((NewArrayNode) node).dimension(0).asConstant(); - if (index == null || length == null || index.asInt() < 0 || index.asInt() >= length.asInt()) { - return true; - } - return false; - } else if (usage instanceof StoreFieldNode) { - StoreFieldNode x = (StoreFieldNode) usage; - assert x.value() == node; - return true; - } else if (usage instanceof StoreIndexedNode) { - StoreIndexedNode x = (StoreIndexedNode) usage; - CiConstant index = x.index().asConstant(); - CiConstant length = ((NewArrayNode) node).dimension(0).asConstant(); - if (index == null || length == null || index.asInt() < 0 || index.asInt() >= length.asInt()) { - return true; - } - return x.value() == node && x.array() != node; - } else if (usage instanceof ArrayLengthNode) { - ArrayLengthNode x = (ArrayLengthNode) usage; - assert x.array() == node; - return false; - } else if (usage instanceof VirtualObjectFieldNode) { - return false; - } else { - return super.escape(node, usage); - } - } - - @Override - public EscapeField[] fields(Node node) { - NewArrayNode x = (NewArrayNode) node; - int length = x.dimension(0).asConstant().asInt(); - EscapeField[] fields = new EscapeField[length]; - for (int i = 0; i < length; i++) { - Integer representation = i; - fields[i] = new EscapeField("[" + i + "]", representation, ((NewArrayNode) node).elementKind()); - } - return fields; - } - - @Override - public void beforeUpdate(Node node, Node usage) { - if (usage instanceof ArrayLengthNode) { - ArrayLengthNode x = (ArrayLengthNode) usage; - x.replaceAndDelete(((NewArrayNode) node).dimension(0)); - } else { - super.beforeUpdate(node, usage); - } - } - - @Override - public int updateState(Node node, Node current, Map fieldIndex, ValueNode[] fieldState) { - if (current instanceof AccessIndexedNode) { - AccessIndexedNode x = (AccessIndexedNode) current; - if (x.array() == node) { - int index = ((AccessIndexedNode) current).index().asConstant().asInt(); - if (current instanceof LoadIndexedNode) { - x.replaceAtUsages(fieldState[index]); - assert x.usages().size() == 0; - x.replaceAndDelete(x.next()); - } else if (current instanceof StoreIndexedNode) { - fieldState[index] = ((StoreIndexedNode) x).value(); - assert x.usages().size() == 0; - x.replaceAndDelete(x.next()); - return index; - } - } - } - return -1; - } - }; -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/java/NewInstanceNode.java --- a/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/java/NewInstanceNode.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,171 +0,0 @@ -/* - * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.nodes.java; - -import java.util.*; - -import com.oracle.max.graal.graph.*; -import com.oracle.max.graal.nodes.*; -import com.oracle.max.graal.nodes.spi.*; -import com.oracle.max.graal.nodes.virtual.*; -import com.sun.cri.ci.*; -import com.sun.cri.ri.*; - -/** - * The {@code NewInstance} instruction represents the allocation of an instance class object. - */ -public final class NewInstanceNode extends FixedWithNextNode { - - final RiType instanceClass; - public final int cpi; - public final RiConstantPool constantPool; - - /** - * Constructs a NewInstance instruction. - * @param type the class being allocated - * @param cpi the constant pool index - * @param graph - */ - public NewInstanceNode(RiType type, int cpi, RiConstantPool constantPool, Graph graph) { - super(CiKind.Object, graph); - this.instanceClass = type; - this.cpi = cpi; - this.constantPool = constantPool; - } - - /** - * Gets the instance class being allocated by this instruction. - * @return the instance class allocated - */ - public RiType instanceClass() { - return instanceClass; - } - - /** - * Gets the exact type produced by this instruction. For allocations of instance classes, this is - * always the class allocated. - * @return the exact type produced by this instruction - */ - @Override - public RiType exactType() { - return instanceClass; - } - - @Override - public void accept(ValueVisitor v) { - v.visitNewInstance(this); - } - - @Override - public Map getDebugProperties() { - Map properties = super.getDebugProperties(); - properties.put("instanceClass", instanceClass); - properties.put("cpi", cpi); - return properties; - } - - @SuppressWarnings("unchecked") - @Override - public T lookup(Class clazz) { - if (clazz == EscapeOp.class) { - return (T) ESCAPE; - } - return super.lookup(clazz); - } - - private static final EscapeOp ESCAPE = new EscapeOp() { - - @Override - public boolean canAnalyze(Node node) { - return ((NewInstanceNode) node).instanceClass().isResolved(); - } - - @Override - public boolean escape(Node node, Node usage) { - if (usage instanceof LoadFieldNode) { - LoadFieldNode x = (LoadFieldNode) usage; - assert x.object() == node; - return x.field().isResolved() == false; - } else if (usage instanceof StoreFieldNode) { - StoreFieldNode x = (StoreFieldNode) usage; - return x.value() == node && x.object() != node; - } else if (usage instanceof StoreIndexedNode) { - StoreIndexedNode x = (StoreIndexedNode) usage; - assert x.value() == node; - return true; - } else if (usage instanceof VirtualObjectFieldNode) { - return false; - } else if (usage instanceof RegisterFinalizerNode) { - RegisterFinalizerNode x = (RegisterFinalizerNode) usage; - assert x.object() == node; - return false; - } else { - return super.escape(node, usage); - } - } - - @Override - public EscapeField[] fields(Node node) { - NewInstanceNode x = (NewInstanceNode) node; - RiField[] riFields = x.instanceClass().fields(); - EscapeField[] fields = new EscapeField[riFields.length]; - for (int i = 0; i < riFields.length; i++) { - RiField field = riFields[i]; - fields[i] = new EscapeField(field.name(), field, field.kind().stackKind()); - } - return fields; - } - - @Override - public void beforeUpdate(Node node, Node usage) { - if (usage instanceof RegisterFinalizerNode) { - RegisterFinalizerNode x = (RegisterFinalizerNode) usage; - x.replaceAndDelete(x.next()); - } else { - super.beforeUpdate(node, usage); - } - } - - @Override - public int updateState(Node node, Node current, Map fieldIndex, ValueNode[] fieldState) { - if (current instanceof AccessFieldNode) { - AccessFieldNode x = (AccessFieldNode) current; - if (x.object() == node) { - int field = fieldIndex.get(((AccessFieldNode) current).field()); - if (current instanceof LoadFieldNode) { - assert fieldState[field] != null : field + ", " + ((AccessFieldNode) current).field(); - x.replaceAtUsages(fieldState[field]); - assert x.usages().size() == 0; - x.replaceAndDelete(x.next()); - } else if (current instanceof StoreFieldNode) { - fieldState[field] = ((StoreFieldNode) x).value(); - assert x.usages().size() == 0; - x.replaceAndDelete(x.next()); - return field; - } - } - } - return -1; - } - }; -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/java/NewMultiArrayNode.java --- a/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/java/NewMultiArrayNode.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,107 +0,0 @@ -/* - * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.nodes.java; - -import com.oracle.max.graal.graph.*; -import com.oracle.max.graal.nodes.*; -import com.oracle.max.graal.nodes.spi.*; -import com.sun.cri.ci.*; -import com.sun.cri.ri.*; - -/** - * The {@code NewMultiArray} instruction represents an allocation of a multi-dimensional object - * array. - */ -public final class NewMultiArrayNode extends NewArrayNode { - - @Input private final NodeInputList dimensions; - - @Override - public ValueNode dimension(int index) { - return dimensions.get(index); - } - - public void setDimension(int index, ValueNode x) { - dimensions.set(index, x); - } - - /** - * The rank of the array allocated by this instruction, i.e. how many array dimensions. - */ - @Override - public int dimensionCount() { - return dimensions.size(); - } - - public final RiType elementType; - public final int cpi; - public final RiConstantPool constantPool; - - /** - * Constructs a new NewMultiArray instruction. - * @param elementType the element type of the array - * @param dimensions the instructions which produce the dimensions for this array - * @param cpi the constant pool index for resolution - * @param riConstantPool the constant pool for resolution - * @param graph - */ - public NewMultiArrayNode(RiType elementType, ValueNode[] dimensions, int cpi, RiConstantPool riConstantPool, Graph graph) { - super(null, graph); - this.constantPool = riConstantPool; - this.elementType = elementType; - this.cpi = cpi; - - this.dimensions = new NodeInputList(this, dimensions.length); - for (int i = 0; i < dimensions.length; i++) { - setDimension(i, dimensions[i]); - } - } - - @Override - public void accept(ValueVisitor v) { - v.visitNewMultiArray(this); - } - - /** - * Gets the element type of the array. - * @return the element type of the array - */ - public RiType elementType() { - return elementType; - } - - @Override - public CiKind elementKind() { - return elementType.kind(); - } - - @Override - public RiType exactType() { - return elementType.arrayOf(); - } - - @Override - public RiType declaredType() { - return exactType(); - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/java/NewObjectArrayNode.java --- a/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/java/NewObjectArrayNode.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,76 +0,0 @@ -/* - * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.nodes.java; - -import com.oracle.max.graal.graph.*; -import com.oracle.max.graal.nodes.*; -import com.oracle.max.graal.nodes.spi.*; -import com.sun.cri.ci.*; -import com.sun.cri.ri.*; - -/** - * The {@code NewObjectArray} instruction represents an allocation of an object array. - */ -public final class NewObjectArrayNode extends NewArrayNode { - - final RiType elementClass; - - /** - * Constructs a new NewObjectArray instruction. - * @param elementClass the class of elements in this array - * @param length the instruction producing the length of the array - * @param graph - */ - public NewObjectArrayNode(RiType elementClass, ValueNode length, Graph graph) { - super(length, graph); - this.elementClass = elementClass; - } - - /** - * Gets the type of the elements of the array. - * @return the element type of the array - */ - public RiType elementType() { - return elementClass; - } - - @Override - public CiKind elementKind() { - return elementClass.kind(); - } - - @Override - public RiType exactType() { - return elementClass.arrayOf(); - } - - @Override - public RiType declaredType() { - return exactType(); - } - - @Override - public void accept(ValueVisitor v) { - v.visitNewObjectArray(this); - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/java/NewTypeArrayNode.java --- a/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/java/NewTypeArrayNode.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,62 +0,0 @@ -/* - * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.nodes.java; - -import com.oracle.max.graal.graph.*; -import com.oracle.max.graal.nodes.*; -import com.oracle.max.graal.nodes.spi.*; -import com.sun.cri.ci.*; -import com.sun.cri.ri.*; - -/** - * The {@code NewTypeArray} class definition. - */ -public final class NewTypeArrayNode extends NewArrayNode { - - final RiType elementType; - - public NewTypeArrayNode(ValueNode length, RiType elementType, Graph graph) { - super(length, graph); - this.elementType = elementType; - } - - @Override - public CiKind elementKind() { - return elementType.kind(); - } - - @Override - public RiType declaredType() { - return elementType.arrayOf(); - } - - @Override - public RiType exactType() { - return elementType.arrayOf(); - } - - @Override - public void accept(ValueVisitor v) { - v.visitNewTypeArray(this); - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/java/RegisterFinalizerNode.java --- a/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/java/RegisterFinalizerNode.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,84 +0,0 @@ -/* - * Copyright (c) 2011, 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.nodes.java; - -import com.oracle.max.graal.graph.*; -import com.oracle.max.graal.nodes.*; -import com.oracle.max.graal.nodes.spi.*; -import com.sun.cri.ci.*; -import com.sun.cri.ri.*; - -/** - * This instruction is used to perform the finalizer registration at the end of the java.lang.Object constructor. - */ -public final class RegisterFinalizerNode extends StateSplit implements Canonicalizable { - - @Input private ValueNode object; - - public ValueNode object() { - return object; - } - - public void setObject(ValueNode x) { - updateUsages(object, x); - object = x; - } - - public RegisterFinalizerNode(ValueNode object, Graph graph) { - super(CiKind.Void, graph); - setObject(object); - } - - @Override - public void accept(ValueVisitor v) { - v.visitRegisterFinalizer(this); - } - - @Override - public Node canonical(NotifyReProcess reProcess) { - RiType declaredType = object.declaredType(); - RiType exactType = object.exactType(); - if (exactType == null && declaredType != null) { - exactType = declaredType.exactType(); - } - - boolean needsCheck = true; - if (exactType != null) { - // we have an exact type - needsCheck = exactType.hasFinalizer(); - } else { - // if either the declared type of receiver or the holder can be assumed to have no finalizers - if (declaredType != null && !declaredType.hasFinalizableSubclass()) { - if (((CompilerGraph) graph()).assumptions().recordNoFinalizableSubclassAssumption(declaredType)) { - needsCheck = false; - } - } - } - - if (!needsCheck) { - return next(); - } - - return this; - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/java/StoreFieldNode.java --- a/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/java/StoreFieldNode.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,73 +0,0 @@ -/* - * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.nodes.java; - -import com.oracle.max.graal.graph.*; -import com.oracle.max.graal.nodes.*; -import com.oracle.max.graal.nodes.spi.*; -import com.sun.cri.ci.*; -import com.sun.cri.ri.*; - -/** - * The {@code StoreField} instruction represents a write to a static or instance field. - */ -public final class StoreFieldNode extends AccessFieldNode { - - @Input private ValueNode value; - - public ValueNode value() { - return value; - } - - public void setValue(ValueNode x) { - updateUsages(value, x); - value = x; - } - - /** - * Creates a new LoadField instance. - * @param object the receiver object - * @param field the compiler interface field - * @param value the instruction representing the value to store to the field - * @param stateAfter the state after the field access - * @param graph - */ - public StoreFieldNode(ValueNode object, RiField field, ValueNode value, Graph graph) { - super(CiKind.Void, object, field, graph); - setValue(value); - } - - @Override - public void accept(ValueVisitor v) { - v.visitStoreField(this); - } - - @SuppressWarnings("unchecked") - @Override - public T lookup(java.lang.Class clazz) { - if (clazz == LoweringOp.class) { - return (T) DELEGATE_TO_RUNTIME; - } - return super.lookup(clazz); - }; -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/java/StoreIndexedNode.java --- a/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/java/StoreIndexedNode.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,74 +0,0 @@ -/* - * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.nodes.java; - -import com.oracle.max.graal.graph.*; -import com.oracle.max.graal.nodes.*; -import com.oracle.max.graal.nodes.spi.*; -import com.sun.cri.ci.*; - -/** - * The {@code StoreIndexed} instruction represents a write to an array element. - */ -public final class StoreIndexedNode extends AccessIndexedNode { - - @Input private ValueNode value; - - public ValueNode value() { - return value; - } - - public void setValue(ValueNode x) { - updateUsages(value, x); - value = x; - } - - /** - * Creates a new StoreIndexed instruction. - * @param array the instruction producing the array - * @param index the instruction producing the index - * @param length the instruction producing the length - * @param elementKind the element type - * @param value the value to store into the array - * @param stateAfter the state after executing this instruction - * @param graph - */ - public StoreIndexedNode(ValueNode array, ValueNode index, ValueNode length, CiKind elementKind, ValueNode value, Graph graph) { - super(CiKind.Void, array, index, length, elementKind, graph); - setValue(value); - } - - @Override - public void accept(ValueVisitor v) { - v.visitStoreIndexed(this); - } - - @SuppressWarnings("unchecked") - @Override - public T lookup(Class clazz) { - if (clazz == LoweringOp.class) { - return (T) DELEGATE_TO_RUNTIME; - } - return super.lookup(clazz); - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/java/TypeCheckNode.java --- a/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/java/TypeCheckNode.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,75 +0,0 @@ -/* - * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.nodes.java; - -import com.oracle.max.graal.graph.*; -import com.oracle.max.graal.nodes.*; -import com.sun.cri.ci.*; -import com.sun.cri.ri.*; - -/** - * The {@code TypeCheck} instruction is the base class of casts and instanceof tests. - */ -public abstract class TypeCheckNode extends BooleanNode { - @Input private ValueNode object; - @Input private ValueNode targetClassInstruction; - - public ValueNode object() { - return object; - } - - public void setObject(ValueNode x) { - updateUsages(object, x); - object = x; - } - - public ValueNode targetClassInstruction() { - return targetClassInstruction; - } - - public void setTargetClassInstruction(ValueNode x) { - updateUsages(targetClassInstruction, x); - targetClassInstruction = x; - } - - /** - * Gets the target class, i.e. the class being cast to, or the class being tested against. - * @return the target class - */ - public RiType targetClass() { - return targetClassInstruction() instanceof ConstantNode ? (RiType) targetClassInstruction().asConstant().asObject() : null; - } - - /** - * Creates a new TypeCheck instruction. - * @param targetClass the class which is being casted to or checked against - * @param object the instruction which produces the object - * @param kind the result type of this instruction - * @param graph - */ - public TypeCheckNode(ValueNode targetClassInstruction, ValueNode object, CiKind kind, Graph graph) { - super(kind, graph); - setObject(object); - setTargetClassInstruction(targetClassInstruction); - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/loop/BasicInductionVariableNode.java --- a/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/loop/BasicInductionVariableNode.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,125 +0,0 @@ -/* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.nodes.loop; - -import com.oracle.max.graal.graph.*; -import com.oracle.max.graal.nodes.*; -import com.oracle.max.graal.nodes.PhiNode.PhiType; -import com.oracle.max.graal.nodes.calc.*; -import com.oracle.max.graal.nodes.spi.*; -import com.sun.cri.ci.*; - - -/** - * LinearInductionVariable that is computed in the loops thanks to Phi(init, this + stride). - * This will keep at least one register busy in the whole loop body - */ -public class BasicInductionVariableNode extends LinearInductionVariableNode implements Canonicalizable{ - public static final BIVLoweringOp LOWERING = new BIVLoweringOp(); - @Input private LoopCounterNode loopCounter; - - public BasicInductionVariableNode(CiKind kind, ValueNode init, ValueNode stride, LoopCounterNode counter, Graph graph) { - super(kind, init, stride, graph); - setLoopCounter(counter); - } - - public LoopCounterNode loopCounter() { - return loopCounter; - } - - public void setLoopCounter(LoopCounterNode loopCounter) { - updateUsages(this.loopCounter, loopCounter); - this.loopCounter = loopCounter; - } - - public ValueNode init() { - return a(); - } - - public void setInit(ValueNode init) { - setA(init); - } - - public ValueNode stride() { - return b(); - } - - public void setStride(ValueNode stride) { - setB(stride); - } - - @Override - public LoopBeginNode loopBegin() { - return loopCounter().loopBegin(); - } - - @Override - public void peelOneIteration() { - this.setInit(IntegerArithmeticNode.add(init(), stride())); - } - - /** - * Will lessen the register pressure but augment the code complexity with a multiplication. - * @return the new DerivedInductionVariable - */ - public DerivedInductionVariableNode toDerivedInductionVariable() { - DerivedInductionVariableNode newDIV = new DerivedInductionVariableNode(kind, init(), stride(), loopCounter(), graph()); - this.replaceAndDelete(newDIV); - return newDIV; - } - - @Override - public Node canonical(NotifyReProcess reProcess) { - if (this.init().isConstant() && this.init().asConstant().asLong() == 0 - && this.stride().isConstant() && this.stride().asConstant().asLong() == 1) { - return this.loopCounter(); - } - return this; - } - - @SuppressWarnings("unchecked") - @Override - public T lookup(Class clazz) { - if (clazz == LoweringOp.class) { - return (T) LOWERING; - } - return super.lookup(clazz); - } - - public static class BIVLoweringOp implements LoweringOp { - @Override - public void lower(Node n, CiLoweringTool tool) { - BasicInductionVariableNode biv = (BasicInductionVariableNode) n; - PhiNode phi = this.ivToPhi(biv.loopBegin(), biv.init(), biv.stride(), biv.kind); - biv.replaceAtNonIVUsages(phi); - } - - public PhiNode ivToPhi(LoopBeginNode loopBegin, ValueNode init, ValueNode stride, CiKind kind) { - PhiNode phi = new PhiNode(kind, loopBegin, PhiType.Value, loopBegin.graph()); - IntegerArithmeticNode after = IntegerArithmeticNode.add(phi, stride); - phi.addInput(init); - phi.addInput(after); - return phi; - } - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/loop/DerivedInductionVariableNode.java --- a/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/loop/DerivedInductionVariableNode.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,125 +0,0 @@ -/* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.nodes.loop; - -import com.oracle.max.graal.graph.*; -import com.oracle.max.graal.nodes.*; -import com.oracle.max.graal.nodes.calc.*; -import com.oracle.max.graal.nodes.spi.*; -import com.sun.cri.ci.*; - - -/** - * LinearInductionVariable that is computed in the loops with offset + scale * base. - * This is computed in the loop only when necessary, puts less pressure on registers. - */ -public class DerivedInductionVariableNode extends LinearInductionVariableNode { - @Input private InductionVariableNode base; - - public DerivedInductionVariableNode(CiKind kind, ValueNode offset, ValueNode scale, InductionVariableNode base, Graph graph) { - super(kind, offset, scale, graph); - setBase(base); - } - - public InductionVariableNode base() { - return base; - } - - public void setBase(InductionVariableNode base) { - updateUsages(this.base, base); - this.base = base; - } - - public ValueNode offset() { - return a(); - } - - public void setOffset(ValueNode offset) { - setA(offset); - } - - public ValueNode scale() { - return b(); - } - - public void setScale(ValueNode scale) { - setB(scale); - } - - @Override - public LoopBeginNode loopBegin() { - return base().loopBegin(); - } - - @Override - public void peelOneIteration() { - // nop - } - - /** - * This will apply strength reduction to this induction variable but will augment register pressure in the loop. - * @return the new BasicInductionVariable - */ - public BasicInductionVariableNode toBasicInductionVariable() { - InductionVariableNode base = base(); - if (base instanceof DerivedInductionVariableNode) { - base = ((DerivedInductionVariableNode) base).toBasicInductionVariable(); - } - ValueNode init; - ValueNode stride; - LoopCounterNode counter; - if (base instanceof BasicInductionVariableNode) { - BasicInductionVariableNode basic = (BasicInductionVariableNode) base; - // let the canonicalizer do its job with this - init = IntegerArithmeticNode.add(offset(), IntegerArithmeticNode.mul(scale(), basic.init())); - stride = IntegerArithmeticNode.mul(scale(), basic.stride()); - counter = basic.loopCounter(); - } else { - assert base instanceof LoopCounterNode; - init = offset(); - stride = scale(); - counter = (LoopCounterNode) base; - } - BasicInductionVariableNode newBIV = new BasicInductionVariableNode(kind, init, stride, counter, graph()); - this.replaceAndDelete(newBIV); - return newBIV; - } - - @SuppressWarnings("unchecked") - @Override - public T lookup(Class clazz) { - if (clazz == LoweringOp.class) { - return (T) LOWERING; - } - return super.lookup(clazz); - } - - private static final LoweringOp LOWERING = new LoweringOp() { - @Override - public void lower(Node n, CiLoweringTool tool) { - DerivedInductionVariableNode div = (DerivedInductionVariableNode) n; - IntegerArithmeticNode computed = IntegerArithmeticNode.add(div.offset(), IntegerArithmeticNode.mul(div.scale(), div.base())); - div.replaceAtNonIVUsages(computed); - } - }; -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/loop/InductionVariableNode.java --- a/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/loop/InductionVariableNode.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,54 +0,0 @@ -/* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.nodes.loop; - -import com.oracle.max.graal.graph.*; -import com.oracle.max.graal.nodes.*; -import com.oracle.max.graal.nodes.calc.*; -import com.oracle.max.graal.nodes.spi.*; -import com.sun.cri.ci.*; - -public abstract class InductionVariableNode extends FloatingNode { - - public InductionVariableNode(CiKind kind, Graph graph) { - super(kind, graph); - assert kind.isInt() || kind.isLong(); - } - - public abstract LoopBeginNode loopBegin(); - - public abstract void peelOneIteration(); - - public void replaceAtNonIVUsages(Node other) { - for (Node usage : this.usages().snapshot()) { - if (!(usage instanceof InductionVariableNode)) { - usage.replaceFirstInput(this, other); - } - } - } - - @Override - public void accept(ValueVisitor v) { - // nop - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/loop/LinearInductionVariableNode.java --- a/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/loop/LinearInductionVariableNode.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,64 +0,0 @@ -/* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.nodes.loop; - -import com.oracle.max.graal.graph.*; -import com.oracle.max.graal.nodes.*; -import com.sun.cri.ci.*; - -/** - * InductionVariable of the form a+b*x. - */ -public abstract class LinearInductionVariableNode extends InductionVariableNode { - @Input private ValueNode a; - @Input private ValueNode b; - - public LinearInductionVariableNode(CiKind kind, ValueNode a, ValueNode b, Graph graph) { - super(kind, graph); - setA(a); - setB(b); - } - - protected ValueNode a() { - return a; - } - - protected ValueNode b() { - return b; - } - - protected void setA(ValueNode a) { - updateUsages(this.a, a); - this.a = a; - } - - - protected void setB(ValueNode b) { - updateUsages(this.b, b); - this.b = b; - } - - public boolean isLinearInductionVariableInput(Node n) { - return n == a() || n == b(); - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/loop/LoopCounterNode.java --- a/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/loop/LoopCounterNode.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,89 +0,0 @@ -/* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.nodes.loop; - -import com.oracle.max.graal.graph.*; -import com.oracle.max.graal.nodes.*; -import com.oracle.max.graal.nodes.spi.*; -import com.sun.cri.ci.*; - -/** - * Counts loop iterations from 0 to Niter. - * If used directly (and not just by BasicInductionVariables) computed with Phi(0, this + 1) - */ -public final class LoopCounterNode extends InductionVariableNode { - @Input private LoopBeginNode loopBegin; - - @Override - public LoopBeginNode loopBegin() { - return loopBegin; - } - - public void setLoopBegin(LoopBeginNode x) { - updateUsages(loopBegin, x); - loopBegin = x; - } - - public LoopCounterNode(CiKind kind, LoopBeginNode loop, Graph graph) { - super(kind, graph); - setLoopBegin(loop); - } - - @Override - public void peelOneIteration() { - BasicInductionVariableNode biv = null; - for (Node usage : usages()) { - if (!(usage instanceof InductionVariableNode && ((InductionVariableNode) usage).loopBegin() == this.loopBegin())) { - if (biv == null) { - biv = createBasicInductionVariable(); - biv.peelOneIteration(); - } - usage.inputs().replace(this, biv); - } - } - } - - @SuppressWarnings("unchecked") - @Override - public T lookup(Class clazz) { - if (clazz == LoweringOp.class) { - return (T) LOWERING; - } - return super.lookup(clazz); - } - - private BasicInductionVariableNode createBasicInductionVariable() { - Graph graph = graph(); - return new BasicInductionVariableNode(kind, ConstantNode.forInt(0, graph), ConstantNode.forInt(1, graph), this, graph); - } - - private static final LoweringOp LOWERING = new LoweringOp() { - @Override - public void lower(Node n, CiLoweringTool tool) { - LoopCounterNode loopCounter = (LoopCounterNode) n; - Graph graph = n.graph(); - PhiNode phi = BasicInductionVariableNode.LOWERING.ivToPhi(loopCounter.loopBegin(), ConstantNode.forInt(0, graph), ConstantNode.forInt(1, graph), loopCounter.kind); - loopCounter.replaceAtNonIVUsages(phi); - } - }; -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/spi/Canonicalizable.java --- a/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/spi/Canonicalizable.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,30 +0,0 @@ -/* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.nodes.spi; - -import com.oracle.max.graal.graph.*; - - -public interface Canonicalizable { - Node canonical(NotifyReProcess reProcess); -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/spi/EscapeField.java --- a/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/spi/EscapeField.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,55 +0,0 @@ -/* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.nodes.spi; - -import com.sun.cri.ci.*; - -public class EscapeField { - - private String name; - private Object representation; - private CiKind kind; - - public EscapeField(String name, Object representation, CiKind kind) { - this.name = name; - this.representation = representation; - this.kind = kind; - } - - public String name() { - return name; - } - - public Object representation() { - return representation; - } - - public CiKind kind() { - return kind; - } - - @Override - public String toString() { - return name(); - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/spi/EscapeOp.java --- a/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/spi/EscapeOp.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,79 +0,0 @@ -/* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.nodes.spi; - -import java.util.*; - -import com.oracle.max.graal.graph.*; -import com.oracle.max.graal.nodes.*; -import com.oracle.max.graal.nodes.calc.*; -import com.oracle.max.graal.nodes.java.*; - - -public abstract class EscapeOp implements Op { - - public abstract boolean canAnalyze(Node node); - - public boolean escape(Node node, Node usage) { - if (usage instanceof IsNonNullNode) { - IsNonNullNode x = (IsNonNullNode) usage; - assert x.object() == node; - return false; - } else if (usage instanceof IsTypeNode) { - IsTypeNode x = (IsTypeNode) usage; - assert x.object() == node; - return false; - } else if (usage instanceof FrameState) { - FrameState x = (FrameState) usage; - assert x.inputContains(node); - return true; - } else if (usage instanceof AccessMonitorNode) { - AccessMonitorNode x = (AccessMonitorNode) usage; - assert x.object() == node; - return false; - } else { - return true; - } - } - - public abstract EscapeField[] fields(Node node); - - public void beforeUpdate(Node node, Node usage) { - if (usage instanceof IsNonNullNode) { - IsNonNullNode x = (IsNonNullNode) usage; - // TODO (ls) not sure about this... - x.replaceAndDelete(ConstantNode.forBoolean(true, node.graph())); - } else if (usage instanceof IsTypeNode) { - IsTypeNode x = (IsTypeNode) usage; - assert x.type() == ((ValueNode) node).exactType(); - // TODO (ls) not sure about this... - x.replaceAndDelete(ConstantNode.forBoolean(true, node.graph())); - } else if (usage instanceof AccessMonitorNode) { - AccessMonitorNode x = (AccessMonitorNode) usage; - x.replaceAndDelete(x.next()); - } - } - - public abstract int updateState(Node node, Node current, Map fieldIndex, ValueNode[] fieldState); - -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/spi/ExceptionExit.java --- a/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/spi/ExceptionExit.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,30 +0,0 @@ -/* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.nodes.spi; - -import com.oracle.max.graal.nodes.*; - - -public interface ExceptionExit { - FixedNode exceptionEdge(); -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/spi/FrameStateAccess.java --- a/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/spi/FrameStateAccess.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,55 +0,0 @@ -/* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.nodes.spi; - -import com.oracle.max.graal.nodes.*; - -public interface FrameStateAccess { - - FrameState duplicate(int newBci); - - int localsSize(); - - int stackSize(); - - int locksSize(); - - boolean rethrowException(); - - ValueNode valueAt(int i); - - ValueNode localAt(int i); - - ValueNode lockAt(int i); - - ValueNode stackAt(int i); - - void setValueAt(int j, ValueNode v); - - void setRethrowException(boolean b); - - ValueNode outerFrameState(); - - FrameState duplicateWithException(int bci, ValueNode exceptionObject); - -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/spi/LIRGeneratorOp.java --- a/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/spi/LIRGeneratorOp.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,29 +0,0 @@ -/* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.nodes.spi; - -import com.oracle.max.graal.graph.*; - -public interface LIRGeneratorOp extends Op { - void generate(Node n, LIRGeneratorTool generator); -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/spi/LIRGeneratorTool.java --- a/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/spi/LIRGeneratorTool.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,42 +0,0 @@ -/* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.nodes.spi; - -import com.oracle.max.graal.nodes.*; -import com.oracle.max.graal.nodes.calc.*; -import com.sun.cri.ci.*; - -public abstract class LIRGeneratorTool extends ValueVisitor { - public abstract CiValue load(ValueNode value); - public abstract CiVariable createResultVariable(ValueNode conv); - public abstract CiValue forceToSpill(CiValue value, CiKind kind, boolean b); - public abstract void emitMove(CiValue tmp, CiValue reg); - public abstract void integerAdd(ValueNode result, ValueNode x, ValueNode y); - public abstract void deoptimizeOn(Condition of); - public abstract CiVariable newVariable(CiKind kind); - public abstract CiTarget target(); - public abstract void emitLea(CiAddress address, CiVariable dest); - public abstract CiValue makeOperand(ValueNode object); - public abstract void emitUnsignedShiftRight(CiValue value, CiValue count, CiValue dst, CiValue tmp); - public abstract void emitAdd(CiValue a, CiValue b, CiValue dest); -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/spi/LoweringOp.java --- a/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/spi/LoweringOp.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,31 +0,0 @@ -/* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.nodes.spi; - -import com.oracle.max.graal.graph.*; -import com.sun.cri.ci.*; - - -public interface LoweringOp extends Op { - void lower(Node n, CiLoweringTool tool); -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/spi/NotifyReProcess.java --- a/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/spi/NotifyReProcess.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,30 +0,0 @@ -/* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.nodes.spi; - -import com.oracle.max.graal.graph.*; - - -public interface NotifyReProcess { - void reProccess(Node n); -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/spi/ValueVisitor.java --- a/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/spi/ValueVisitor.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,81 +0,0 @@ -/* - * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.nodes.spi; - -import com.oracle.max.graal.nodes.*; -import com.oracle.max.graal.nodes.calc.*; -import com.oracle.max.graal.nodes.extended.*; -import com.oracle.max.graal.nodes.java.*; - -/** - * The {@link ValueVisitor} implements one half of the visitor - * pattern for {@linkplain ValueNode IR values}, allowing clients to implement functionality - * depending on the type of an value without doing type tests. - */ -public abstract class ValueVisitor { - // Checkstyle: stop - public abstract void visitArithmetic(ArithmeticNode i); - public abstract void visitArrayLength(ArrayLengthNode i); - public abstract void visitMerge(MergeNode i); - public abstract void visitCheckCast(CheckCastNode i); - public abstract void visitNormalizeCompare(NormalizeCompareNode i); - public abstract void visitConstant(ConstantNode i); - public abstract void visitConvert(ConvertNode i); - public abstract void visitConditional(ConditionalNode i); - public abstract void visitExceptionObject(ExceptionObjectNode i); - public abstract void visitEndNode(EndNode i); - public abstract void visitFrameState(FrameState i); - public abstract void visitAnchor(AnchorNode i); - public abstract void visitIf(IfNode i); - public abstract void visitInvoke(InvokeNode i); - public abstract void visitLoadField(LoadFieldNode i); - public abstract void visitLoadIndexed(LoadIndexedNode i); - public abstract void visitLocal(LocalNode i); - public abstract void visitLogic(LogicNode i); - public abstract void visitLookupSwitch(LookupSwitchNode i); - public abstract void visitMemoryRead(ReadNode i); - public abstract void visitMemoryWrite(WriteNode i); - public abstract void visitMonitorAddress(MonitorAddressNode monitorAddress); - public abstract void visitMonitorEnter(MonitorEnterNode i); - public abstract void visitMonitorExit(MonitorExitNode i); - public abstract void visitNegate(NegateNode i); - public abstract void visitNewInstance(NewInstanceNode i); - public abstract void visitNewMultiArray(NewMultiArrayNode i); - public abstract void visitNewObjectArray(NewObjectArrayNode i); - public abstract void visitNewTypeArray(NewTypeArrayNode i); - public abstract void visitFixedGuard(FixedGuardNode fixedGuard); - public abstract void visitPhi(PhiNode i); - public abstract void visitRegisterFinalizer(RegisterFinalizerNode i); - public abstract void visitReturn(ReturnNode i); - public abstract void visitShift(ShiftNode i); - public abstract void visitStoreField(StoreFieldNode i); - public abstract void visitStoreIndexed(StoreIndexedNode i); - public abstract void visitTableSwitch(TableSwitchNode i); - public abstract void visitDeoptimize(DeoptimizeNode deoptimize); - public abstract void visitUnwind(UnwindNode unwind); - public abstract void visitLoopBegin(LoopBeginNode loopBegin); - public abstract void visitLoopEnd(LoopEndNode loopEnd); - public abstract void visitValueAnchor(ValueAnchorNode valueAnchor); - public abstract void visitGuardNode(GuardNode guardNode); - public abstract void visitMathIntrinsic(MathIntrinsicNode node); -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/virtual/VirtualObjectFieldNode.java --- a/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/virtual/VirtualObjectFieldNode.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,102 +0,0 @@ -/* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.nodes.virtual; - -import java.util.*; - -import com.oracle.max.graal.graph.*; -import com.oracle.max.graal.nodes.*; -import com.oracle.max.graal.nodes.calc.*; -import com.oracle.max.graal.nodes.spi.*; -import com.sun.cri.ci.*; - - -public class VirtualObjectFieldNode extends FloatingNode { - - @Input private VirtualObjectNode object; - @Input private FloatingNode lastState; - @Input private ValueNode input; - - public VirtualObjectNode object() { - return object; - } - - public void setObject(VirtualObjectNode x) { - updateUsages(object, x); - object = x; - } - - public FloatingNode lastState() { - return lastState; - } - - public void setLastState(FloatingNode x) { - updateUsages(lastState, x); - lastState = x; - } - - public ValueNode input() { - return input; - } - - public void setInput(ValueNode x) { - updateUsages(input, x); - input = x; - } - - private int index; - - /** - * Constructs a new ArrayLength instruction. - * @param array the instruction producing the array - * @param newFrameState the state after executing this instruction - */ - public VirtualObjectFieldNode(VirtualObjectNode object, FloatingNode lastState, ValueNode input, int index, Graph graph) { - super(CiKind.Int, graph); - this.index = index; - setObject(object); - setLastState(lastState); - setInput(input); - } - - public int index() { - return index; - } - - @Override - public void accept(ValueVisitor v) { - // nothing to do... - } - - @Override - public Map getDebugProperties() { - Map properties = super.getDebugProperties(); - properties.put("index", index); - return properties; - } - - @Override - public String shortName() { - return "VirtualObjectField " + object().fields()[index].name(); - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/virtual/VirtualObjectNode.java --- a/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/virtual/VirtualObjectNode.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,71 +0,0 @@ -/* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.nodes.virtual; - -import java.util.*; - -import com.oracle.max.graal.graph.*; -import com.oracle.max.graal.nodes.calc.*; -import com.oracle.max.graal.nodes.spi.*; -import com.sun.cri.ci.*; -import com.sun.cri.ri.*; - - -public class VirtualObjectNode extends FloatingNode { - - - - private EscapeField[] fields; - private RiType type; - - public VirtualObjectNode(RiType type, EscapeField[] fields, Graph graph) { - super(CiKind.Int, graph); - this.type = type; - this.fields = fields; - } - - public RiType type() { - return type; - } - - public EscapeField[] fields() { - return fields; - } - - @Override - public void accept(ValueVisitor v) { - // nothing to do... - } - - @Override - public Map getDebugProperties() { - Map properties = super.getDebugProperties(); - properties.put("type", type); - return properties; - } - - @Override - public String shortName() { - return "VirtualObject " + type.name(); - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.runtime/.checkstyle --- a/graal/com.oracle.max.graal.runtime/.checkstyle Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,10 +0,0 @@ - - - - - - - - - - diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.runtime/.checkstyle_checks.xml --- a/graal/com.oracle.max.graal.runtime/.checkstyle_checks.xml Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,191 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.runtime/.classpath --- a/graal/com.oracle.max.graal.runtime/.classpath Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,13 +0,0 @@ - - - - - - - - - - - - - diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.runtime/.project --- a/graal/com.oracle.max.graal.runtime/.project Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,29 +0,0 @@ - - - com.oracle.max.graal.runtime - - - - - - 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 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.runtime/.settings/org.eclipse.jdt.core.prefs --- a/graal/com.oracle.max.graal.runtime/.settings/org.eclipse.jdt.core.prefs Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,384 +0,0 @@ -#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 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.runtime/.settings/org.eclipse.jdt.ui.prefs --- a/graal/com.oracle.max.graal.runtime/.settings/org.eclipse.jdt.ui.prefs Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,75 +0,0 @@ -#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 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.runtime/com_sun_hotspot_c1x_VMEntries.h --- a/graal/com.oracle.max.graal.runtime/com_sun_hotspot_c1x_VMEntries.h Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,189 +0,0 @@ -/* 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 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.runtime/create_native_header.bat --- a/graal/com.oracle.max.graal.runtime/create_native_header.bat Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -javah -classpath c1x4hotspot.jar com.sun.hotspot.c1x.VMEntries \ No newline at end of file diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/Compiler.java --- a/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/Compiler.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,36 +0,0 @@ -/* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.runtime; - -import com.oracle.max.graal.compiler.*; -import com.sun.cri.ri.*; - -public interface Compiler { - - VMEntries getVMEntries(); - VMExits getVMExits(); - GraalCompiler getCompiler(); - RiType lookupType(String returnType, HotSpotTypeResolved accessingClass); - HotSpotVMConfig getConfig(); - -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/CompilerImpl.java --- a/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/CompilerImpl.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,201 +0,0 @@ -/* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.runtime; - -import java.io.*; -import java.net.*; - -import com.oracle.max.asm.target.amd64.*; -import com.oracle.max.graal.compiler.*; -import com.oracle.max.graal.runtime.logging.*; -import com.oracle.max.graal.runtime.server.*; -import com.sun.cri.ci.*; -import com.sun.cri.ri.*; -import com.sun.cri.xir.*; - -/** - * Singleton class holding the instance of the GraalCompiler. - */ -public final class CompilerImpl implements Compiler, Remote { - - private static Compiler theInstance; - - public static Compiler getInstance() { - return theInstance; - } - - public static void initialize() { - if (theInstance != null) { - throw new IllegalStateException("Compiler already initialized"); - } - - String remote = System.getProperty("graal.remote"); - if (remote != null) { - // remote compilation (will not create a local Compiler) - try { - System.out.println("Graal compiler started in client/server mode, server: " + remote); - Socket socket = new Socket(remote, 1199); - ReplacingStreams streams = new ReplacingStreams(socket.getOutputStream(), socket.getInputStream()); - streams.getInvocation().sendResult(new VMEntriesNative()); - - theInstance = (Compiler) streams.getInvocation().waitForResult(false); - } catch (IOException e1) { - System.out.println("Connection to compilation server FAILED."); - throw new RuntimeException(e1); - } catch (ClassNotFoundException e2) { - System.out.println("Connection to compilation server FAILED."); - throw new RuntimeException(e2); - } - } else { - // ordinary local compilation - theInstance = new CompilerImpl(null); - } - } - - public static Compiler initializeServer(VMEntries entries) { - assert theInstance == null; - theInstance = new CompilerImpl(entries); - return theInstance; - } - - private final VMEntries vmEntries; - private final VMExits vmExits; - private GraalCompiler compiler; - - private final HotSpotRuntime runtime; - private final CiTarget target; - private final RiXirGenerator generator; - private final RiRegisterConfig registerConfig; - private final HotSpotVMConfig config; - - public HotSpotVMConfig getConfig() { - return config; - } - - private CompilerImpl(VMEntries entries) { - - // initialize VMEntries - if (entries == null) { - entries = new VMEntriesNative(); - } - - // initialize VMExits - VMExits exits = new VMExitsNative(this); - - // logging, etc. - if (CountingProxy.ENABLED) { - exits = CountingProxy.getProxy(VMExits.class, exits); - entries = CountingProxy.getProxy(VMEntries.class, entries); - } - if (Logger.ENABLED) { - exits = LoggingProxy.getProxy(VMExits.class, exits); - entries = LoggingProxy.getProxy(VMEntries.class, entries); - } - - // set the final fields - vmEntries = entries; - vmExits = exits; - - // initialize compiler and GraalOptions - config = vmEntries.getConfiguration(); - config.check(); - - // these options are important - graal will not generate correct code without them - GraalOptions.GenSpecialDivChecks = true; - GraalOptions.NullCheckUniquePc = true; - GraalOptions.InvokeSnippetAfterArguments = true; - GraalOptions.StackShadowPages = config.stackShadowPages; - - runtime = new HotSpotRuntime(config, this); - registerConfig = runtime.globalStubRegConfig; - - final int wordSize = 8; - final int stackFrameAlignment = 16; - target = new HotSpotTarget(new AMD64(), true, wordSize, stackFrameAlignment, config.vmPageSize, wordSize, true); - - RiXirGenerator generator = new HotSpotXirGenerator(config, target, registerConfig, this); - if (Logger.ENABLED) { - this.generator = LoggingProxy.getProxy(RiXirGenerator.class, generator); - } else { - this.generator = generator; - } - - } - - @Override - public GraalCompiler getCompiler() { - if (compiler == null) { - compiler = new GraalCompiler(runtime, target, generator, registerConfig); - } - return compiler; - } - - @Override - public VMEntries getVMEntries() { - return vmEntries; - } - - @Override - public VMExits getVMExits() { - return vmExits; - } - - @Override - public RiType lookupType(String returnType, HotSpotTypeResolved accessingClass) { - if (returnType.length() == 1 && vmExits instanceof VMExitsNative) { - VMExitsNative exitsNative = (VMExitsNative) vmExits; - CiKind kind = CiKind.fromPrimitiveOrVoidTypeChar(returnType.charAt(0)); - switch(kind) { - case Boolean: - return exitsNative.typeBoolean; - case Byte: - return exitsNative.typeByte; - case Char: - return exitsNative.typeChar; - case Double: - return exitsNative.typeDouble; - case Float: - return exitsNative.typeFloat; - case Illegal: - break; - case Int: - return exitsNative.typeInt; - case Jsr: - break; - case Long: - return exitsNative.typeLong; - case Object: - break; - case Short: - return exitsNative.typeShort; - case Void: - return exitsNative.typeVoid; - case Word: - break; - - } - } - return vmEntries.RiSignature_lookupType(returnType, accessingClass); - } - -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/CompilerObject.java --- a/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/CompilerObject.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,38 +0,0 @@ -/* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.runtime; - -import java.io.*; - - -/** - * Parent class for all HotSpot Ri... types. - */ -public abstract class CompilerObject implements Serializable { - protected final Compiler compiler; - - protected CompilerObject(Compiler compiler) { - this.compiler = compiler; - } - -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/HotSpotConstantPool.java --- a/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/HotSpotConstantPool.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,147 +0,0 @@ -/* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.runtime; - -import java.io.*; -import java.util.*; - -import com.sun.cri.ri.*; - -/** - * Implementation of RiConstantPool for HotSpot. - */ -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 implements Serializable { - - 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(Compiler compiler, long vmId) { - super(compiler); - 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); - if (result.isResolved()) { - 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 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/HotSpotExceptionHandler.java --- a/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/HotSpotExceptionHandler.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,69 +0,0 @@ -/* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.runtime; - -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; - - public HotSpotExceptionHandler() { - super(null); - } - - @Override - public int startBCI() { - return startBci; - } - - @Override - public int endBCI() { - return endBci; - } - - @Override - public int handlerBCI() { - return handlerBci; - } - - @Override - public int catchTypeCPI() { - return catchClassIndex; - } - - @Override - public boolean isCatchAll() { - return catchClassIndex == 0; - } - - @Override - public RiType catchType() { - return catchClass; - } - -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/HotSpotField.java --- a/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/HotSpotField.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,134 +0,0 @@ -/* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package com.oracle.max.graal.runtime; - -import java.lang.reflect.*; - -import com.oracle.max.graal.compiler.*; -import com.sun.cri.ci.*; -import com.sun.cri.ri.*; - -/** - * Represents a field in a HotSpot type. - */ -public class HotSpotField extends CompilerObject implements RiField { - - private final RiType holder; - private final String name; - private final RiType type; - private final int offset; - private final int accessFlags; - private CiConstant constant; - - public HotSpotField(Compiler compiler, RiType holder, String name, RiType type, int offset, int accessFlags) { - super(compiler); - this.holder = holder; - this.name = name; - this.type = type; - this.offset = offset; - this.accessFlags = accessFlags; - } - - @Override - public int accessFlags() { - return accessFlags; - } - - @Override - public CiConstant constantValue(CiConstant receiver) { - if (receiver == null) { - if (constant == null && holder.isResolved() && holder.isSubtypeOf(compiler.getVMEntries().getType(GraalOptions.class))) { - Field f; - try { - f = GraalOptions.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 holder.isResolved(); - } - - @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<" + CiUtil.format("%h.%n", this, false) + ":" + offset + ">"; - } - -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/HotSpotMethod.java --- a/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/HotSpotMethod.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,57 +0,0 @@ -/* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.runtime; - -import java.util.*; - -import com.sun.cri.ri.*; - - -public abstract class HotSpotMethod extends CompilerObject implements RiMethod { - - protected RiType holder; - protected String name; - public Map compilerStorage; - - protected HotSpotMethod(Compiler compiler) { - super(compiler); - } - - @Override - public final RiType holder() { - return holder; - } - - @Override - public final String name() { - return name; - } - - @Override - public Map compilerStorage() { - if (compilerStorage == null) { - compilerStorage = new HashMap(); - } - return compilerStorage; - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/HotSpotMethodResolved.java --- a/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/HotSpotMethodResolved.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,32 +0,0 @@ -/* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.runtime; - -import com.oracle.max.graal.runtime.server.*; -import com.sun.cri.ri.*; - -public interface HotSpotMethodResolved extends RiMethod, Remote { - - RiMethod uniqueConcreteMethod(); - void dumpProfile(); -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/HotSpotMethodResolvedImpl.java --- a/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/HotSpotMethodResolvedImpl.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,233 +0,0 @@ -/* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.runtime; - -import java.lang.reflect.*; - -import com.oracle.max.graal.compiler.debug.*; -import com.oracle.max.graal.graph.*; -import com.sun.cri.ci.*; -import com.sun.cri.ri.*; - -/** - * Implementation of RiMethod for resolved HotSpot methods. - */ -public final class HotSpotMethodResolvedImpl extends HotSpotMethod implements HotSpotMethodResolved { - - /** DO NOT USE IN JAVA CODE! */ - @Deprecated - private Object javaMirror; - - // cached values - private final int codeSize; - private final int accessFlags; - private final int maxLocals; - private final int maxStackSize; - private RiExceptionHandler[] exceptionHandlers; - private RiSignature signature; - private Boolean hasBalancedMonitors; - - private HotSpotMethodResolvedImpl() { - super(null); - codeSize = -1; - accessFlags = -1; - maxLocals = -1; - maxStackSize = -1; - } - - @Override - public int accessFlags() { - return accessFlags; - } - - @Override - public boolean canBeStaticallyBound() { - return isLeafMethod() || Modifier.isStatic(accessFlags()); - } - - @Override - public byte[] code() { - assert holder.isResolved(); - - byte[] ret = compiler.getVMEntries().RiMethod_code(this); - assert ret.length == codeSize : "expected: " + codeSize + ", actual: " + ret.length; - return ret; - } - - @Override - public int codeSize() { - return codeSize; - } - - @Override - public RiExceptionHandler[] exceptionHandlers() { - return compiler.getVMEntries().RiMethod_exceptionHandlers(this); - } - - @Override - public boolean hasBalancedMonitors() { - if (hasBalancedMonitors == null) { - hasBalancedMonitors = compiler.getVMEntries().RiMethod_hasBalancedMonitors(this); - } - return hasBalancedMonitors; - } - - @Override - public boolean isClassInitializer() { - return "".equals(name) && Modifier.isStatic(accessFlags()); - } - - @Override - public boolean isConstructor() { - return "".equals(name) && !Modifier.isStatic(accessFlags()); - } - - @Override - public boolean isLeafMethod() { - return Modifier.isFinal(accessFlags()) || Modifier.isPrivate(accessFlags()); - } - - @Override - public boolean isOverridden() { - throw new UnsupportedOperationException("isOverridden"); - } - - @Override - public boolean noSafepoints() { - return false; - } - - @Override - public boolean isResolved() { - return true; - } - - @Override - public String jniSymbol() { - throw new UnsupportedOperationException("jniSymbol"); - } - - public BitMap[] livenessMap() { - return null; - } - - @Override - public int maxLocals() { - return maxLocals; - } - - @Override - public int maxStackSize() { - 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(this); - } - - @Override - public RiSignature signature() { - if (signature == null) { - signature = new HotSpotSignature(compiler, compiler.getVMEntries().RiMethod_signature(this)); - } - return signature; - } - - @Override - public String toString() { - return "HotSpotMethod<" + CiUtil.format("%h.%n", this, false) + ">"; - } - - public boolean hasCompiledCode() { - return compiler.getVMEntries().RiMethod_hasCompiledCode(this); - } - - @Override - public RiType accessor() { - return null; - } - - @Override - public int intrinsic() { - return 0; - } - - @Override - public boolean minimalDebugInfo() { - return false; - } - - public int invocationCount() { - return compiler.getVMEntries().RiMethod_invocationCount(this); - } - - public int exceptionProbability(int bci) { - return compiler.getVMEntries().RiMethod_exceptionProbability(this, bci); - } - - public RiTypeProfile typeProfile(int bci) { - return compiler.getVMEntries().RiMethod_typeProfile(this, bci); - } - - public double branchProbability(int bci) { - return compiler.getVMEntries().RiMethod_branchProbability(this, bci); - } - - public double[] switchProbability(int bci) { - return compiler.getVMEntries().RiMethod_switchProbability(this, bci); - } - - @Override - public int compiledCodeSize() { - return compiler.getVMEntries().RiMethod_compiledCodeSize(this); - } - - public void dumpProfile() { - TTY.println("profile info for %s", this); - TTY.println("canBeStaticallyBound: " + canBeStaticallyBound()); - TTY.println("invocationCount: " + invocationCount()); - for (int i = 0; i < codeSize(); i++) { - if (branchProbability(i) != -1) { - TTY.println(" branchProbability@%d: %f", i, branchProbability(i)); - } - RiTypeProfile profile = typeProfile(i); - if (profile != null && profile.count > 0) { - TTY.println(" profile@%d: count: %d, morphism: %d", i, profile.count, profile.morphism); - if (exceptionProbability(i) != -1) { - TTY.println(" exceptionProbability@%d: %d", i, exceptionProbability(i)); - } - } - } - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/HotSpotMethodUnresolved.java --- a/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/HotSpotMethodUnresolved.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,189 +0,0 @@ -/* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.runtime; - -import com.oracle.max.graal.graph.*; -import com.sun.cri.ci.*; -import com.sun.cri.ri.*; - -/** - * Implementation of RiMethod for unresolved HotSpot methods. - */ -public final class HotSpotMethodUnresolved extends HotSpotMethod { - private final RiSignature signature; - - public HotSpotMethodUnresolved(Compiler compiler, String name, String signature, RiType holder) { - super(compiler); - this.name = name; - this.holder = holder; - this.signature = new HotSpotSignature(compiler, signature); - } - - @Override - public RiSignature signature() { - return signature; - } - - @Override - public boolean isResolved() { - return false; - } - - @Override - public byte[] code() { - throw unresolved("code"); - } - - @Override - public int codeSize() { - return 0; - } - - @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 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 boolean noSafepoints() { - return false; - } - - @Override - public BitMap[] 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"); - } - - @Override - public boolean minimalDebugInfo() { - throw unresolved("minimalDebugInfo"); - } - - 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 RiType accessor() { - return null; - } - - @Override - public int intrinsic() { - return 0; - } - - public int invocationCount() { - return -1; - } - - public int exceptionProbability(int bci) { - return -1; - } - - public RiTypeProfile typeProfile(int bci) { - return null; - } - - public double branchProbability(int bci) { - return -1; - } - - public double[] switchProbability(int bci) { - return null; - } - - @Override - public int compiledCodeSize() { - return -1; - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/HotSpotOptions.java --- a/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/HotSpotOptions.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,107 +0,0 @@ -/* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package com.oracle.max.graal.runtime; - -import java.lang.reflect.*; - -import com.oracle.max.graal.compiler.*; -import com.oracle.max.graal.runtime.logging.*; - -public class HotSpotOptions { - - public static void setDefaultOptions() { - GraalOptions.CommentedAssembly = false; - GraalOptions.MethodEndBreakpointGuards = 2; - GraalOptions.ResolveClassBeforeStaticInvoke = false; - } - - public static 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) { - fieldName = option; - valueString = null; - } else { - fieldName = option.substring(0, index); - valueString = option.substring(index + 1); - } - } - - Field f; - try { - f = GraalOptions.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) { - if (valueString == null || valueString.length() == 0) { - value = true; - } else { - 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; - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/HotSpotProxy.java --- a/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/HotSpotProxy.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,92 +0,0 @@ -/* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.runtime; - -/** - * Provides methods to classify the HotSpot-internal identifiers. - */ -public final class HotSpotProxy { - - private HotSpotProxy() { - } - - private enum CompilerObjectType { - // this enum needs to have the same values as the one in graal_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 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/HotSpotRegisterConfig.java --- a/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/HotSpotRegisterConfig.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,209 +0,0 @@ -/* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.runtime; - -import static com.oracle.max.asm.target.amd64.AMD64.*; - -import java.util.*; - -import com.oracle.max.asm.target.amd64.*; -import com.oracle.max.graal.compiler.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.*; - -public class HotSpotRegisterConfig implements RiRegisterConfig { - - // be careful - the contents of this array are duplicated in graal_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 CiCalleeSaveLayout 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 CiCalleeSaveLayout(0, -1, 8, rsaRegs); - } else { - registerSaveArea = new CiCalleeSaveLayout(0, 0, 0, new CiRegister[0]); - } - - 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, boolean stackOnly) { - if (type == Type.NativeCall) { - throw new UnsupportedOperationException(); - } - return callingConvention(parameters, type, target, stackOnly); - } - - public CiRegister[] getCallingConventionRegisters(Type type, RegisterFlag flag) { - return allParameterRegisters; - } - - private CiCallingConvention callingConvention(CiKind[] types, Type type, CiTarget target, boolean stackOnly) { - 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 (!stackOnly && currentGeneral < generalParameterRegisters.length) { - CiRegister register = generalParameterRegisters[currentGeneral++]; - locations[i] = register.asValue(kind); - } - break; - case Float: - case Double: - if (!stackOnly && 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 CiCalleeSaveLayout getCalleeSaveLayout() { - return registerSaveArea; - } - - @Override - public String toString() { - String res = String.format( - "Allocatable: " + Arrays.toString(getAllocatableRegisters()) + "%n" + - "CallerSave: " + Arrays.toString(getCallerSaveRegisters()) + "%n" + - "CalleeSave: " + getCalleeSaveLayout() + "%n" + - "Scratch: " + getScratchRegister() + "%n"); - return res; - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/HotSpotRuntime.java --- a/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/HotSpotRuntime.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,639 +0,0 @@ -/* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.runtime; - -import java.io.*; -import java.lang.reflect.*; -import java.util.*; - -import com.oracle.max.graal.compiler.*; -import com.oracle.max.graal.graph.*; -import com.oracle.max.graal.nodes.*; -import com.oracle.max.graal.nodes.calc.*; -import com.oracle.max.graal.nodes.calc.ConditionalNode.ConditionalStructure; -import com.oracle.max.graal.nodes.extended.*; -import com.oracle.max.graal.nodes.java.*; -import com.oracle.max.graal.runtime.nodes.*; -import com.sun.cri.bytecode.*; -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.cri.ri.RiType.Representation; -import com.sun.max.asm.dis.*; -import com.sun.max.lang.*; - -/** - * CRI runtime implementation for the HotSpot VM. - */ -public class HotSpotRuntime implements RiRuntime { - private static final long DOUBLENAN_RAW_LONG_BITS = Double.doubleToRawLongBits(Double.NaN); - private static final int FLOATNAN_RAW_INT_BITS = Float.floatToRawIntBits(Float.NaN); - - final HotSpotVMConfig config; - final HotSpotRegisterConfig regConfig; - final HotSpotRegisterConfig globalStubRegConfig; - private final Compiler compiler; - private IdentityHashMap intrinsicGraphs = new IdentityHashMap(); - - - public HotSpotRuntime(HotSpotVMConfig config, Compiler compiler) { - this.config = config; - this.compiler = compiler; - 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.stubID != null) { - return "{" + call.stubID + "}"; - } 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(); - } - - public Class getJavaClass(CiConstant c) { - return null; - } - - @Override - public RiType asRiType(CiKind kind) { - return compiler.getVMEntries().getType(kind.toJavaClass()); - } - - @Override - public RiType getTypeOf(CiConstant constant) { - return compiler.getVMEntries().getRiType(constant); - } - - @Override - public boolean isExceptionType(RiType type) { - return type.isSubtypeOf(compiler.getVMEntries().getType(Throwable.class)); - } - - @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 registerCompilerStub(CiTargetMethod targetMethod, String name) { - return HotSpotTargetMethod.installStub(compiler, targetMethod, name); - } - - @Override - public int sizeOfBasicObjectLock() { - // TODO shouldn't be hard coded - return 2 * 8; - } - - @Override - public int basicObjectLockOffsetInBytes() { - return 8; - } - - @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 areConstantObjectsEqual(CiConstant x, CiConstant y) { - return compiler.getVMEntries().compareConstantObjects(x, y); - } - - @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; - } - - @Override - public int getArrayLength(CiConstant array) { - return compiler.getVMEntries().getArrayLength(array); - } - - @Override - public Class asJavaClass(CiConstant c) { - return null; - } - - @Override - public Object asJavaObject(CiConstant c) { - return null; - } - - @Override - public void lower(Node n, CiLoweringTool tool) { - if (!GraalOptions.Lower) { - return; - } - - if (n instanceof LoadFieldNode) { - LoadFieldNode field = (LoadFieldNode) n; - if (field.isVolatile()) { - return; - } - Graph graph = field.graph(); - int displacement = ((HotSpotField) field.field()).offset(); - assert field.kind != CiKind.Illegal; - ReadNode memoryRead = new ReadNode(field.field().kind().stackKind(), field.object(), LocationNode.create(field.field(), field.field().kind(), displacement, graph), graph); - memoryRead.setGuard((GuardNode) tool.createGuard(new IsNonNullNode(field.object(), graph))); - FixedNode next = field.next(); - field.setNext(null); - memoryRead.setNext(next); - field.replaceAndDelete(memoryRead); - } else if (n instanceof StoreFieldNode) { - StoreFieldNode field = (StoreFieldNode) n; - if (field.isVolatile()) { - return; - } - Graph graph = field.graph(); - int displacement = ((HotSpotField) field.field()).offset(); - WriteNode memoryWrite = new WriteNode(CiKind.Illegal, field.object(), field.value(), LocationNode.create(field.field(), field.field().kind(), displacement, graph), graph); - memoryWrite.setGuard((GuardNode) tool.createGuard(new IsNonNullNode(field.object(), graph))); - memoryWrite.setStateAfter(field.stateAfter()); - FixedNode next = field.next(); - field.setNext(null); - if (field.field().kind() == CiKind.Object && !field.value().isNullConstant()) { - FieldWriteBarrier writeBarrier = new FieldWriteBarrier(field.object(), graph); - memoryWrite.setNext(writeBarrier); - writeBarrier.setNext(next); - } else { - memoryWrite.setNext(next); - } - field.replaceAndDelete(memoryWrite); - } else if (n instanceof LoadIndexedNode) { - LoadIndexedNode loadIndexed = (LoadIndexedNode) n; - Graph graph = loadIndexed.graph(); - GuardNode boundsCheck = createBoundsCheck(loadIndexed, tool); - - CiKind elementKind = loadIndexed.elementKind(); - LocationNode arrayLocation = createArrayLocation(graph, elementKind); - arrayLocation.setIndex(loadIndexed.index()); - ReadNode memoryRead = new ReadNode(elementKind.stackKind(), loadIndexed.array(), arrayLocation, graph); - memoryRead.setGuard(boundsCheck); - FixedNode next = loadIndexed.next(); - loadIndexed.setNext(null); - memoryRead.setNext(next); - loadIndexed.replaceAndDelete(memoryRead); - } else if (n instanceof StoreIndexedNode) { - StoreIndexedNode storeIndexed = (StoreIndexedNode) n; - Graph graph = storeIndexed.graph(); - AnchorNode anchor = new AnchorNode(graph); - GuardNode boundsCheck = createBoundsCheck(storeIndexed, tool); - anchor.addGuard(boundsCheck); - - - CiKind elementKind = storeIndexed.elementKind(); - LocationNode arrayLocation = createArrayLocation(graph, elementKind); - arrayLocation.setIndex(storeIndexed.index()); - ValueNode value = storeIndexed.value(); - ValueNode array = storeIndexed.array(); - if (elementKind == CiKind.Object && !value.isNullConstant()) { - // Store check! - if (array.exactType() != null) { - RiType elementType = array.exactType().componentType(); - if (elementType.superType() != null) { - ConstantNode type = new ConstantNode(elementType.getEncoding(Representation.ObjectHub), graph); - value = new CheckCastNode(type, value, graph); - } else { - assert elementType.name().equals("Ljava/lang/Object;") : elementType.name(); - } - } else { - ReadNode arrayElementKlass = readArrayElementKlass(graph, array); - value = new CheckCastNode(arrayElementKlass, value, graph); - } - } - WriteNode memoryWrite = new WriteNode(elementKind.stackKind(), array, value, arrayLocation, graph); - memoryWrite.setGuard(boundsCheck); - memoryWrite.setStateAfter(storeIndexed.stateAfter()); - FixedNode next = storeIndexed.next(); - storeIndexed.setNext(null); - anchor.setNext(memoryWrite); - if (elementKind == CiKind.Object && !value.isNullConstant()) { - ArrayWriteBarrier writeBarrier = new ArrayWriteBarrier(array, arrayLocation, graph); - memoryWrite.setNext(writeBarrier); - writeBarrier.setNext(next); - } else { - memoryWrite.setNext(next); - } - storeIndexed.replaceAtPredecessors(anchor); - storeIndexed.delete(); - } else if (n instanceof UnsafeLoad) { - UnsafeLoad load = (UnsafeLoad) n; - Graph graph = load.graph(); - assert load.kind != CiKind.Illegal; - LocationNode location = LocationNode.create(LocationNode.UNSAFE_ACCESS_LOCATION, load.kind, 0, graph); - location.setIndex(load.offset()); - location.setIndexScalingEnabled(false); - ReadNode memoryRead = new ReadNode(load.kind.stackKind(), load.object(), location, graph); - memoryRead.setGuard((GuardNode) tool.createGuard(new IsNonNullNode(load.object(), graph))); - FixedNode next = load.next(); - load.setNext(null); - memoryRead.setNext(next); - load.replaceAndDelete(memoryRead); - } else if (n instanceof UnsafeStore) { - UnsafeStore store = (UnsafeStore) n; - Graph graph = store.graph(); - assert store.kind != CiKind.Illegal; - LocationNode location = LocationNode.create(LocationNode.UNSAFE_ACCESS_LOCATION, store.kind, 0, graph); - location.setIndex(store.offset()); - location.setIndexScalingEnabled(false); - WriteNode write = new WriteNode(store.kind.stackKind(), store.object(), store.value(), location, graph); - FieldWriteBarrier barrier = new FieldWriteBarrier(store.object(), graph); - FixedNode next = store.next(); - store.setNext(null); - barrier.setNext(next); - write.setNext(barrier); - write.setStateAfter(store.stateAfter()); - store.replaceAtPredecessors(write); - store.delete(); - } - } - - private ReadNode readArrayElementKlass(Graph graph, ValueNode array) { - ReadNode arrayKlass = readHub(graph, array); - ReadNode arrayElementKlass = new ReadNode(CiKind.Object, arrayKlass, LocationNode.create(LocationNode.FINAL_LOCATION, CiKind.Object, config.arrayClassElementOffset, graph), graph); - return arrayElementKlass; - } - - private LocationNode createArrayLocation(Graph graph, CiKind elementKind) { - return LocationNode.create(LocationNode.getArrayLocation(elementKind), elementKind, config.getArrayOffset(elementKind), graph); - } - - private GuardNode createBoundsCheck(AccessIndexedNode n, CiLoweringTool tool) { - return (GuardNode) tool.createGuard(new CompareNode(n.index(), Condition.BT, n.length(), n.graph())); - } - - @Override - public Graph intrinsicGraph(RiMethod caller, int bci, RiMethod method, List parameters) { - if (!intrinsicGraphs.containsKey(method)) { - RiType holder = method.holder(); - String fullName = method.name() + method.signature().asString(); - String holderName = holder.name(); - if (holderName.equals("Ljava/lang/Object;")) { - if (fullName.equals("getClass()Ljava/lang/Class;")) { - CompilerGraph graph = new CompilerGraph(this); - LocalNode receiver = new LocalNode(CiKind.Object, 0, graph); - ReadNode klassOop = readHub(graph, receiver); - ReturnNode ret = new ReturnNode(new ReadNode(CiKind.Object, klassOop, LocationNode.create(LocationNode.FINAL_LOCATION, CiKind.Object, config.classMirrorOffset, graph), graph), graph); - graph.start().setNext(ret); - graph.setReturn(ret); - intrinsicGraphs.put(method, graph); - } - } else if (holderName.equals("Ljava/lang/System;")) { - if (fullName.equals("arraycopy(Ljava/lang/Object;ILjava/lang/Object;II)V")) { - CompilerGraph graph = new CompilerGraph(this); - LocalNode src = new LocalNode(CiKind.Object, 0, graph); - LocalNode srcPos = new LocalNode(CiKind.Int, 1, graph); - LocalNode dest = new LocalNode(CiKind.Object, 2, graph); - LocalNode destPos = new LocalNode(CiKind.Int, 3, graph); - ValueNode length = new LocalNode(CiKind.Int, 4, graph); - src.setDeclaredType(((ValueNode) parameters.get(0)).declaredType()); - dest.setDeclaredType(((ValueNode) parameters.get(2)).declaredType()); - - if (src.declaredType() == null || dest.declaredType() == null) { - return null; - } - - if (src.declaredType() != dest.declaredType()) { - return null; - } - - if (!src.declaredType().isArrayClass()) { - return null; - } - - CiKind componentType = src.declaredType().componentType().kind(); - if (componentType == CiKind.Object) { - return null; - } - - FrameState stateBefore = new FrameState(method, FrameState.BEFORE_BCI, 0, 0, 0, false, graph); - FrameState stateAfter = new FrameState(method, FrameState.AFTER_BCI, 0, 0, 0, false, graph); - - // Add preconditions. - FixedGuardNode guard = new FixedGuardNode(graph); - ArrayLengthNode srcLength = new ArrayLengthNode(src, graph); - ArrayLengthNode destLength = new ArrayLengthNode(dest, graph); - IntegerAddNode upperLimitSrc = new IntegerAddNode(CiKind.Int, srcPos, length, graph); - IntegerAddNode upperLimitDest = new IntegerAddNode(CiKind.Int, destPos, length, graph); - guard.addNode(new CompareNode(srcPos, Condition.BE, srcLength, graph)); - guard.addNode(new CompareNode(destPos, Condition.BE, destLength, graph)); - guard.addNode(new CompareNode(length, Condition.GE, ConstantNode.forInt(0, graph), graph)); - guard.addNode(new CompareNode(upperLimitSrc, Condition.LE, srcLength, graph)); - guard.addNode(new CompareNode(upperLimitDest, Condition.LE, destLength, graph)); - graph.start().setNext(guard); - - LocationNode location = LocationNode.create(LocationNode.FINAL_LOCATION, componentType, config.getArrayOffset(componentType), graph); - - // Build normal vector instruction. - CreateVectorNode normalVector = new CreateVectorNode(false, length, graph); - ReadVectorNode values = new ReadVectorNode(new IntegerAddVectorNode(normalVector, srcPos, graph), src, location, graph); - new WriteVectorNode(new IntegerAddVectorNode(normalVector, destPos, graph), dest, location, values, graph); - normalVector.setStateAfter(stateAfter); - - // Build reverse vector instruction. - CreateVectorNode reverseVector = new CreateVectorNode(true, length, graph); - ReadVectorNode reverseValues = new ReadVectorNode(new IntegerAddVectorNode(reverseVector, srcPos, graph), src, location, graph); - new WriteVectorNode(new IntegerAddVectorNode(reverseVector, destPos, graph), dest, location, reverseValues, graph); - reverseVector.setStateAfter(stateAfter); - - IfNode ifNode = new IfNode(new CompareNode(src, Condition.EQ, dest, graph), 0.5, graph); - guard.setNext(ifNode); - - IfNode secondIf = new IfNode(new CompareNode(srcPos, Condition.LT, destPos, graph), 0.5, graph); - ifNode.setTrueSuccessor(secondIf); - - secondIf.setTrueSuccessor(reverseVector); - - MergeNode merge1 = new MergeNode(graph); - merge1.addEnd(new EndNode(graph)); - merge1.addEnd(new EndNode(graph)); - merge1.setStateAfter(stateBefore); - - - InvokeNode newInvoke = null; - if (componentType == CiKind.Object) { - ValueNode srcClass = readHub(graph, src); - ValueNode destClass = readHub(graph, dest); - IfNode elementClassIf = new IfNode(new CompareNode(srcClass, Condition.EQ, destClass, graph), 0.5, graph); - ifNode.setFalseSuccessor(elementClassIf); - newInvoke = new InvokeNode(bci, Bytecodes.INVOKESTATIC, CiKind.Void, new ValueNode[]{src, srcPos, dest, destPos, length}, method, method.signature().returnType(method.holder()), graph); - newInvoke.setCanInline(false); - newInvoke.setStateAfter(stateAfter); - elementClassIf.setFalseSuccessor(newInvoke); - elementClassIf.setTrueSuccessor(merge1.endAt(0)); - } else { - ifNode.setFalseSuccessor(merge1.endAt(0)); - } - - secondIf.setFalseSuccessor(merge1.endAt(1)); - merge1.setNext(normalVector); - - MergeNode merge2 = new MergeNode(graph); - merge2.addEnd(new EndNode(graph)); - merge2.addEnd(new EndNode(graph)); - merge2.setStateAfter(stateAfter); - - normalVector.setNext(merge2.endAt(0)); - reverseVector.setNext(merge2.endAt(1)); - - if (newInvoke != null) { - merge2.addEnd(new EndNode(graph)); - newInvoke.setNext(merge2.endAt(2)); - } - - ReturnNode ret = new ReturnNode(null, graph); - merge2.setNext(ret); - graph.setReturn(ret); - return graph; - } - } else if (holderName.equals("Ljava/lang/Float;")) { //XXX (gd) the non-raw versions of (F/D)2(I/L) should return a sanitized NaN in the NaN case. - if (fullName.equals("floatToRawIntBits(F)I")) { - CompilerGraph graph = new CompilerGraph(this); - ReturnNode ret = new ReturnNode(new FPConversionNode(CiKind.Int, new LocalNode(CiKind.Float, 0, graph), graph), graph); - graph.start().setNext(ret); - graph.setReturn(ret); - intrinsicGraphs.put(method, graph); - } else if (fullName.equals("floatToIntBits(F)I")) { - CompilerGraph graph = new CompilerGraph(this); - LocalNode arg = new LocalNode(CiKind.Float, 0, graph); - CompareNode isNan = new CompareNode(arg, Condition.NE, arg, graph); - isNan.setUnorderedIsTrue(true); - FPConversionNode fpConv = new FPConversionNode(CiKind.Int, arg, graph); - ConditionalStructure conditionalStructure = ConditionalNode.createConditionalStructure(isNan, ConstantNode.forInt(FLOATNAN_RAW_INT_BITS, graph), fpConv, 0.1); - ReturnNode ret = new ReturnNode(conditionalStructure.phi, graph); - graph.start().setNext(conditionalStructure.ifNode); - conditionalStructure.merge.setNext(ret); - graph.setReturn(ret); - intrinsicGraphs.put(method, graph); - } else if (fullName.equals("intBitsToFloat(I)F")) { - CompilerGraph graph = new CompilerGraph(this); - ReturnNode ret = new ReturnNode(new FPConversionNode(CiKind.Float, new LocalNode(CiKind.Int, 0, graph), graph), graph); - graph.start().setNext(ret); - graph.setReturn(ret); - intrinsicGraphs.put(method, graph); - } - } else if (holderName.equals("Ljava/lang/Double;")) { - if (fullName.equals("doubleToRawLongBits(D)J")) { - CompilerGraph graph = new CompilerGraph(this); - ReturnNode ret = new ReturnNode(new FPConversionNode(CiKind.Long, new LocalNode(CiKind.Double, 0, graph), graph), graph); - graph.start().setNext(ret); - graph.setReturn(ret); - intrinsicGraphs.put(method, graph); - } else if (fullName.equals("doubleToLongBits(D)J")) { - CompilerGraph graph = new CompilerGraph(this); - LocalNode arg = new LocalNode(CiKind.Double, 0, graph); - CompareNode isNan = new CompareNode(arg, Condition.NE, arg, graph); - isNan.setUnorderedIsTrue(true); - FPConversionNode fpConv = new FPConversionNode(CiKind.Long, arg, graph); - ConditionalStructure conditionalStructure = ConditionalNode.createConditionalStructure(isNan, ConstantNode.forLong(DOUBLENAN_RAW_LONG_BITS, graph), fpConv, 0.1); - ReturnNode ret = new ReturnNode(conditionalStructure.phi, graph); - graph.start().setNext(conditionalStructure.ifNode); - conditionalStructure.merge.setNext(ret); - graph.setReturn(ret); - intrinsicGraphs.put(method, graph); - } else if (fullName.equals("longBitsToDouble(J)D")) { - CompilerGraph graph = new CompilerGraph(this); - ReturnNode ret = new ReturnNode(new FPConversionNode(CiKind.Double, new LocalNode(CiKind.Long, 0, graph), graph), graph); - graph.start().setNext(ret); - graph.setReturn(ret); - intrinsicGraphs.put(method, graph); - } - } else if (holderName.equals("Ljava/lang/Thread;")) { - if (fullName.equals("currentThread()Ljava/lang/Thread;")) { - CompilerGraph graph = new CompilerGraph(this); - ReturnNode ret = new ReturnNode(new CurrentThread(config.threadObjectOffset, graph), graph); - graph.start().setNext(ret); - graph.setReturn(ret); - intrinsicGraphs.put(method, graph); - } - } else if (holderName.equals("Lsun/misc/Unsafe;")) { - if (fullName.equals("getObject(Ljava/lang/Object;J)Ljava/lang/Object;")) { - CompilerGraph graph = new CompilerGraph(this); - LocalNode object = new LocalNode(CiKind.Object, 1, graph); - LocalNode offset = new LocalNode(CiKind.Long, 2, graph); - UnsafeLoad load = new UnsafeLoad(object, offset, CiKind.Object, graph); - ReturnNode ret = new ReturnNode(load, graph); - load.setNext(ret); - graph.start().setNext(load); - graph.setReturn(ret); - intrinsicGraphs.put(method, graph); - } else if (fullName.equals("putObject(Ljava/lang/Object;JLjava/lang/Object;)V")) { - CompilerGraph graph = new CompilerGraph(this); - LocalNode object = new LocalNode(CiKind.Object, 1, graph); - LocalNode offset = new LocalNode(CiKind.Long, 2, graph); - LocalNode value = new LocalNode(CiKind.Object, 3, graph); - UnsafeStore store = new UnsafeStore(object, offset, value, CiKind.Object, graph); - FrameState frameState = new FrameState(method, FrameState.AFTER_BCI, 0, 0, 0, false, graph); - store.setStateAfter(frameState); - ReturnNode ret = new ReturnNode(null, graph); - store.setNext(ret); - graph.start().setNext(store); - graph.setReturn(ret); - intrinsicGraphs.put(method, graph); - } - } else if (holderName.equals("Ljava/lang/Math;")) { - MathIntrinsicNode.Operation op = null; - if (fullName.equals("abs(D)D")) { - op = MathIntrinsicNode.Operation.ABS; - } else if (fullName.equals("sqrt(D)D")) { - op = MathIntrinsicNode.Operation.SQRT; - } - if (op != null) { - CompilerGraph graph = new CompilerGraph(this); - LocalNode value = new LocalNode(CiKind.Double, 0, graph); - MathIntrinsicNode min = new MathIntrinsicNode(value, op, graph); - ReturnNode ret = new ReturnNode(min, graph); - graph.start().setNext(ret); - graph.setReturn(ret); - intrinsicGraphs.put(method, graph); - } - } - - if (!intrinsicGraphs.containsKey(method)) { - intrinsicGraphs.put(method, null); - } - } - return intrinsicGraphs.get(method); - } - - private ReadNode readHub(Graph graph, ValueNode value) { - return new ReadNode(CiKind.Object, value, LocationNode.create(LocationNode.FINAL_LOCATION, CiKind.Object, config.hubOffset, graph), graph); - } - - @Override - public RiType getType(Class clazz) { - return compiler.getVMEntries().getType(clazz); - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/HotSpotSignature.java --- a/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/HotSpotSignature.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,149 +0,0 @@ -/* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.runtime; - -import java.util.*; - -import com.sun.cri.ci.*; -import com.sun.cri.ri.*; - -/** - * Represents a method signature. - */ -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(Compiler compiler, String signature) { - super(compiler); - 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.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.lookupType(returnType, (HotSpotTypeResolved) accessingClass); - } - return returnTypeCache; - } - - @Override - public String toString() { - return "HotSpotSignature<" + originalString + ">"; - } - -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/HotSpotTarget.java --- a/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/HotSpotTarget.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,41 +0,0 @@ -/* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.runtime; - -import com.sun.cri.ci.*; - -/** - * HotSpot-specific CiTarget that provides the correct stack frame size alignment. - */ -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 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/HotSpotTargetMethod.java --- a/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/HotSpotTargetMethod.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,108 +0,0 @@ -/* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.runtime; - -import java.util.*; - -import com.oracle.max.graal.runtime.logging.*; -import com.sun.cri.ci.*; -import com.sun.cri.ci.CiTargetMethod.ExceptionHandler; -import com.sun.cri.ci.CiTargetMethod.Mark; -import com.sun.cri.ci.CiTargetMethod.Site; - -/** - * CiTargetMethod augmented with HotSpot-specific information. - */ -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(Compiler compiler, HotSpotMethodResolved method, CiTargetMethod targetMethod) { - super(compiler); - 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(Compiler compiler, CiTargetMethod targetMethod, String name) { - super(compiler); - 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(Compiler compiler, HotSpotMethodResolved method, CiTargetMethod targetMethod) { - compiler.getVMEntries().installMethod(new HotSpotTargetMethod(compiler, method, targetMethod)); - } - - public static Object installStub(Compiler compiler, CiTargetMethod targetMethod, String name) { - return compiler.getVMEntries().installStub(new HotSpotTargetMethod(compiler, targetMethod, name)); - } - -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/HotSpotType.java --- a/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/HotSpotType.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,41 +0,0 @@ -/* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.runtime; - -import com.sun.cri.ri.*; - -/** - * Common interface for all HotSpot RiType-implementations. - */ -public abstract class HotSpotType extends CompilerObject implements RiType { - protected String name; - - protected HotSpotType(Compiler compiler) { - super(compiler); - } - - @Override - public final String name() { - return name; - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/HotSpotTypePrimitive.java --- a/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/HotSpotTypePrimitive.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,162 +0,0 @@ -/* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.runtime; - -import com.oracle.max.graal.compiler.util.*; -import com.sun.cri.ci.*; -import com.sun.cri.ri.*; - -/** - * Implementation of RiType for primitive HotSpot types. - */ -public final class HotSpotTypePrimitive extends HotSpotType { - - private CiKind kind; - - - HotSpotTypePrimitive(Compiler compiler, CiKind kind) { - super(compiler); - this.kind = kind; - this.name = kind.toString(); - } - - @Override - public int accessFlags() { - return kind.toJavaClass().getModifiers(); - } - - @Override - public RiType arrayOf() { - return compiler.getVMEntries().getPrimitiveArrayType(kind); - } - - @Override - public RiType componentType() { - return null; - } - - @Override - public RiType exactType() { - return this; - } - - @Override - public RiType superType() { - return null; - } - - @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(CiConstant 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 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; - } - - @Override - public RiMethod uniqueConcreteMethod(RiMethod method) { - return null; - } - - @Override - public RiField[] fields() { - return null; - } - - @Override - public RiMethod getMethod(String name, String signature) { - return null; - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/HotSpotTypeResolved.java --- a/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/HotSpotTypeResolved.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,38 +0,0 @@ -/* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.runtime; - -import com.oracle.max.graal.runtime.server.*; -import com.sun.cri.ri.*; - -public interface HotSpotTypeResolved extends RiType, Remote { - - String toString(); - - RiConstantPool constantPool(); - - int instanceSize(); - - RiField createRiField(String name, RiType type, int offset, int flags); - -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/HotSpotTypeResolvedImpl.java --- a/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/HotSpotTypeResolvedImpl.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,238 +0,0 @@ -/* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.runtime; - -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. - */ -public final class HotSpotTypeResolvedImpl extends HotSpotType implements HotSpotTypeResolved { - - private Class javaMirror; - private String simpleName; - private int accessFlags; - private boolean hasFinalizer; - private boolean hasSubclass; - private boolean hasFinalizableSubclass; - private boolean isArrayClass; - private boolean isInstanceClass; - private boolean isInterface; - private int instanceSize; - private RiType componentType; - private HashMap fieldCache; - private RiConstantPool pool; - private RiType superType; - private boolean superTypeSet; - private RiField[] fields; - - private HotSpotTypeResolvedImpl() { - super(null); - } - - @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 superType() { - if (!superTypeSet) { - superType = compiler.getVMEntries().RiType_superType(this); - superTypeSet = true; - } - return superType; - } - - @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(javaMirror); - case ObjectHub: - return CiConstant.forObject(this); - case StaticFields: - return CiConstant.forObject(javaMirror); - 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 compiler.getVMEntries().RiType_isInitialized(this); - } - - @Override - public boolean isInstance(CiConstant 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 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>"; - } - - @Override - public RiConstantPool constantPool() { - // TODO: Implement constant pool without the need for VmId and cache the constant pool. - return compiler.getVMEntries().RiType_constantPool(this); - } - - @Override - public int instanceSize() { - return instanceSize; - } - - @Override - public RiField createRiField(String name, RiType type, int offset, int flags) { - RiField result = null; - - long id = offset + ((long) flags << 32); - - // (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(id); - } - - if (result == null) { - result = new HotSpotField(compiler, this, name, type, offset, flags); - fieldCache.put(id, result); - } else { - assert result.name().equals(name); - assert result.accessFlags() == flags; - } - - return result; - } - - @Override - public RiMethod uniqueConcreteMethod(RiMethod method) { - assert method instanceof HotSpotMethodResolved; - return ((HotSpotMethodResolved) method).uniqueConcreteMethod(); - } - - @Override - public RiField[] fields() { - if (fields == null) { - fields = compiler.getVMEntries().RiType_fields(this); - } - return fields; - } - - @Override - public RiMethod getMethod(String name, String signature) { - return compiler.getVMEntries().RiType_resolveMethodImpl(this, name, signature); - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/HotSpotTypeUnresolved.java --- a/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/HotSpotTypeUnresolved.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,213 +0,0 @@ -/* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.runtime; - -import com.sun.cri.ci.*; -import com.sun.cri.ri.*; - -/** - * Implementation of RiType for unresolved HotSpot classes. - */ -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(Compiler compiler, String name) { - super(compiler); - 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(Compiler compiler, String name, int dimensions) { - super(compiler); - 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(name.length() + dimensions + 2); - for (int i = 0; i < dimensions; i++) { - str.append('['); - } - str.append('L').append(name).append(';'); - return str.toString(); - } - - @Override - public RiType uniqueConcreteSubtype() { - throw unresolved("uniqueConcreteSubtype"); - } - - @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(CiConstant obj) { - throw unresolved("isInstance()"); - } - - @Override - public RiType componentType() { - assert isArrayClass() : "no array class" + name(); - return new HotSpotTypeUnresolved(compiler, simpleName, dimensions - 1); - } - - @Override - public RiType exactType() { - throw unresolved("exactType()"); - } - - @Override - public RiType superType() { - throw unresolved("superType()"); - } - - @Override - public RiType arrayOf() { - return new HotSpotTypeUnresolved(compiler, 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; - } - - @Override - public RiMethod uniqueConcreteMethod(RiMethod method) { - throw unresolved("uniqueConcreteMethod"); - } - - @Override - public RiField[] fields() { - return null; - } - - @Override - public RiMethod getMethod(String name, String signature) { - return null; - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/HotSpotVMConfig.java --- a/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/HotSpotVMConfig.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,119 +0,0 @@ -/* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.runtime; - -import com.sun.cri.ci.*; - -/** - * Used to communicate configuration details, runtime offsets, etc. to graal upon compileMethod. - */ -public final class HotSpotVMConfig extends CompilerObject { - - private HotSpotVMConfig() { - super(null); - } - - // 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 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 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/HotSpotXirGenerator.java --- a/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/HotSpotXirGenerator.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1423 +0,0 @@ -/* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.runtime; - -import static com.oracle.max.graal.runtime.TemplateFlag.*; -import static com.sun.cri.ci.CiCallingConvention.Type.*; - -import java.lang.reflect.*; -import java.util.*; -import java.util.concurrent.*; - -import com.oracle.max.asm.target.amd64.*; -import com.sun.cri.ci.CiAddress.Scale; -import com.sun.cri.ci.*; -import com.sun.cri.ci.CiRegister.RegisterFlag; -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; - -public class HotSpotXirGenerator implements RiXirGenerator { - - // this needs to correspond to graal_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 final Compiler compiler; - - private CiXirAssembler globalAsm; - - public HotSpotXirGenerator(HotSpotVMConfig config, CiTarget target, RiRegisterConfig registerConfig, Compiler compiler) { - this.config = config; - this.target = target; - this.registerConfig = registerConfig; - this.compiler = compiler; - } - - 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, false); - 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 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.rax, AMD64.rbx); - useRegisters(asm, getGeneralParameterRegister(0)); - useRegisters(asm, getGeneralParameterRegister(1)); - 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 CiRegister getGeneralParameterRegister(int index) { - return registerConfig.getCallingConventionRegisters(CiCallingConvention.Type.RuntimeCall, RegisterFlag.CPU)[index]; - } - - 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.rax, AMD64.rbx); - useRegisters(asm, getGeneralParameterRegister(0)); - useRegisters(asm, getGeneralParameterRegister(1)); - 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) { - - @Override - protected XirTemplate create(CiXirAssembler asm, long flags, CiKind kind) { - XirOperand result = asm.restart(kind); - XirParameter object = asm.createInputParameter("object", CiKind.Object); - - 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) { - - @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); - 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) && kind == CiKind.Object) { - 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 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() { - - @Override - protected XirTemplate create(CiXirAssembler asm, long flags) { - emitNewTypeArray(asm, flags, CiKind.Object, config.useFastNewObjectArray, config.newObjectArrayStub); - return asm.finishTemplate("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); - - 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); - } - } - - 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() { - - @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); - } - - asm.mov(hub, asm.createConstantInputParameter("hub", CiKind.Object)); - - asm.mov(rank, asm.i(dimensions)); - useRegisters(asm, AMD64.rax); - asm.callRuntime(config.newMultiArrayStub, result); - return asm.finishTemplate("multiNewArray" + dimensions); - } - }; - - private SimpleTemplates checkCastTemplates = new SimpleTemplates(NULL_CHECK) { - - @Override - protected XirTemplate create(CiXirAssembler asm, long flags) { - asm.restart(); - XirParameter object = asm.createInputParameter("object", CiKind.Object); - final XirOperand hub; - hub = asm.createConstantInputParameter("hub", CiKind.Object); - - 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.Word, AMD64.r10); - asm.mov(scratch, asm.createConstant(CiConstant.forWord(2))); - - asm.callRuntime(CiRuntimeCall.Deoptimize, null); - asm.shouldNotReachHere(); - - return asm.finishTemplate(object, "checkcast"); - } - }; - - private SimpleTemplates instanceOfTemplates = new SimpleTemplates(NULL_CHECK) { - - @Override - protected XirTemplate create(CiXirAssembler asm, long flags) { - asm.restart(CiKind.Void); - XirParameter object = asm.createInputParameter("object", CiKind.Object); - final XirOperand hub; - hub = asm.createConstantInputParameter("hub", CiKind.Object); - - XirOperand objHub = asm.createTemp("objHub", CiKind.Object); - - XirLabel slowPath = asm.createOutOfLineLabel("slow path"); - XirLabel trueSucc = asm.createInlineLabel(XirLabel.TrueSuccessor); - XirLabel falseSucc = asm.createInlineLabel(XirLabel.FalseSuccessor); - - if (is(NULL_CHECK, flags)) { - // null isn't "instanceof" anything - asm.jeq(falseSucc, object, asm.o(null)); - } - - asm.pload(CiKind.Object, objHub, object, asm.i(config.hubOffset), false); - // if we get an exact match: succeed immediately - asm.jeq(trueSucc, objHub, hub); - asm.jmp(slowPath); - - // -- out of line ------------------------------------------------------- - asm.bindOutOfLine(slowPath); - checkSubtype(asm, objHub, objHub, hub); - asm.jeq(falseSucc, objHub, asm.o(null)); - asm.jmp(trueSucc); - - return asm.finishTemplate("instanceof"); - } - }; - - private SimpleTemplates materializeInstanceOfTemplates = 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); - final XirOperand hub; - hub = asm.createConstantInputParameter("hub", CiKind.Object); - - XirOperand objHub = asm.createTemp("objHub", CiKind.Object); - - XirLabel slowPath = asm.createOutOfLineLabel("slow path"); - XirLabel trueSucc = asm.createInlineLabel("ok"); - XirLabel falseSucc = asm.createInlineLabel("ko"); - XirLabel end = asm.createInlineLabel("end"); - - if (is(NULL_CHECK, flags)) { - // null isn't "instanceof" anything - asm.jeq(falseSucc, object, asm.o(null)); - } - - asm.pload(CiKind.Object, objHub, object, asm.i(config.hubOffset), false); - // if we get an exact match: succeed immediately - asm.jeq(trueSucc, objHub, hub); - asm.jmp(slowPath); - - asm.bindInline(trueSucc); - asm.mov(result, asm.i(1)); - asm.jmp(end); - asm.bindInline(falseSucc); - asm.mov(result, asm.i(0)); - asm.bindInline(end); - - // -- out of line ------------------------------------------------------- - asm.bindOutOfLine(slowPath); - checkSubtype(asm, objHub, objHub, hub); - asm.jeq(falseSucc, objHub, asm.o(null)); - asm.jmp(trueSucc); - - return asm.finishTemplate("instanceof"); - } - }; - - private XirOperand genArrayLength(CiXirAssembler asm, 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(asm, 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); - XirOperand scratch = asm.createRegisterTemp("scratch", CiKind.Word, AMD64.r10); - asm.mov(scratch, asm.createConstant(CiConstant.forWord(0))); - asm.callRuntime(CiRuntimeCall.Deoptimize, 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); - if (is(NULL_CHECK, flags)) { - asm.nop(1); - } - 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("getClass"); - } - }; - - 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) && kind == CiKind.Object) { - 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)); - XirOperand scratch = asm.createRegisterTemp("scratch", CiKind.Word, AMD64.r10); - asm.mov(scratch, asm.createConstant(CiConstant.forWord(0))); - asm.callRuntime(CiRuntimeCall.Deoptimize, 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.nop(1); - 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.nop(1); - 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) && kind == CiKind.Object) { - 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); - XirOperand scratch = asm.createRegisterTemp("scratch", CiKind.Word, AMD64.r10); - asm.mov(scratch, asm.createConstant(CiConstant.forWord(0))); - asm.callRuntime(CiRuntimeCall.Deoptimize, 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)); - XirOperand scratch = asm.createRegisterTemp("scratch", CiKind.Word, AMD64.r10); - asm.mov(scratch, asm.createConstant(CiConstant.forWord(0))); - asm.callRuntime(CiRuntimeCall.Deoptimize, null); - asm.shouldNotReachHere(); - } - 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"); - } - }; - - private SimpleTemplates typeCheckTemplates = new SimpleTemplates(NULL_CHECK) { - @Override - protected XirTemplate create(CiXirAssembler asm, long flags) { - asm.restart(); - XirParameter object = asm.createInputParameter("object", CiKind.Object); - XirOperand hub = asm.createConstantInputParameter("hub", CiKind.Object); - - XirOperand objHub = asm.createTemp("objHub", CiKind.Object); - - XirLabel slowPath = asm.createOutOfLineLabel("deopt"); - - if (is(NULL_CHECK, flags)) { - asm.nop(1); - asm.mark(MARK_IMPLICIT_NULL); - } - - asm.pload(CiKind.Object, objHub, object, asm.i(config.hubOffset), false); - // if we get an exact match: continue - asm.jneq(slowPath, objHub, hub); - - // -- out of line ------------------------------------------------------- - asm.bindOutOfLine(slowPath); - XirOperand scratch = asm.createRegisterTemp("scratch", CiKind.Word, AMD64.r10); - asm.mov(scratch, asm.createConstant(CiConstant.forWord(2))); - - asm.callRuntime(CiRuntimeCall.Deoptimize, null); - asm.shouldNotReachHere(); - - return asm.finishTemplate(object, "typeCheck"); - } - }; - - @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) { - throw new CiBailout("Xir ResolveClass not available"); - } - - @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) { - assert field.isResolved(); - return new XirSnippet(getFieldTemplates.get(site, field.kind()), object, XirArgument.forInt(((HotSpotField) field).offset())); - } - - @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) { - assert field.isResolved(); - return new XirSnippet(putFieldTemplates.get(site, field.kind()), object, value, XirArgument.forInt(((HotSpotField) field).offset())); - } - - @Override - public XirSnippet genGetStatic(XirSite site, XirArgument object, RiField field) { - assert field.isResolved(); - return new XirSnippet(getFieldTemplates.get(site, field.kind()), object, XirArgument.forInt(((HotSpotField) field).offset())); - } - - @Override - public XirSnippet genPutStatic(XirSite site, XirArgument object, RiField field, XirArgument value) { - assert field.isResolved(); - return new XirSnippet(putFieldTemplates.get(site, field.kind()), object, value, XirArgument.forInt(((HotSpotField) field).offset())); - } - - @Override - public XirSnippet genNewInstance(XirSite site, RiType type) { - assert type.isResolved(); - int instanceSize = ((HotSpotTypeResolved) type).instanceSize(); - return new XirSnippet(newInstanceTemplates.get(site, instanceSize), XirArgument.forObject(type)); - } - - @Override - public XirSnippet genNewArray(XirSite site, XirArgument length, CiKind elementKind, RiType componentType, RiType arrayType) { - if (elementKind == CiKind.Object) { - assert arrayType.isResolved(); - return new XirSnippet(newObjectArrayTemplates.get(site), length, XirArgument.forObject(arrayType)); - } - 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) { - assert type.isResolved(); - XirArgument[] params = Arrays.copyOf(lengths, lengths.length + 1); - params[lengths.length] = XirArgument.forObject(type); - return new XirSnippet(multiNewArrayTemplate.get(site, lengths.length), params); - } - - @Override - public XirSnippet genCheckCast(XirSite site, XirArgument receiver, XirArgument hub, RiType type) { - return new XirSnippet(checkCastTemplates.get(site), receiver, hub); - } - - @Override - public XirSnippet genInstanceOf(XirSite site, XirArgument object, XirArgument hub, RiType type) { - assert type.isResolved(); - return new XirSnippet(instanceOfTemplates.get(site), object, hub); - } - - @Override - public XirSnippet genMaterializeInstanceOf(XirSite site, XirArgument object, XirArgument hub, RiType type) { - assert type.isResolved(); - return new XirSnippet(materializeInstanceOfTemplates.get(site), object, hub); - } - - @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 XirSnippet genTypeCheck(XirSite site, XirArgument object, XirArgument hub, RiType type) { - assert type.isResolved(); - return new XirSnippet(typeCheckTemplates.get(site), object, hub); - } - - @Override - public List buildTemplates(CiXirAssembler asm) { - this.globalAsm = asm; - List templates = new ArrayList(); - return templates; - } - - 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.globalAsm.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 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/InvocationSocket.java --- a/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/InvocationSocket.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,276 +0,0 @@ -/* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.runtime; - -import java.io.*; -import java.lang.reflect.*; -import java.util.*; - -import com.oracle.max.graal.runtime.logging.*; - -/** - * A collection of java.lang.reflect proxies that communicate 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. - */ -public class InvocationSocket { - - private static final boolean DEBUG = false; - private static final boolean COUNT_CALLS = false; - - private static final HashSet cachedMethodNames = new HashSet(); - private static final HashSet forbiddenMethodNames = new HashSet(); - - static { - cachedMethodNames.add("name"); - cachedMethodNames.add("kind"); - cachedMethodNames.add("isResolved"); - cachedMethodNames.add("getVMEntries"); - cachedMethodNames.add("exactType"); - cachedMethodNames.add("isInitialized"); - forbiddenMethodNames.add("javaClass"); - } - - private final ObjectOutputStream output; - private final ObjectInputStream input; - - private final Map counts = new HashMap(); - - public InvocationSocket(ObjectOutputStream output, ObjectInputStream input) { - this.output = output; - this.input = input; - - if (COUNT_CALLS) { - Runtime.getRuntime().addShutdownHook(new Thread() { - @Override - public void run() { - SortedMap sorted = new TreeMap(); - for (Map.Entry entry : counts.entrySet()) { - sorted.put(entry.getValue(), entry.getKey()); - } - for (Map.Entry entry : sorted.entrySet()) { - System.out.println(entry.getKey() + ": " + entry.getValue()); - } - } - }); - } - } - - /** - * Represents one invocation of a method that is transferred via the socket connection. - * - * @author Lukas Stadler - */ - private static class Invocation implements Serializable { - - public Object receiver; - public String methodName; - public Object[] args; - - public Invocation(Object receiver, String methodName, Object[] args) { - this.receiver = receiver; - this.methodName = methodName; - this.args = args; - } - } - - /** - * Represents the result of an invocation that is transferred via the socket connection. - * - * @author Lukas Stadler - */ - private static class Result implements Serializable { - - public Object result; - - public Result(Object result) { - this.result = result; - } - } - - private void incCount(String name, Object[] args) { - if (COUNT_CALLS) { - name = name + (args == null ? 0 : args.length); - if (counts.get(name) != null) { - counts.put(name, counts.get(name) + 1); - } else { - counts.put(name, 1); - } - } - } - - /** - * Each instance of this class handles remote invocations for one instance of a Remote class. It will forward all - * interface methods to the other end of the socket and cache the results of calls to certain methods. - * - * @author Lukas Stadler - */ - public class Handler implements InvocationHandler { - - private final Object receiver; - private final HashMap cache = new HashMap(); - - public Handler(Object receiver) { - this.receiver = receiver; - } - - @Override - public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { - // only interface methods can be transferred, java.lang.Object methods - if (method.getDeclaringClass() == Object.class) { - return method.invoke(receiver, args); - } - String methodName = method.getName(); - // check if the result of this zero-arg method was cached - if (args == null || args.length == 0) { - if (cache.containsKey(methodName)) { - return cache.get(methodName); - } - } - if (forbiddenMethodNames.contains(methodName)) { - throw new IllegalAccessException(methodName + " not allowed"); - } - Object result = null; - try { - if (DEBUG) { - Logger.startScope("invoking remote " + methodName); - } - incCount(methodName, args); - - output.writeObject(new Invocation(receiver, methodName, args)); - output.flush(); - result = waitForResult(false); - - // result caching for selected methods - if ((args == null || args.length == 0) && cachedMethodNames.contains(methodName)) { - cache.put(methodName, result); - } - return result; - } catch (Throwable t) { - t.printStackTrace(); - throw t; - } finally { - if (DEBUG) { - Logger.endScope(" = " + result); - } - } - } - } - - /** - * Waits for the result of a remote method invocation. Invocations that should be executed in this VM might arrive - * while waiting for the result, and these invocations will be executed before again waiting fort he result. - */ - public Object waitForResult(boolean eofExpected) throws IOException, ClassNotFoundException { - while (true) { - Object in; - try { - in = input.readObject(); - } catch (EOFException e) { - if (eofExpected) { - return null; - } - throw e; - } - 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 (Class clazz = invoke.receiver.getClass(); clazz != null; clazz = clazz.getSuperclass()) { - for (Method m : clazz.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 = null; - try { - if (invoke.args == null) { - if (DEBUG) { - Logger.startScope("invoking local " + invoke.methodName); - } - result = method.invoke(invoke.receiver); - } else { - if (Logger.ENABLED && DEBUG) { - StringBuilder str = new StringBuilder(); - str.append("invoking local " + invoke.methodName + "("); - for (int i = 0; i < invoke.args.length; i++) { - str.append(i == 0 ? "" : ", "); - str.append(Logger.pretty(invoke.args[i])); - } - str.append(")"); - Logger.startScope(str.toString()); - } - result = method.invoke(invoke.receiver, 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 { - if (DEBUG) { - if (result instanceof Result) { - Logger.endScope(" = " + ((Result) result).result); - } else { - Logger.endScope(" = " + result); - } - } - } - output.writeObject(result); - output.flush(); - } - } - } - - /** - * Sends a result without invoking a method, used by CompilationServer startup code. - */ - public void sendResult(Object obj) throws IOException { - output.writeObject(new Result(obj)); - output.flush(); - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/TemplateFlag.java --- a/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/TemplateFlag.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,36 +0,0 @@ -/* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.runtime; - -enum TemplateFlag { - NULL_CHECK, 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 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/VMEntries.java --- a/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/VMEntries.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,109 +0,0 @@ -/* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package com.oracle.max.graal.runtime; - -import com.sun.cri.ci.*; -import com.sun.cri.ri.*; - -/** - * Entries into the HotSpot VM from Java code. - */ -public interface VMEntries { - - // Checkstyle: stop - - byte[] RiMethod_code(HotSpotMethodResolved method); - - String RiMethod_signature(HotSpotMethodResolved method); - - RiExceptionHandler[] RiMethod_exceptionHandlers(HotSpotMethodResolved method); - - boolean RiMethod_hasBalancedMonitors(HotSpotMethodResolved method); - - RiMethod RiMethod_uniqueConcreteMethod(HotSpotMethodResolved method); - - int RiMethod_invocationCount(HotSpotMethodResolved method); - - int RiMethod_exceptionProbability(HotSpotMethodResolved method, int bci); - - RiTypeProfile RiMethod_typeProfile(HotSpotMethodResolved method, int bci); - - double RiMethod_branchProbability(HotSpotMethodResolved method, int bci); - - double[] RiMethod_switchProbability(HotSpotMethodResolved method, int bci); - - 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(); - - 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); - - boolean RiType_isInitialized(HotSpotTypeResolved klass); - - RiType getType(Class javaClass); - - void recordBailout(String reason); - - RiType RiType_uniqueConcreteSubtype(HotSpotTypeResolved klass); - - RiType RiType_superType(HotSpotTypeResolved klass); - - int getArrayLength(CiConstant array); - - boolean compareConstantObjects(CiConstant x, CiConstant y); - - RiType getRiType(CiConstant constant); - - RiField[] RiType_fields(HotSpotTypeResolved klass); - - boolean RiMethod_hasCompiledCode(HotSpotMethodResolved method); - - int RiMethod_compiledCodeSize(HotSpotMethodResolved method); - - // Checkstyle: resume -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/VMEntriesNative.java --- a/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/VMEntriesNative.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,157 +0,0 @@ -/* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package com.oracle.max.graal.runtime; - -import java.lang.reflect.*; - -import com.oracle.max.graal.runtime.server.*; -import com.sun.cri.ci.*; -import com.sun.cri.ri.*; - -/** - * Entries into the HotSpot VM from Java code. - */ -public class VMEntriesNative implements VMEntries, Remote { - - // Checkstyle: stop - @Override - public native byte[] RiMethod_code(HotSpotMethodResolved method); - - @Override - public native String RiMethod_signature(HotSpotMethodResolved method); - - @Override - public native RiExceptionHandler[] RiMethod_exceptionHandlers(HotSpotMethodResolved method); - - @Override - public native boolean RiMethod_hasBalancedMonitors(HotSpotMethodResolved method); - - @Override - public native RiMethod RiMethod_uniqueConcreteMethod(HotSpotMethodResolved method); - - @Override - public native int RiMethod_invocationCount(HotSpotMethodResolved method); - - @Override - public native int RiMethod_exceptionProbability(HotSpotMethodResolved method, int bci); - - @Override - public native RiTypeProfile RiMethod_typeProfile(HotSpotMethodResolved method, int bci); - - @Override - public native double RiMethod_branchProbability(HotSpotMethodResolved method, int bci); - - @Override - public native double[] RiMethod_switchProbability(HotSpotMethodResolved method, int bci); - - @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 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 RiType_superType(HotSpotTypeResolved klass); - - @Override - public native boolean RiType_isInitialized(HotSpotTypeResolved klass); - - @Override - public native RiType getType(Class javaClass); - - @Override - public native void recordBailout(String reason); - - @Override - public int getArrayLength(CiConstant array) { - return Array.getLength(array.asObject()); - } - - @Override - public boolean compareConstantObjects(CiConstant x, CiConstant y) { - return x.asObject() == y.asObject(); - } - - @Override - public RiType getRiType(CiConstant constant) { - Object o = constant.asObject(); - if (o == null) { - return null; - } - return getType(o.getClass()); - } - - @Override - public native RiField[] RiType_fields(HotSpotTypeResolved klass); - - @Override - public native boolean RiMethod_hasCompiledCode(HotSpotMethodResolved method); - - @Override - public native int RiMethod_compiledCodeSize(HotSpotMethodResolved method); - - // Checkstyle: resume -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/VMExits.java --- a/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/VMExits.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,61 +0,0 @@ -/* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package com.oracle.max.graal.runtime; - -import com.sun.cri.ci.*; -import com.sun.cri.ri.*; - -/** - * Exits from the HotSpot VM into Java code. - */ -public interface VMExits { - - void compileMethod(HotSpotMethodResolved method, int entryBCI) throws Throwable; - - RiMethod createRiMethodUnresolved(String name, String signature, RiType holder); - - RiSignature createRiSignature(String signature); - - RiField createRiField(RiType holder, String name, RiType type, int offset, int flags); - - 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); - - void shutdownCompiler() throws Throwable; - - void startCompiler(); -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/VMExitsNative.java --- a/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/VMExitsNative.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,279 +0,0 @@ -/* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package com.oracle.max.graal.runtime; - -import java.io.*; -import java.lang.management.*; -import java.util.*; - -import com.oracle.max.graal.compiler.*; -import com.oracle.max.graal.compiler.debug.*; -import com.oracle.max.graal.compiler.graph.*; -import com.oracle.max.graal.runtime.logging.*; -import com.oracle.max.graal.runtime.server.*; -import com.sun.cri.ci.*; -import com.sun.cri.ri.*; - -/** - * Exits from the HotSpot VM into Java code. - */ -public class VMExitsNative implements VMExits, Remote { - - public static final boolean LogCompiledMethods = false; - public static boolean compileMethods = true; - private static boolean PrintGCStats = false; - - private final Compiler compiler; - - public final HotSpotTypePrimitive typeBoolean; - public final HotSpotTypePrimitive typeChar; - public final HotSpotTypePrimitive typeFloat; - public final HotSpotTypePrimitive typeDouble; - public final HotSpotTypePrimitive typeByte; - public final HotSpotTypePrimitive typeShort; - public final HotSpotTypePrimitive typeInt; - public final HotSpotTypePrimitive typeLong; - public final HotSpotTypePrimitive typeVoid; - - public VMExitsNative(Compiler compiler) { - this.compiler = compiler; - - typeBoolean = new HotSpotTypePrimitive(compiler, CiKind.Boolean); - typeChar = new HotSpotTypePrimitive(compiler, CiKind.Char); - typeFloat = new HotSpotTypePrimitive(compiler, CiKind.Float); - typeDouble = new HotSpotTypePrimitive(compiler, CiKind.Double); - typeByte = new HotSpotTypePrimitive(compiler, CiKind.Byte); - typeShort = new HotSpotTypePrimitive(compiler, CiKind.Short); - typeInt = new HotSpotTypePrimitive(compiler, CiKind.Int); - typeLong = new HotSpotTypePrimitive(compiler, CiKind.Long); - typeVoid = new HotSpotTypePrimitive(compiler, CiKind.Void); - } - - private static Set compiledMethods = new HashSet(); - - public void startCompiler() { - // Make sure TTY is initialized here such that the correct System.out is used for TTY. - TTY.isSuppressed(); - } - - public void shutdownCompiler() throws Throwable { - compileMethods = false; - - new Sandbox() { - - @Override - public void run() { - if (GraalOptions.Meter) { - GraalMetrics.print(); - } - if (GraalOptions.Time) { - GraalTimers.print(); - } - if (PrintGCStats) { - printGCStats(); - } - } - }.start(); - } - - public abstract class Sandbox { - - public void start() throws Throwable { - // (ls) removed output and error stream rewiring, this influences applications and, for example, makes dacapo tests fail. -// PrintStream oldOut = System.out; -// PrintStream oldErr = System.err; - run(); -// System.setOut(oldOut); -// System.setErr(oldErr); - } - - protected abstract void run() throws Throwable; - } - - 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); - } - - @Override - public void compileMethod(final HotSpotMethodResolved method, final int entryBCI) throws Throwable { - if (!compileMethods) { - return; - } - - new Sandbox() { - @Override - public void run() throws Throwable { - try { - CiResult result = compiler.getCompiler().compileMethod(method, -1, null, null); - if (LogCompiledMethods) { - String qualifiedName = CiUtil.toJavaName(method.holder()) + "::" + method.name(); - compiledMethods.add(qualifiedName); - } - - if (result.bailout() != null) { - Throwable cause = result.bailout().getCause(); - if (!GraalOptions.QuietBailout && !(result.bailout() instanceof JSRNotSupportedBailout)) { - StringWriter out = new StringWriter(); - result.bailout().printStackTrace(new PrintWriter(out)); - TTY.println("Bailout while compiling " + method + " :\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)); - } - } - } - String s = result.bailout().getMessage(); - if (cause != null) { - s = cause.getMessage(); - } - compiler.getVMEntries().recordBailout(s); - } else { - HotSpotTargetMethod.installMethod(compiler, method, result.targetMethod()); - } - } catch (Throwable t) { - StringWriter out = new StringWriter(); - t.printStackTrace(new PrintWriter(out)); - TTY.println("Compilation interrupted: (" + method + ")\n" + out.toString()); - throw t; - } - } - }.start(); - } - - @Override - public RiMethod createRiMethodUnresolved(String name, String signature, RiType holder) { - return new HotSpotMethodUnresolved(compiler, name, signature, holder); - } - - @Override - public RiSignature createRiSignature(String signature) { - return new HotSpotSignature(compiler, signature); - } - - @Override - public RiField createRiField(RiType holder, String name, RiType type, int offset, int flags) { - if (offset != -1) { - HotSpotTypeResolved resolved = (HotSpotTypeResolved) holder; - return resolved.createRiField(name, type, offset, flags); - } - return new HotSpotField(compiler, holder, name, type, offset, flags); - } - - @Override - public RiType createRiType(long vmId, String name) { - throw new RuntimeException("not implemented"); - } - - @Override - public RiType createRiTypePrimitive(int basicType) { - switch (basicType) { - case 4: - return typeBoolean; - case 5: - return typeChar; - case 6: - return typeFloat; - case 7: - return typeDouble; - case 8: - return typeByte; - case 9: - return typeShort; - case 10: - return typeInt; - case 11: - return typeLong; - case 14: - return typeVoid; - default: - throw new IllegalArgumentException("Unknown basic type: " + basicType); - } - } - - @Override - public RiType createRiTypeUnresolved(String name) { - return new HotSpotTypeUnresolved(compiler, name); - } - - @Override - public RiConstantPool createRiConstantPool(long vmId) { - return new HotSpotConstantPool(compiler, 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 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/logging/CountingProxy.java --- a/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/logging/CountingProxy.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,102 +0,0 @@ -/* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.runtime.logging; - -import java.lang.reflect.*; -import java.util.*; - -import com.oracle.max.graal.runtime.server.*; - -/** - * A java.lang.reflect proxy that hierarchically logs all method invocations along with their parameters and return - * values. - */ -public class CountingProxy implements InvocationHandler { - - public static final boolean ENABLED = Boolean.valueOf(System.getProperty("graal.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) { - Class[] interfaces = ReplacingStreams.getAllInterfaces(delegate.getClass()); - Object obj = Proxy.newProxyInstance(interf.getClassLoader(), interfaces, 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 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/logging/Logger.java --- a/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/logging/Logger.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,170 +0,0 @@ -/* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.runtime.logging; - -import java.io.*; -import java.lang.reflect.*; -import java.util.*; - -/** - * Scoped logging class used to display the call hierarchy of VMEntries/VMExits calls. - */ -public class Logger { - - public static final boolean ENABLED = Boolean.valueOf(System.getProperty("graal.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("graal.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 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/logging/LoggingProxy.java --- a/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/logging/LoggingProxy.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,77 +0,0 @@ -/* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.runtime.logging; - -import java.lang.reflect.*; - -import com.oracle.max.graal.runtime.server.*; - -/** - * A java.lang.reflect proxy that hierarchically logs all method invocations along with their parameters and return values. - */ -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; - } - - /** - * The object returned by this method will implement all interfaces that are implemented by delegate. - */ - public static T getProxy(Class interf, T delegate) { - Class[] interfaces = ReplacingStreams.getAllInterfaces(delegate.getClass()); - Object obj = Proxy.newProxyInstance(interf.getClassLoader(), interfaces, new LoggingProxy(delegate)); - return interf.cast(obj); - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/logging/package-info.java --- a/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/logging/package-info.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,29 +0,0 @@ -/* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -/** - * Logging framework for the HotSpot CRI implementation. - * - * @author Lukas Stadler - * @author Thomas Wuerthinger - */ -package com.oracle.max.graal.runtime.logging; diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/nodes/ArrayWriteBarrier.java --- a/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/nodes/ArrayWriteBarrier.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,78 +0,0 @@ -/* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.runtime.nodes; - -import com.oracle.max.graal.graph.*; -import com.oracle.max.graal.nodes.*; -import com.oracle.max.graal.nodes.extended.*; -import com.oracle.max.graal.nodes.spi.*; -import com.sun.cri.ci.*; - - -public final class ArrayWriteBarrier extends WriteBarrier { - - @Input private ValueNode object; - @Input private LocationNode location; - - public ValueNode object() { - return object; - } - - public void setObject(ValueNode x) { - updateUsages(this.object, x); - this.object = x; - } - - public LocationNode location() { - return location; - } - - public void setLocation(LocationNode x) { - updateUsages(location, x); - location = x; - } - - public ArrayWriteBarrier(ValueNode object, LocationNode index, Graph graph) { - super(graph); - this.setObject(object); - this.setLocation(index); - } - - - @SuppressWarnings("unchecked") - @Override - public T lookup(Class clazz) { - if (clazz == LIRGeneratorOp.class) { - return (T) new LIRGeneratorOp() { - @Override - public void generate(Node n, LIRGeneratorTool generator) { - assert n == ArrayWriteBarrier.this; - CiVariable temp = generator.newVariable(CiKind.Word); - generator.emitLea(location().createAddress(generator, object()), temp); - ArrayWriteBarrier.this.generateBarrier(temp, generator); - } - }; - } - return super.lookup(clazz); - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/nodes/CurrentThread.java --- a/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/nodes/CurrentThread.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,56 +0,0 @@ -/* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.runtime.nodes; - -import com.oracle.max.asm.target.amd64.*; -import com.oracle.max.graal.graph.*; -import com.oracle.max.graal.nodes.calc.*; -import com.oracle.max.graal.nodes.spi.*; -import com.sun.cri.ci.*; - - -public final class CurrentThread extends FloatingNode { - - private int threadObjectOffset; - - public CurrentThread(int threadObjectOffset, Graph graph) { - super(CiKind.Object, graph); - this.threadObjectOffset = threadObjectOffset; - } - - @SuppressWarnings("unchecked") - @Override - public T lookup(Class clazz) { - if (clazz == LIRGeneratorOp.class) { - return (T) new LIRGeneratorOp() { - @Override - public void generate(Node n, LIRGeneratorTool generator) { - CurrentThread conv = (CurrentThread) n; - CiValue result = generator.createResultVariable(conv); - generator.emitMove(new CiAddress(CiKind.Object, AMD64.r15.asValue(CiKind.Word), threadObjectOffset), result); - } - }; - } - return super.lookup(clazz); - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/nodes/FPConversionNode.java --- a/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/nodes/FPConversionNode.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,87 +0,0 @@ -/* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.runtime.nodes; - -import com.oracle.max.graal.graph.*; -import com.oracle.max.graal.nodes.*; -import com.oracle.max.graal.nodes.calc.*; -import com.oracle.max.graal.nodes.spi.*; -import com.sun.cri.ci.*; - - -public final class FPConversionNode extends FloatingNode implements Canonicalizable { - - @Input private ValueNode value; - - public ValueNode value() { - return value; - } - - public void setValue(ValueNode x) { - updateUsages(value, x); - value = x; - } - - public FPConversionNode(CiKind kind, ValueNode value, Graph graph) { - super(kind, graph); - this.setValue(value); - } - - @SuppressWarnings("unchecked") - @Override - public T lookup(Class clazz) { - if (clazz == LIRGeneratorOp.class) { - return (T) LIRGEN; - } - return super.lookup(clazz); - } - - private static final LIRGeneratorOp LIRGEN = new LIRGeneratorOp() { - - @Override - public void generate(Node n, LIRGeneratorTool generator) { - FPConversionNode conv = (FPConversionNode) n; - CiValue reg = generator.createResultVariable(conv); - CiValue value = generator.load(conv.value()); - CiValue tmp = generator.forceToSpill(value, conv.kind, false); - generator.emitMove(tmp, reg); - } - }; - - @Override - public Node canonical(NotifyReProcess reProcess) { - if (value instanceof ConstantNode) { - CiKind fromKind = value.kind; - if (kind == CiKind.Int && fromKind == CiKind.Float) { - return ConstantNode.forInt(Float.floatToRawIntBits(((ConstantNode) value).asConstant().asFloat()), graph()); - } else if (kind == CiKind.Long && fromKind == CiKind.Double) { - return ConstantNode.forLong(Double.doubleToRawLongBits(((ConstantNode) value).asConstant().asDouble()), graph()); - } else if (kind == CiKind.Float && fromKind == CiKind.Int) { - return ConstantNode.forFloat(Float.intBitsToFloat(((ConstantNode) value).asConstant().asInt()), graph()); - } else if (kind == CiKind.Double && fromKind == CiKind.Long) { - return ConstantNode.forDouble(Double.longBitsToDouble(((ConstantNode) value).asConstant().asLong()), graph()); - } - } - return this; - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/nodes/FieldWriteBarrier.java --- a/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/nodes/FieldWriteBarrier.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,65 +0,0 @@ -/* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.runtime.nodes; - -import com.oracle.max.graal.graph.*; -import com.oracle.max.graal.nodes.*; -import com.oracle.max.graal.nodes.spi.*; -import com.sun.cri.ci.*; - - -public final class FieldWriteBarrier extends WriteBarrier { - @Input private ValueNode object; - - public ValueNode object() { - return object; - } - - public void setObject(ValueNode x) { - updateUsages(object, x); - object = x; - } - - public FieldWriteBarrier(ValueNode object, Graph graph) { - super(graph); - this.setObject(object); - } - - - @SuppressWarnings("unchecked") - @Override - public T lookup(Class clazz) { - if (clazz == LIRGeneratorOp.class) { - return (T) new LIRGeneratorOp() { - @Override - public void generate(Node n, LIRGeneratorTool generator) { - assert n == FieldWriteBarrier.this; - CiVariable temp = generator.newVariable(CiKind.Word); - generator.emitMove(generator.makeOperand(object()), temp); - FieldWriteBarrier.this.generateBarrier(temp, generator); - } - }; - } - return super.lookup(clazz); - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/nodes/UnsafeLoad.java --- a/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/nodes/UnsafeLoad.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,71 +0,0 @@ -/* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.runtime.nodes; - -import com.oracle.max.graal.graph.*; -import com.oracle.max.graal.nodes.*; -import com.oracle.max.graal.nodes.spi.*; -import com.sun.cri.ci.*; - -/** - * Load of a value from a location specified as an offset relative to an object. - */ -public class UnsafeLoad extends StateSplit { - - @Input private ValueNode object; - - @Input private ValueNode offset; - - public ValueNode object() { - return object; - } - - public void setObject(ValueNode x) { - updateUsages(object, x); - object = x; - } - - public ValueNode offset() { - return offset; - } - - public void setOffset(ValueNode x) { - updateUsages(offset, x); - offset = x; - } - - public UnsafeLoad(ValueNode object, ValueNode offset, CiKind kind, Graph graph) { - super(kind, graph); - setObject(object); - setOffset(offset); - } - - @SuppressWarnings("unchecked") - @Override - public T lookup(Class clazz) { - if (clazz == LoweringOp.class) { - return (T) DELEGATE_TO_RUNTIME; - } - return super.lookup(clazz); - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/nodes/UnsafeStore.java --- a/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/nodes/UnsafeStore.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,81 +0,0 @@ -/* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.runtime.nodes; - -import com.oracle.max.graal.graph.*; -import com.oracle.max.graal.nodes.*; -import com.oracle.max.graal.nodes.spi.*; -import com.sun.cri.ci.*; - -/** - * Store of a value at a location specified as an offset relative to an object. - */ -public class UnsafeStore extends StateSplit { - - @Input private ValueNode object; - @Input private ValueNode offset; - @Input private ValueNode value; - - public ValueNode object() { - return object; - } - - public void setObject(ValueNode x) { - updateUsages(object, x); - object = x; - } - - public ValueNode offset() { - return offset; - } - - public void setOffset(ValueNode x) { - updateUsages(offset, x); - offset = x; - } - - public ValueNode value() { - return value; - } - - public void setValue(ValueNode x) { - updateUsages(value, x); - value = x; - } - - public UnsafeStore(ValueNode object, ValueNode offset, ValueNode value, CiKind kind, Graph graph) { - super(kind, graph); - setObject(object); - setOffset(offset); - setValue(value); - } - - @SuppressWarnings("unchecked") - @Override - public T lookup(Class clazz) { - if (clazz == LoweringOp.class) { - return (T) DELEGATE_TO_RUNTIME; - } - return super.lookup(clazz); - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/nodes/WriteBarrier.java --- a/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/nodes/WriteBarrier.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,52 +0,0 @@ -/* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.runtime.nodes; - -import com.oracle.max.graal.graph.*; -import com.oracle.max.graal.nodes.*; -import com.oracle.max.graal.nodes.spi.*; -import com.oracle.max.graal.runtime.*; -import com.sun.cri.ci.*; - - -public abstract class WriteBarrier extends FixedWithNextNode { - - public WriteBarrier(Graph graph) { - super(CiKind.Illegal, graph); - } - - - protected void generateBarrier(CiValue temp, LIRGeneratorTool generator) { - HotSpotVMConfig config = CompilerImpl.getInstance().getConfig(); - generator.emitUnsignedShiftRight(temp, CiConstant.forInt(config.cardtableShift), temp, CiValue.IllegalValue); - - long startAddress = config.cardtableStartAddress; - int displacement = 0; - if (((int) startAddress) == startAddress) { - displacement = (int) startAddress; - } else { - generator.emitAdd(temp, CiConstant.forLong(config.cardtableStartAddress), temp); - } - generator.emitMove(CiConstant.FALSE, new CiAddress(CiKind.Boolean, temp, displacement)); - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/package-info.java --- a/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/package-info.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,31 +0,0 @@ -/* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -/** - * Package 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.oracle.max.graal.runtime; diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/server/CompilationServer.java --- a/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/server/CompilationServer.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,123 +0,0 @@ -/* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.runtime.server; - -import java.io.*; -import java.net.*; -import java.util.*; - -import javax.net.*; - -import com.oracle.max.graal.runtime.*; -import com.oracle.max.graal.runtime.Compiler; -import com.oracle.max.graal.runtime.logging.*; - -/** - * Server side of the client/server compilation model. The server listens for connections on the hardcoded port 1199. - * - * @author Lukas Stadler - */ -public class CompilationServer implements Runnable { - - public static void main(String[] args) throws Exception { - new CompilationServer(false).run(); - } - - public static interface ConnectionObserver { - - void connectionStarted(Compiler compiler); - - void connectionFinished(Compiler compiler); - } - - private final boolean multiple; - private final ArrayList observers = new ArrayList(); - - /** - * Creates a new Compilation server. The server is activated by calling {@link #run()} directly or via a new - * {@link Thread}. - * - * @param multiple true if the server should server should serve an infinite amount of consecutive connections, - * false if it should terminate after the first connection ends. - */ - public CompilationServer(boolean multiple) { - this.multiple = multiple; - HotSpotOptions.setDefaultOptions(); - } - - public void addConnectionObserver(ConnectionObserver observer) { - observers.add(observer); - } - - public void removeConnectionObserver(ConnectionObserver observer) { - observers.remove(observer); - } - - public void run() { - final ServerSocket serverSocket; - try { - serverSocket = ServerSocketFactory.getDefault().createServerSocket(1199); - } catch (IOException e) { - throw new RuntimeException("Couldn't create compilation server", e); - } - do { - Socket socket = null; - try { - Logger.log("Compilation server ready, waiting for client to connect..."); - socket = serverSocket.accept(); - Logger.log("Connected to " + socket.getRemoteSocketAddress()); - - ReplacingStreams streams = new ReplacingStreams(socket.getOutputStream(), socket.getInputStream()); - - // get the VMEntries proxy from the client - VMEntries entries = (VMEntries) streams.getInvocation().waitForResult(false); - - // return the initialized compiler to the client - Compiler compiler = CompilerImpl.initializeServer(entries); - compiler.getCompiler(); - streams.getInvocation().sendResult(compiler); - - for (ConnectionObserver observer : observers) { - observer.connectionStarted(compiler); - } - - streams.getInvocation().waitForResult(true); - - for (ConnectionObserver observer : observers) { - observer.connectionFinished(compiler); - } - } catch (IOException e) { - e.printStackTrace(); - } catch (ClassNotFoundException e) { - throw new RuntimeException(e); - } finally { - if (socket != null) { - try { - socket.close(); - } catch (IOException e) { - } - } - } - } while (multiple); - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/server/Remote.java --- a/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/server/Remote.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,28 +0,0 @@ -/* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.runtime.server; - - -public interface Remote { - -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/server/ReplacingStreams.java --- a/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/server/ReplacingStreams.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,228 +0,0 @@ -/* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.runtime.server; - -import java.io.*; -import java.lang.reflect.*; -import java.util.*; - -import com.oracle.max.graal.runtime.*; -import com.oracle.max.graal.runtime.Compiler; -import com.sun.cri.ci.*; - -public class ReplacingStreams { - - private IdentityHashMap objectMap = new IdentityHashMap(); - private ArrayList objectList = new ArrayList(); - - private ReplacingOutputStream output; - private ReplacingInputStream input; - - private InvocationSocket invocation; - - public ReplacingStreams(OutputStream outputStream, InputStream inputStream) throws IOException { - output = new ReplacingOutputStream(new BufferedOutputStream(outputStream)); - // required, because creating an ObjectOutputStream writes a header, but doesn't flush the stream - output.flush(); - input = new ReplacingInputStream(new BufferedInputStream(inputStream)); - invocation = new InvocationSocket(output, input); - - addStaticObject(CiValue.IllegalValue); - addStaticObject(HotSpotProxy.DUMMY_CONSTANT_OBJ); - } - - public void setInvocationSocket(InvocationSocket invocation) { - this.invocation = invocation; - } - - public ReplacingOutputStream getOutput() { - return output; - } - - public ReplacingInputStream getInput() { - return input; - } - - public InvocationSocket getInvocation() { - return invocation; - } - - private void addStaticObject(Object obj) { - int id = objectList.size(); - objectList.add(obj); - objectMap.put(obj, new Placeholder(id)); - } - - public static class Placeholder implements Serializable { - - public final int id; - - public Placeholder(int id) { - this.id = id; - } - - @Override - public String toString() { - return "#<" + id + ">"; - } - } - - public static class NewRemoteCallPlaceholder implements Serializable { - - public final Class[] interfaces; - - public NewRemoteCallPlaceholder(Class[] interfaces) { - this.interfaces = interfaces; - } - } - - public static class NewDummyPlaceholder implements Serializable { - } - - /** - * Replaces certain cir objects that cannot easily be made Serializable. - */ - public class ReplacingInputStream extends ObjectInputStream { - - private Compiler compiler; - - public ReplacingInputStream(InputStream in) throws IOException { - super(in); - enableResolveObject(true); - } - - public void setCompiler(Compiler compiler) { - this.compiler = compiler; - } - - @Override - protected Object resolveObject(Object obj) throws IOException { - // see ReplacingInputStream.replaceObject for details on when these types of objects are created - - if (obj instanceof Placeholder) { - Placeholder placeholder = (Placeholder) obj; - obj = objectList.get(placeholder.id); - return obj; - } - - if (obj instanceof NewRemoteCallPlaceholder) { - NewRemoteCallPlaceholder newPlaceholder = (NewRemoteCallPlaceholder) obj; - Placeholder placeholder = new Placeholder(objectList.size()); - obj = Proxy.newProxyInstance(getClass().getClassLoader(), newPlaceholder.interfaces, invocation.new Handler(placeholder)); - objectMap.put(obj, placeholder); - objectList.add(obj); - return obj; - } - - if (obj instanceof NewDummyPlaceholder) { - obj = new Placeholder(objectList.size()); - objectMap.put(obj, (Placeholder) obj); - objectList.add(obj); - return obj; - } - - return obj; - } - } - - /** - * Replaces certain cir objects that cannot easily be made Serializable. - */ - public class ReplacingOutputStream extends ObjectOutputStream { - - public ReplacingOutputStream(OutputStream out) throws IOException { - super(out); - enableReplaceObject(true); - } - - @Override - protected Object replaceObject(Object obj) throws IOException { - // is the object a known instance? - Placeholder placeholder = objectMap.get(obj); - if (placeholder != null) { - return placeholder; - } - - // is the object an instance of a class that will always be executed remotely? - if (obj instanceof Remote) { - return createRemoteCallPlaceholder(obj); - } - - // is the object a constant of object type? - if (obj.getClass() == CiConstant.class) { - CiConstant constant = (CiConstant) obj; - if (constant.kind != CiKind.Object) { - return obj; - } - Object contents = constant.asObject(); - if (contents == null) { - return obj; - } - // don't replace if the object already is a placeholder - if (contents instanceof Placeholder || contents instanceof Long) { - return obj; - } - placeholder = objectMap.get(contents); - if (placeholder != null) { - return CiConstant.forObject(placeholder); - } - if (contents instanceof Remote) { - return CiConstant.forObject(createRemoteCallPlaceholder(contents)); - } - return CiConstant.forObject(createDummyPlaceholder(contents)); - } - return obj; - } - } - - public static Class[] getAllInterfaces(Class clazz) { - HashSet> interfaces = new HashSet>(); - getAllInterfaces(clazz, interfaces); - return interfaces.toArray(new Class[interfaces.size()]); - } - - private static void getAllInterfaces(Class clazz, HashSet> interfaces) { - for (Class< ? > iface : clazz.getInterfaces()) { - if (!interfaces.contains(iface)) { - interfaces.add(iface); - getAllInterfaces(iface, interfaces); - } - } - if (clazz.getSuperclass() != null) { - getAllInterfaces(clazz.getSuperclass(), interfaces); - } - } - - private Object createRemoteCallPlaceholder(Object obj) { - // collect all interfaces that this object's class implements (proxies only support interfaces) - objectMap.put(obj, new Placeholder(objectList.size())); - objectList.add(obj); - return new NewRemoteCallPlaceholder(getAllInterfaces(obj.getClass())); - } - - public Object createDummyPlaceholder(Object obj) { - objectMap.put(obj, new Placeholder(objectList.size())); - objectList.add(obj); - return new NewDummyPlaceholder(); - } -} diff -r 83de46612a8d -r a97b5881c222 graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/server/package-info.java --- a/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/server/package-info.java Wed Aug 10 01:15:39 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,26 +0,0 @@ -/* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -/** - * Implementation of a compilation server socket that delegates incoming requests to Graal. - */ -package com.oracle.max.graal.runtime.server;