6
I Use This!
Inactive

News

Analyzed about 17 hours ago. based on code collected 2 days ago.
IR
Posted over 17 years ago by David Grove
Page edited by David Grove - "update class names." The optimizing compiler intermediate representation (IR) is held in an object of type IR and includes a list of ... [More] instructions. Every instruction is classified into one of the pre-defined instruction formats. Each instruction includes an operator and zero or more operands. Instructions are grouped into basic blocks; basic blocks are constrained to having control-flow instructions at their end. Basic blocks fall-through to other basic blocks or contain branch instructions that have a destination basic block label. The graph of basic blocks is held in the cfg (control-flow graph) field of IR. This section documents basic information about the intermediate instruction. For a tutorial based introduction to the material it is highly recommended that you read "Jikes RVM Optimizing Compiler Intermediate Code Representation". IR Operators The IR operators are defined by the class Operators, which in turn is automatically generated from a template by a driver. The input to the driver are two files, both called OperatorList.dat. One input file resides in $RVM_ROOT/rvm/src-generated/opt-ir and defines machine-independent operators. The other resides in $RVM_ROOT/rvm/src-generated/opt-ir/${arch} and defines machine-dependent operators, where ${arch} is the specific instruction architecture of interest. Each operator in OperatorList.dat is defined by a five-line record, consisting of: SYMBOL: a static symbol to identify the operator INSTRUCTION_FORMAT: the instruction format class that accepts this operator. TRAITS: a set of characteristics of the operator, composed with a bit-wise or (|) operator. See Operator.java for a list of valid traits. IMPLDEFS: set of registers implicitly defined by this operator; usually applies only to machine-dependent operators IMPLUSES: set of registers implicitly used by this operator; usually applies only to machine-dependent operators For example, the entry in OperatorList.dat that defines the integer addition operator is INT_ADD Binary none <blank line> <blank line> The operator for a conditional branch based on values of two references is defined by REF_IFCOMP IntIfCmp branch | conditional <blank line> <blank line> Additionally, the machine-specific OperatorList.dat file contains another line of information for use by the assembler. See the file for details. Instruction Formats Every IR instruction fits one of the pre-defined Instruction Formats. The Java package com.ibm.jikesrvm.opt.ir defines roughly 75 architecture-independent instruction formats. For each instruction format, the package includes a class that defines a set of static methods by which optimizing compiler code can access an instruction of that format. For example, INT_MOVE instructions conform to the Move instruction format. The following code fragment shows code that uses the Operators interface and the Move instruction format: X.java import com.ibm.jikesrvm.opt.ir.*; class X { void foo(Instruction s) { if (Move.conforms(s)) { // if this instruction fits the Move format RegisterOperand r1 = Move.getResult(s); Operand r2 = Move.getVal(s); System.out.println("Found a move instruction: " r1 " := " r2); } else { System.out.println(s " is not a MOVE"); } } } This example shows just a subset of the access functions defined for the Move format. Other static access functions can set each operand (in this case, Result and Val), query each operand for nullness, clear operands, create Move instructions, mutate other instructions into Move instructions, and check the index of a particular operand field in the instruction. See the Javadoc™ reference for a complete description of the API. Each fixed-length instruction format is defined in the text file $RVM_ROOT/rvm/src-generated/opt-ir/InstructionFormatList.dat. Each record in this file has four lines: NAME: the name of the instruction format SIZES: the number of operands defined, defined and used, and used SIG: a description of each operand, each description given by D/DU/U: Is this operand a def, use, or both? NAME: the unique name to identify the operand TYPE: the type of the operand (a subclass of Operand) [opt]: is this operand optional? VARSIG: a description of repeating operands, used for variable-length instructions. So for example, the record that defines the Move instruction format is Move 1 0 1 "D Result RegisterOperand" "U Val Operand" <blank line> This specifies that the Move format has two operands, one def and one use. The def is called Result and must be of type RegisterOperand. The use is called Val and must be of type Operand. A few instruction formats have variable number of operands. The format for these records is given at the top of InstructionFormatList.dat. For example, the record for the variable-length Call instruction format is: Call 1 0 3 1 U 4 "D Result RegisterOperand" \ "U Address Operand" "U Method MethodOperand" "U Guard Operand opt" "Param Operand" This record defines the Call instruction format. The second line indicates that this format always has at least 4 operands (1 def and 3 uses), plus a variable number of uses of one other type. The trailing 4 on line 2 tells the template generator to generate special constructors for cases of having 1, 2, 3, or 4 of the extra operands. Finally, the record names the Call instruction operands and constrains the types. The final line specifies the name and types of the variable-numbered operands. In this case, a Call instruction has a variable number of (use) operands called Param. Client code can access the ith parameter operand of a Call instruction s by calling Call.getParam(s,i). A number of instruction formats share operands of the same semantic meaning and name. For convenience in accessing like instruction formats, the template generator supports four common operand access types: ResultCarrier: provides access to an operand of type RegisterOperand named Result. GuardResultCarrier: provides access to an operand of type RegisterOperand named GuardResult. LocationCarrier: provides access to an operand of type LocationOperand named Location. GuardCarrier: provides access to an operand of type Operand named Guard. For example, for any instruction s that carries a Result operand (eg. Move, Binary, and Unary formats), client code can call ResultCarrier.conforms(s) and ResultCarrier.getResult(s) to access the Result operand. Finally, a note on rationale. Religious object-oriented philosophers will cringe at the InstructionFormats. Instead, all this functionality could be implemented more cleanly with a hierarchy of instruction types exploiting (multiple) inheritance. We rejected the class hierarchy approach due to efficiency concerns of frequent virtual/interface method dispatch and type checks. Recent improvements in our interface invocation sequence and dynamic type checking algorithms may alleviate some of this concern. View Online Changes between revision 3 and revision 4:  The optimizing compiler intermediate representation (IR) is held in an object of type {{OPT\_IR}} and includes a list of instructions. Every instruction is classified into one of the pre-defined instruction formats. Each instruction includes an operator and zero or more operands. Instructions are grouped into basic blocks; basic blocks are constrained to having control-flow instructions at their end. Basic blocks fall-through to other basic blocks or contain branch instructions that have a destination basic block label. The graph of basic blocks is held in the {{cfg}} (control-flow graph) field of OPT_IR.   The optimizing compiler intermediate representation (IR) is held in an object of type {{IR}} and includes a list of instructions. Every instruction is classified into one of the pre-defined instruction formats. Each instruction includes an operator and zero or more operands. Instructions are grouped into basic blocks; basic blocks are constrained to having control-flow instructions at their end. Basic blocks fall-through to other basic blocks or contain branch instructions that have a destination basic block label. The graph of basic blocks is held in the {{cfg}} (control-flow graph) field of IR.     This section documents basic information about the intermediate instruction. For a tutorial based introduction to the material it is highly recommended that you read "[Jikes RVM Optimizing Compiler Intermediate Code Representation|Presentations#ir]".     h2. IR Operators    The IR operators are defined by the class {{OPT_Operators}}, which in turn is automatically generated from a template by a driver. The input to the driver are two files, both called {{OperatorList.dat}}. One input file resides in {{$RVM_ROOT/rvm/src-generated/opt-ir}} and defines machine-independent operators. The other resides in {{$RVM_ROOT/rvm/src-generated/opt-ir/$\{arch\}}} and defines machine-dependent operators, where {{$\{arch\}}} is the specific instruction architecture of interest.   The IR operators are defined by the class {{Operators}}, which in turn is automatically generated from a template by a driver. The input to the driver are two files, both called {{OperatorList.dat}}. One input file resides in {{$RVM_ROOT/rvm/src-generated/opt-ir}} and defines machine-independent operators. The other resides in {{$RVM_ROOT/rvm/src-generated/opt-ir/$\{arch\}}} and defines machine-dependent operators, where {{$\{arch\}}} is the specific instruction architecture of interest.     Each operator in {{OperatorList.dat}} is defined by a five-line record, consisting of:  * {{SYMBOL}}: a static symbol to identify the operator  * {{INSTRUCTION_FORMAT}}: the instruction format class that accepts this operator. * {{TRAITS}}: a set of characteristics of the operator, composed with a bit-wise or (_\|_) operator. See {{OPT_Operator.java}} for a list of valid traits.   * {{TRAITS}}: a set of characteristics of the operator, composed with a bit-wise or (_\|_) operator. See {{Operator.java}} for a list of valid traits.  * {{IMPLDEFS}}: set of registers implicitly defined by this operator; usually applies only to machine-dependent operators  * {{IMPLUSES}}: set of registers implicitly used by this operator; usually applies only to machine-dependent operators     For example, the entry in {{OperatorList.dat}} that defines the integer addition operator is  {noformat}  INT_ADD  Binary  none  <blank line>  <blank line>  {noformat}  The operator for a conditional branch based on values of two references is defined by  {noformat}  REF_IFCOMP  IntIfCmp  branch | conditional  <blank line>  <blank line>  {noformat}    Additionally, the machine-specific {{OperatorList.dat}} file contains another line of information for use by the assembler. See the file for details.     h2. Instruction Formats     Every IR instruction fits one of the pre-defined _Instruction Formats_. The Java package {{com.ibm.jikesrvm.opt.ir}} defines roughly 75 architecture-independent instruction formats. For each instruction format, the package includes a class that defines a set of static methods by which optimizing compiler code can access an instruction of that format.    For example, {{INT_MOVE}} instructions conform to the {{Move}} instruction format. The following code fragment shows code that uses the {{OPT_Operators}} interface and the {{Move}} instruction format:   For example, {{INT_MOVE}} instructions conform to the {{Move}} instruction format. The following code fragment shows code that uses the {{Operators}} interface and the {{Move}} instruction format:  {code:title=X.java|borderStyle=solid}  import com.ibm.jikesrvm.opt.ir.*;  class X { void foo(OPT_Instruction s) {   void foo(Instruction s) {   if (Move.conforms(s)) { // if this instruction fits the Move format OPT_RegisterOperand r1 = Move.getResult(s);  OPT_Operand r2 = Move.getVal(s);   RegisterOperand r1 = Move.getResult(s);  Operand r2 = Move.getVal(s);   System.out.println("Found a move instruction: " r1 " := " r2);   } else {   System.out.println(s " is not a MOVE");   }   }  }  {code}  This example shows just a subset of the access functions defined for the Move format. Other static access functions can set each operand (in this case, {{Result}} and {{Val}}), query each operand for nullness, clear operands, create Move instructions, mutate other instructions into Move instructions, and check the index of a particular operand field in the instruction. See the Javadoc[™| Trademarks] reference for a complete description of the API.     Each fixed-length instruction format is defined in the text file {{$RVM_ROOT/rvm/src-generated/opt-ir/InstructionFormatList.dat}}. Each record in this file has four lines:  * {{NAME}}: the name of the instruction format  * {{SIZES}}: the number of operands defined, defined and used, and used  * {{SIG}}: a description of each operand, each description given by  ** {{D/DU/U}}: Is this operand a def, use, or both?  ** {{NAME}}: the unique name to identify the operand ** {{TYPE}}: the type of the operand (a subclass of {{OPT_Operand}}   ** {{TYPE}}: the type of the operand (a subclass of {{Operand)}}  ** {{\[opt\]}}: is this operand optional?  * {{VARSIG}}: a description of repeating operands, used for variable-length instructions.     So for example, the record that defines the {{Move}} instruction format is  {noformat}  Move  1 0 1 "D Result OPT_RegisterOperand" "U Val OPT_Operand"   "D Result RegisterOperand" "U Val Operand"  <blank line>  {noformat} This specifies that the {{Move}} format has two operands, one def and one use. The def is called {{Result}} and must be of type {{OPT_RegisterOperand}}. The use is called {{Val}} and must be of type {{OPT_Operand}}.   This specifies that the {{Move}} format has two operands, one def and one use. The def is called {{Result}} and must be of type {{RegisterOperand}}. The use is called {{Val}} and must be of type {{Operand}}.     A few instruction formats have variable number of operands. The format for these records is given at the top of {{InstructionFormatList.dat}}. For example, the record for the variable-length {{Call}} instruction format is:  {noformat}  Call  1 0 3 1 U 4 "D Result OPT_RegisterOperand" \  "U Address OPT_Operand" "U Method OPT_MethodOperand" "U Guard OPT_Operand opt"  "Param OPT_Operand"   "D Result RegisterOperand" \  "U Address Operand" "U Method MethodOperand" "U Guard Operand opt"  "Param Operand"  {noformat}  This record defines the {{Call}} instruction format. The second line indicates that this format always has at least 4 operands (1 def and 3 uses), plus a variable number of uses of one other type. The trailing 4 on line 2 tells the template generator to generate special constructors for cases of having 1, 2, 3, or 4 of the extra operands. Finally, the record names the {{Call}} instruction operands and constrains the types. The final line specifies the name and types of the variable-numbered operands. In this case, a {{Call}} instruction has a variable number of (use) operands called {{Param}}. Client code can access the ith parameter operand of a {{Call}} instruction {{s}} by calling {{Call.getParam(s,i)}}.     A number of instruction formats share operands of the same semantic meaning and name. For convenience in accessing like instruction formats, the template generator supports four common operand access types: * {{ResultCarrier}}: provides access to an operand of type {{OPT_RegisterOperand}} named {{Result}}.  * {{GuardResultCarrier}}: provides access to an operand of type {{OPT_RegisterOperand}} named {{GuardResult}}.  * {{LocationCarrier}}: provides access to an operand of type {{OPT_LocationOperand}} named {{Location}}.  * {{GuardCarrier}}: provides access to an operand of type {{OPT_Operand}} named {{Guard}}.   * {{ResultCarrier}}: provides access to an operand of type {{RegisterOperand}} named {{Result}}.  * {{GuardResultCarrier}}: provides access to an operand of type {{RegisterOperand}} named {{GuardResult}}.  * {{LocationCarrier}}: provides access to an operand of type {{LocationOperand}} named {{Location}}.  * {{GuardCarrier}}: provides access to an operand of type {{Operand}} named {{Guard}}.     For example, for any instruction {{s}} that carries a {{Result}} operand (eg. {{Move}}, {{Binary}}, and {{Unary}} formats), client code can call {{ResultCarrier.conforms(s)}} and {{ResultCarrier.getResult(s)}} to access the {{Result}} operand.     Finally, a note on rationale. Religious object-oriented philosophers will cringe at the InstructionFormats. Instead, all this functionality could be implemented more cleanly with a hierarchy of instruction types exploiting (multiple) inheritance. We rejected the class hierarchy approach due to efficiency concerns of frequent virtual/interface method dispatch and type checks. Recent improvements in our interface invocation sequence and dynamic type checking algorithms may alleviate some of this concern.    View All Revisions | Revert To Version 3 [Less]
Posted over 17 years ago by David Grove
Page edited by David Grove - "update class names." The fundamental unit for optimization in Jikes RVM is a single method. The optimization of a method consists ... [More] of a series of compiler phases performed on the method. These phases transform the IR (intermediate representation) from bytecodes through HIR (high-level intermediate representation), LIR (low-level intermediate representation), and MIR (machine intermediate representation) and finally into machine code. Various optimizing transformations are performed at each level of IR. An object of the class CompilationPlan contains all the information necessary to generate machine code for a method. An instance of this class includes, among other fields, the RVMMethod to be compiled and the array of OptimizationPlanElements which define the compilation steps. The execute method of an CompilationPlan invokes the optimizing compiler to generate machine code for the method, executing the compiler phases as listed in the plan's OptimizationPlanElements. The OptimizationPlanner class defines the standard phases used in a compilation. This class contains a static field, called masterPlan, which contains all possible OptimizationPlanElements. The structure of the master plan is a tree. Any element may either be an atomic element (a leaf of the tree), or an aggregate element (an internal node of the tree). The master plan has the following general structure: elements which convert bytecodes to HIR elements which perform optimization transformations on the HIR elements which perform optimization transformations using SSA form elements which convert HIR to LIR elements which perform optimization transformations on the LIR elements which perform optimization transformations using SSA form elements which convert LIR to MIR elements which perform optimization transformations on MIR elements which convert MIR to machine code A client (compiler driver) constructs a specific optimization plan by including all the OptimizationPlanElements contained in the master plan which are appropriate for this compilation instance. Whether or not an element should be part of a compilation plan is determined by its shouldPerform method. For each atomic element, the values in the OptOptions object are generally used to determine whether the element should be included in the compilation plan. Each aggregate element must be included when any of its component elements must be included. Each element must have a perform method defined which takes the IR as a parameter. It is expected, but not required, that the perform method will modify the IR. The perform method of an aggregate element will invoke the perform methods of its elements. Each atomic element is an object of the final class OptimizationPlanAtomicElement. The main work of this class is performed by its phase, an object of type CompilerPhase. The CompilerPhase class is not final; each phase overrides this class, in particular it overrides the perform method, which is invoked by its enclosing element's perform method. All the state associated with the element is contained in the CompilerPhase; no state is in the element. Every optimization plan consists of a selection of elements from the master plan; thus two optimization plans associated with different methods will share the same component element objects. Clearly, it is undesirable to share state associated with a particular compilation phase between two different method compilations. In order to prevent this, the perform method of an atomic element creates a new instance of its phase immediately before calling the phase's perform method. In the case where the phase contains no state the newExecution method of CompilerPhase can be overridden to return the phase itself rather than a clone of the phase View Online Changes between revision 1 and revision 2:  The fundamental unit for optimization in Jikes RVM is a single method. The optimization of a method consists of a series of compiler phases performed on the method. These phases transform the [IR] (intermediate representation) from bytecodes through HIR (high-level intermediate representation), LIR (low-level intermediate representation), and MIR (machine intermediate representation) and finally into machine code. Various optimizing transformations are performed at each level of IR.     An object of the class {{OPT\_CompilationPlan}} contains all the information necessary to generate machine code for a method. An instance of this class includes, among other fields, the {{VM\_Method}} to be compiled and the array of {{OPT\_OptimizationPlanElements}} which define the compilation steps. The {{execute}} method of an {{OPT\_CompilationPlan}} invokes the optimizing compiler to generate machine code for the method, executing the compiler phases as listed in the plan's {{OPT\_OptimizationPlanElements}}.   An object of the class {{CompilationPlan}} contains all the information necessary to generate machine code for a method. An instance of this class includes, among other fields, the {{RVMMethod}} to be compiled and the array of {{OptimizationPlanElements}} which define the compilation steps. The {{execute}} method of an {{CompilationPlan}} invokes the optimizing compiler to generate machine code for the method, executing the compiler phases as listed in the plan's {{OptimizationPlanElements}}.    The {{OPT\_OptimizationPlanner}} class defines the standard phases used in a compilation. This class contains a static field, called {{masterPlan}}, which contains all possible {{OPT\_OptimizationPlanElements}}. The structure of the master plan is a tree. Any element may either be an atomic element (a leaf of the tree), or an aggregate element (an internal node of the tree). The master plan has the following general structure:      The {{OptimizationPlanner}} class defines the standard phases used in a compilation. This class contains a static field, called {{masterPlan}}, which contains all possible {{OptimizationPlanElements}}. The structure of the master plan is a tree. Any element may either be an atomic element (a leaf of the tree), or an aggregate element (an internal node of the tree). The master plan has the following general structure:  * elements which convert bytecodes to HIR  * elements which perform optimization transformations on the HIR  ** elements which perform optimization transformations using SSA form  * elements which convert HIR to LIR  * elements which perform optimization transformations on the LIR  ** elements which perform optimization transformations using SSA form  * elements which convert LIR to MIR  * elements which perform optimization transformations on MIR  * elements which convert MIR to machine code    A client (compiler driver) constructs a specific optimization plan by including all the {{OPT\_OptimizationPlanElements}} contained in the master plan which are appropriate for this compilation instance. Whether or not an element should be part of a compilation plan is determined by its {{shouldPerform}} method. For each atomic element, the values in the {{OPT_Options}} object are generally used to determine whether the element should be included in the compilation plan. Each aggregate element must be included when any of its component elements must be included.   A client (compiler driver) constructs a specific optimization plan by including all the {{OptimizationPlanElements}} contained in the master plan which are appropriate for this compilation instance. Whether or not an element should be part of a compilation plan is determined by its {{shouldPerform}} method. For each atomic element, the values in the {{OptOptions}} object are generally used to determine whether the element should be included in the compilation plan. Each aggregate element must be included when any of its component elements must be included.     Each element must have a {{perform}} method defined which takes the IR as a parameter. It is expected, but not required, that the {{perform}} method will modify the IR. The perform method of an aggregate element will invoke the perform methods of its elements.    Each atomic element is an object of the final class {{OPT\_OptimizationPlanAtomicElement}}. The main work of this class is performed by its _phase_, an object of type {{OPT\_CompilerPhase}}. The {{OPT\_CompilerPhase}} class is not final; each phase overrides this class, in particular it overrides the {{perform}} method, which is invoked by its enclosing element's {{perform}} method. All the state associated with the element is contained in the {{OPT\_CompilerPhase}}; no state is in the element.   Each atomic element is an object of the final class {{OptimizationPlanAtomicElement}}. The main work of this class is performed by its _phase_, an object of type {{CompilerPhase}}. The {{CompilerPhase}} class is not final; each phase overrides this class, in particular it overrides the {{perform}} method, which is invoked by its enclosing element's {{perform}} method. All the state associated with the element is contained in the {{CompilerPhase}}; no state is in the element.     Every optimization plan consists of a selection of elements from the master plan; thus two optimization plans associated with different methods will share the same component element objects. Clearly, it is undesirable to share state associated with a particular compilation phase between two different method compilations. In order to prevent this, the {{perform}} method of an atomic element creates a new instance of its phase immediately before calling the phase's {{perform}} method. In the case where the phase contains no state the {{newExecution}} method of {{OPT_CompilerPhase}} can be overridden to return the phase itself rather than a clone of the phase      Every optimization plan consists of a selection of elements from the master plan; thus two optimization plans associated with different methods will share the same component element objects. Clearly, it is undesirable to share state associated with a particular compilation phase between two different method compilations. In order to prevent this, the {{perform}} method of an atomic element creates a new instance of its phase immediately before calling the phase's {{perform}} method. In the case where the phase contains no state the {{newExecution}} method of {{CompilerPhase}} can be overridden to return the phase itself rather than a clone of the phase View All Revisions | Revert To Version 1 [Less]
Posted over 17 years ago by David Grove
Page edited by David Grove - "update class names." General Architecture The goal of the baseline compiler is to efficiently generate code that is "obviously ... [More] correct." It also needs to be easy to port to a new platform and self contained (the entire baseline compiler must be included in all Jikes RVM boot images to support dynamically loading other compilers). Roughly two thirds of the baseline compiler is machine-independent. The main file is BaselineCompiler and its parent TemplateCompilerFramework. The main platform-dependent file is BaselineCompilerImpl. Baseline compilation consists of two main steps: GC map computation (discussed below) and code generation. Code generation is straightforward, consisting of a single pass through the bytecodes of the method being compiled. The compiler does not try to optimize register usage, instead the bytecode operand stack is held in memory. This leads to bytecodes that push a constant onto the stack, creating a memory write in the generated machine code. The number of memory accesses in the baseline compiler corresponds directly to the number of bytecodes. TemplateCompilerFramework contains the main code generation switch statement that invokes the appropriate emit<bytecode>_ method of BaselineCompilerImpl. GC Maps The baseline compiler computes GC maps by abstractly interpreting the bytecodes to determine which expression stack slots and local variables contain references at the start of each bytecode. There are additional compilations to handle JSRs; see the source code for details. This strategy of computing a single GC map that applies to all the internal GC points for each bytecode slightly constrains code generation. The code generator must ensure that the GC map remains valid at all GC points (including implicit GC points introduced by null pointer exceptions). It also forces the baseline compiler to report reference parameters for the various invoke bytecodes as live in the GC map for the call (because the GC map also needs to cover the various internal GC points that happen before the call is actually performed). Note that this is not an issue for the optimizing compiler which computes GC maps for each machine code instruction that is a GC point. Command-Line Options The command-line options to the baseline compiler are stored as fields in an object of type BaselineOptions; this file is mechanically generated by the build process. To add or modify the command-line options in BaselineOptions.java, you must modify either BooleanOptions.dat, or ValueOptions.dat. You should describe your desired command-line option in a format described below in the appendix; you will also find the details for the optimizing compiler's command-line options. Some options are common to both the baseline compiler and optimizing compiler. They are defined by the SharedBooleanOptions.dat and SharedValueOptions.dat files found in the rvm/src-generated/options directory. View Online Changes between revision 4 and revision 5:  h2. General Architecture     The goal of the baseline compiler is to efficiently generate code that is "obviously correct." It also needs to be easy to port to a new platform and self contained (the entire baseline compiler must be included in all Jikes RVM boot images to support dynamically loading other compilers).  Roughly two thirds of the baseline compiler is machine-independent. The main file is {{VM_BaselineCompiler}}. The main platform-dependent file is {{VM_Compiler}}.   Roughly two thirds of the baseline compiler is machine-independent. The main file is {{BaselineCompiler}} and its parent {{TemplateCompilerFramework}}. The main platform-dependent file is {{BaselineCompilerImpl}}.    Baseline compilation consists of two main steps: GC map computation (discussed below) and code generation. Code generation is straightforward, consisting of a single pass through the bytecodes of the method being compiled. The compiler does not try to optimize register usage, instead the bytecode operand stack is held in memory. This leads to bytecodes that push a constant onto the stack, creating a memory write in the generated machine code. The number of memory accesses in the baseline compiler corressponds directly to the number of bytecodes. {{VM\_BaselineCompiler}} contains the main code generation switch statement that invokes the appropriate _{{emit\_<bytecode>}}_ method of {{VM_Compiler}}.   Baseline compilation consists of two main steps: GC map computation (discussed below) and code generation. Code generation is straightforward, consisting of a single pass through the bytecodes of the method being compiled. The compiler does not try to optimize register usage, instead the bytecode operand stack is held in memory. This leads to bytecodes that push a constant onto the stack, creating a memory write in the generated machine code. The number of memory accesses in the baseline compiler corresponds directly to the number of bytecodes. {{TemplateCompilerFramework}} contains the main code generation switch statement that invokes the appropriate {{{_}emit_<bytecode>\_}} method of {{BaselineCompilerImpl}}.     h2. GC Maps     The baseline compiler computes GC maps by abstractly interpreting the bytecodes to determine which expression stack slots and local variables contain references at the start of each bytecode. There are additional compilations to handle {{JSR{}}}s; see the source code for details. This strategy of computing a single GC map that applies to all the internal GC points for each bytecode slightly constrains code generation. The code generator must ensure that the GC map remains valid at all GC points (including implicit GC points introduced by null pointer exceptions). It also forces the baseline compiler to report reference parameters for the various {{invoke}} bytecodes as live in the GC map for the call (because the GC map also needs to cover the various internal GC points that happen before the call is actually performed). Note that this is not an issue for the optimizing compiler which computes GC maps for each machine code instruction that is a GC point.     h2. Command-Line Options     The command-line options to the baseline compiler are stored as fields in an object of type {{VM_BaselineOptions}}; this file is mechanically generated by the build process. To add or modify the command-line options in {{VM_BaselineOptions.java}}, you must modify either {{BooleanOptions.dat}}, or {{ValueOptions.dat}}. You should describe your desired command-line option in a format described below in the appendix; you will also find the details for the optimizing compiler's command-line options. Some options are common to both the baseline compiler and optimizing compiler. They are defined by the {{SharedBooleanOptions.dat}} and {{SharedValueOptions.dat}} files found in the {{rvm/src-generated/options}} directory.   The command-line options to the baseline compiler are stored as fields in an object of type {{BaselineOptions}}; this file is mechanically generated by the build process. To add or modify the command-line options in {{BaselineOptions.java}}, you must modify either {{BooleanOptions.dat}}, or {{ValueOptions.dat}}. You should describe your desired command-line option in a format described below in the appendix; you will also find the details for the optimizing compiler's command-line options. Some options are common to both the baseline compiler and optimizing compiler. They are defined by the {{SharedBooleanOptions.dat}} and {{SharedValueOptions.dat}} files found in the {{rvm/src-generated/options}} directory. View All Revisions | Revert To Version 4 [Less]
Posted over 17 years ago by David Grove
Page edited by David Grove - "fix URL for opt compiler tutorial" This page contains slides from stand-alone presentations. Some of the Publications also have ... [More] presentations associated with them. Jikes RVM Author: Ian Rogers Conference: Free and Open Source Developers' European Meeting Abstract: A short presentation on the Jikes RVM and related research in the context of open source Java. Download: PowerPoint (5.8MB) Dynamic Compilation and Adaptive Optimization in Virtual Machines Authors: ''Matthew Arnold, Stephen Fink, David Grove, and Michael Hind'' Instructor: Michael Hind Conference: ACACES'06, July 24-28, 2006 (This is an updated version of the PLDI'04 tutorial) Abstract: The past decade has witnessed the widespread adoption of programming languages designed to execute on virtual machines, such as the Java and C# programming language. However, such languages face significant performance challenges beyond those confronted by traditional languages. First, portable program representations and dynamic language features, force the deferral of most optimizations until runtime, inducing runtime optimization overhead. Second, modular program representations preclude many forms of whole-program inter-procedural optimization. Third, virtual machines incur additional costs for runtime services such as security guarantees and automatic memory management. To address these challenges, mainstream virtual machine implementations include substantial infrastructure for online profiling, dynamic compilation, and feedback-directed optimization. As a result, adaptive optimization has begun to mature as a widespread production-level technology. This course will survey the state-of-the-art in the areas of dynamic compilation and adaptive optimization in virtual machines. Dynamic compilation is the process of dynamically optimizing a portable representation, such as Java byte codes, into native code. Adaptive optimization is the online decision process that determines the overall strategy for profiling and employing dynamic compilation. In addition to surveying the state-of-the-art, and highlighting the many topics for open research in this area, this course will also debunk several misconceptions about these two topics, such as Dynamic compilers must be blazingly fast. Dynamic class loading is a fundamental roadblock to cross-method optimization. A static compiler can always get better performance than a dynamic compiler. Sophisticated profiling is too expensive to perform online. Program optimization is a dead field. Lack of a suitable infrastructure is a significant barrier to research in this area. Download: PDF (3.3MB) MMTk: The Memory Management Toolkit Presentors: ''Steve Blackburn and Perry Cheng'' Conference: ISMM'04, October 23, 2004 (ISMM'04 Tutorial) Abstract: MMTk is a framework for construction of garbage collectors within the open-source Jikes Research Virtual Machine. The tutorial was given by two of its creators. Download: PDF (325KMB) Jikes RVM Optimizing Compiler Intermediate Code Representation Presentors: Shane Brewer Event: Group presentation at University of Alberta, March 20, 2003. Download: PowerPoint (280K) or PDF (247K) The Design and Implementation of the Jikes RVM Optmizing Compiler Presentors: ''David Grove and Michael Hind'' Conference: OOPSLA '02, November 5, 2002 (OOPSLA '02 Tutorial) Abstract: The Jikes Research Virtual Machine (RVM) is a software infrastructure designed to execute Java programs typically used in programming language implementation research. The Jikes RVM is available as an open source project. The Jikes RVM provides the academic and research communities with a flexible open testbed to prototype new virtual machine technologies and experiment with various design alternatives. A large number of academic research groups have already adopted it. It runs on AIX, Linux, and OS X platforms and demonstrates industrial strength performance for many benchmark programs. The Jikes RVM includes state-of-the-art technologies for dynamic compilation, adaptive optimization, garbage collection, thread scheduling, and synchronization. This tutorial presents an overview of the Jikes RVM optimizing compiler. The first part of the tutorial covers the structure of the compiler, focusing on the requirements, goals, and design of its intermediate representation (IR). The second part of the tutorial covers some of the compiler's extensive set of analyses and optimizations, ranging from simple local analyzes to SSA-based flow-sensitive optimizations with type-based heap analysis. The last part covers the integration of the optimizing compiler into the adaptive optimization system, focusing on instrumentation compilation and feedback-directed optimizations. Specific issues to be covered include: optimizing the memory model, precise exceptions, and dynamic class loading; compiler requirements for runtime support of garbage collection maps, scheduling (yield points), exception tables, line number information; compiler/runtime system cooperation for fast object allocation and runtime services (for example dynamic type checking or invokeinterface); compiler structure for multiple platforms; tracing an interesting method (for example, one of our enumeration loops from the compiler) through key optimizations to illustrate how type analysis, inlining, scalar replacement, plus a set of traditional optimizations work together; etc. Download: gzip-compressed PostScript (2,084KB) The Design and Implementation of the Jikes RVM Optmizing Compiler Presentors: ''Stephen Fink and Michael Hind'' Conference: PLDI '02, June 16, 2002 (PLDI '02 Tutorial) Abstract: The Jikes Research Virtual Machine (RVM) is a software infrastructure designed to execute Java programs typically used in programming language implementation research. The system runs on the AIX™/PowerPC™ Linux ®/PowerPC, and Linux/IA-32 platforms and demonstrates industrial strength performance for many benchmark programs. Many academic groups have adopted the Jikes RVM as their primary research infrastructure, resulting in publications in leading conferences such as PLDI '02 and ISMM '02. In the first six months since its open source release the VM has been downloaded by over 1000 different IP addresses, including over 70 universities around the world. This two-hour tutorial presents an overview of the Jikes RVM optimizing compiler. The first part of the tutorial covers the structure of the compiler, focusing on the requirements, goals, and design of its intermediate representation (IR). The second part of the tutorial covers some of the compiler's extensive set of analyses and optimizations, ranging from simple local analyses to SSA-based flow-sensitive optimizations with type-based heap analysis. Time permitting, we will highlight the integration of the optimizing compiler into the adaptive optimization system. Download: gzip-compressed PostScript (1,055 KB) The Design and Implementation of the Jalapeño Research VM for Java Presentors: ''Dick Attanasio and Michael Hind'' Conference: International Conference on Parallel Architectures and Compilation Techniques, September 9, 2001 (PACT01 Tutorial) Abstract: The design and implementation of a high-performing Java virtual machine is a formidable task. Over the past three years IBM researchers have developed the Jalapeno research virtual machine for Java as a high-performing server platform. To address the requirements of servers, performance and scalability in particular, Jalapeño was designed from scratch to be as self-sufficient as possible. Key design features of Jalapeño include the entire VM is implemented in the Java programming language, a flexible online adaptive optimization infrastructure, implemented as concurrent Java threads, utilizes two compilers and no interpreter guided by a cost-benefit model a family of parallel, type-exact garbage collectors, a lightweight thread package with compiler-supported preemption, and an aggressive optimizing compiler with multiplel optimization levels. This full-day tutorial will share the lessons learned from the design and implementation of Jalapeño. Design decisions will be contrasted to other Java implementations. Download: All 12 sections (ZIP-compressed PostScript) (2,319K) Individual sections, all in gzip-compressed PostScript: 1. Introduction (92K) 2. VM (86K) ''Corresponding papers in IBM Systems Journal and OOPSLA '99'' 3. Exception handling (51K) 4. Dynamic Type Checking (126K) ''Corresponding paper in JVM '01'' 5. Interface invocation (216K) ''Corresponding paper in OOPSLA '01'' 6. Threading and Synchronization (35K) ''Corresponding paper in IBM Systems Journal'' 7. JNI support (58K) 8. Memory Management (126K) ''Corresponding paper in LCPC '01'' 9. Optimizing Compiler Overview (240K) ''Corresponding paper in Java&#153 Grande '99'' 10. Adaptive Optimization System (540K) ''Corresponding paper in OOPSLA '00'' 11. DejaVu (6817K) 12. References (86K) Optimizing Compilation of Java Programs (Revised version of PLDI tutorial) Presentor: ''Vivek Sarkar'' Conference: ACM Java Grande, June 2001 (Java Grande Tutorial) Download: gzip-compressed PostScript 186K Optimizing Compilation of Java Programs Presentor: ''Vivek Sarkar'' Conference: ACM Conference on Programming Languages Design and Implementation, June 2000 Download: gzip-compressed PostScript 258K Issues in High-Performance Programming in Java Authors: ''Bowen Alpern and Susan Flynn-Hummel'' Conference: High Performance Computing System, June 13th, 1999 (HPCS '99 Tutorial) Abstract: Java is a modern object-oriented type-safe programming language with automatic memory management. These features make it attractive to anyone responsible for developing and maintaining a large software project. Its multithreading support is a further inducement to those anxious to exploit parallel processing hardware. To date, however, there has been a performance penulty for using the language. For the vast majority of programming efforts, this is marginal concern at most. But, for performance programming, any degradation in performance is a potential show stopper. Java performance has improved markedly in the last year or two. The advent of a second generation of Just-In-Time (JIT) compiler technology promises to further close the performance gap between Java and traditional languages for most applications. This raises the question: will Java ever be the language of choice for performance-critical applications? Unfortunately, the jury is still out. The Java Grande forum has been established to address the problems with using Java for computationally intensive science and engineering applications. Under its auspices, a number of interesting projects are underway. Proposals for improving Java performance run a bewildering gamut from idioms to be used by the programmer, through bytecode and JIT optimization techniques, to major language changes. This tutorial will systematically identify and classify the aspects of Java that are problematic from the performance point of view. It will then chart the terrain upon which such issues might be addressed. Finally, it will survey approaches to improving Java performance. Download: PostScript file Part 1 (764K), Part 2 (656K) Link to: presentation (html) View Online Changes between revision 5 and revision 6:  This page contains slides from stand-alone presentations. Some of the [Publications] also have presentations associated with them.     {anchor:dynamic-compilation}     h2. Jikes RVM     * Author: [Ian Rogers|http://www.cs.man.ac.uk/~irogers]  * Conference: Free and Open Source Developers' European Meeting  * Abstract:  ** A short presentation on the Jikes RVM and related research in the context of open source Java.  * Download: [PowerPoint|ftp://ftp.cs.man.ac.uk/pub/apt/presentations/irogers_fosdem07.ppt] (5.8MB)     h2. Dynamic Compilation and Adaptive Optimization in Virtual Machines     * Authors: ''[Matthew Arnold|http://www.research.ibm.com/people/m/marnold], [Stephen Fink|http://www.research.ibm.com/people/s/sfink], [David Grove|http://www.research.ibm.com/people/d/dgrove], and [Michael Hind|http://www.research.ibm.com/people/h/hind]''  * Instructor: [Michael Hind|http://www.research.ibm.com/people/h/hind]  * Conference: [ACACES'06|http://www.hipeac.net/hipeac/acaces2006], July 24-28, 2006 (This is an updated version of the PLDI'04 tutorial)  * Abstract:  ** The past decade has witnessed the widespread adoption of programming languages designed to execute on virtual machines, such as the Java and C# programming language. However, such languages face significant performance challenges beyond those confronted by traditional languages. First, portable program representations and dynamic language features, force the deferral of most optimizations until runtime, inducing runtime optimization overhead. Second, modular program representations preclude many forms of whole-program inter-procedural optimization. Third, virtual machines incur additional costs for runtime services such as security guarantees and automatic memory management. To address these challenges, mainstream virtual machine implementations include substantial infrastructure for online profiling, dynamic compilation, and feedback-directed optimization. As a result, adaptive optimization has begun to mature as a widespread production-level technology.  ** This course will survey the state-of-the-art in the areas of dynamic compilation and adaptive optimization in virtual machines. Dynamic compilation is the process of dynamically optimizing a portable representation, such as Java byte codes, into native code. Adaptive optimization is the online decision process that determines the overall strategy for profiling and employing dynamic compilation. In addition to surveying the state-of-the-art, and highlighting the many topics for open research in this area, this course will also debunk several misconceptions about these two topics, such as  *** Dynamic compilers must be blazingly fast.  *** Dynamic class loading is a fundamental roadblock to cross-method optimization.  *** A static compiler can always get better performance than a dynamic compiler.  *** Sophisticated profiling is too expensive to perform online.  *** Program optimization is a dead field.  *** Lack of a suitable infrastructure is a significant barrier to research in this area.     * Download: [PDF|http://www.research.ibm.com/people/h/hind/ACACES06.pdf] (3.3MB)     {anchor:mmtk}     h2. MMTk: The Memory Management Toolkit     * Presentors: ''[Steve Blackburn|http://cs.anu.edu.au/~Steve.Blackburn] and [Perry Cheng|http://www.research.ibm.com/people/p/perryche]''  * Conference: [ISMM'04|http://www.research.ibm.com/ismm04], October 23, 2004 (ISMM'04 Tutorial)  * Abstract: MMTk is a framework for construction of garbage collectors within the open-source Jikes Research Virtual Machine. The tutorial was given by two of its creators.  * Download: [PDF|http://jikesrvm.sourceforge.net/info/talks/ISMM04-MMTk.pdf] (325KMB)     {anchor:ir}     h2. Jikes RVM Optimizing Compiler Intermediate Code Representation     * Presentors: Shane Brewer  * Event: Group presentation at University of Alberta, March 20, 2003.  * Download: [PowerPoint (280K)|http://www.cs.ualberta.ca/~amaral/courses/605-jit/jikesIR.ppt] or [PDF (247K)|http://www.ugrad.cs.ubc.ca/~cs411/2006W2/handouts/jikes-IR-shane-brewer.pdf]     {anchor:opt}     h2. The Design and Implementation of the Jikes RVM Optmizing Compiler     * Presentors: ''David Grove and Michael Hind''  * Conference: [OOPSLA '02|http://www.oopsla.org], November 5, 2002 (OOPSLA '02 Tutorial)  * Abstract:  ** The Jikes Research Virtual Machine (RVM) is a software infrastructure designed to execute Java programs typically used in programming language implementation research. The Jikes RVM is available as an open source project. The Jikes RVM provides the academic and research communities with a flexible open testbed to prototype new virtual machine technologies and experiment with various design alternatives. A large number of academic research groups have already adopted it. It runs on AIX, Linux, and OS X platforms and demonstrates industrial strength performance for many benchmark programs. The Jikes RVM includes state-of-the-art technologies for dynamic compilation, adaptive optimization, garbage collection, thread scheduling, and synchronization.  ** This tutorial presents an overview of the Jikes RVM optimizing compiler. The first part of the tutorial covers the structure of the compiler, focusing on the requirements, goals, and design of its intermediate representation (IR). The second part of the tutorial covers some of the compiler's extensive set of analyses and optimizations, ranging from simple local analyzes to SSA-based flow-sensitive optimizations with type-based heap analysis. The last part covers the integration of the optimizing compiler into the adaptive optimization system, focusing on instrumentation compilation and feedback-directed optimizations.  ** Specific issues to be covered include: optimizing the memory model, precise exceptions, and dynamic class loading; compiler requirements for runtime support of garbage collection maps, scheduling (yield points), exception tables, line number information; compiler/runtime system cooperation for fast object allocation and runtime services (for example dynamic type checking or invokeinterface); compiler structure for multiple platforms; tracing an interesting method (for example, one of our enumeration loops from the compiler) through key optimizations to illustrate how type analysis, inlining, scalar replacement, plus a set of traditional optimizations work together; etc.   * Download: [gzip-compressed PostScript|http://jikesrvm.sourceforge.net/info/talks/oopsla02-tutorial.ps.gz] (2,084KB)   * Download: [gzip-compressed PostScript|http://domino.research.ibm.com/comm/research_people.nsf/pages/dgrove.oopsla02Tutorial.html] (2,084KB)     h2. The Design and Implementation of the Jikes RVM Optmizing Compiler     * Presentors: ''Stephen Fink and Michael Hind''  * Conference: [PLDI '02|http://sunshine.cs.uni-dortmund.de/~knoop/PLDI2002/pldi2002_main.html], June 16, 2002 (PLDI '02 Tutorial)  * Abstract:  ** The Jikes Research Virtual Machine (RVM) is a software infrastructure designed to execute Java programs typically used in programming language implementation research. The system runs on the AIX™/PowerPC™ Linux ®/PowerPC, and Linux/IA-32 platforms and demonstrates industrial strength performance for many benchmark programs. Many academic groups have adopted the Jikes RVM as their primary research infrastructure, resulting in publications in leading conferences such as PLDI '02 and ISMM '02. In the first six months since its open source release the VM has been downloaded by over 1000 different IP addresses, including over 70 universities around the world.  ** This two-hour tutorial presents an overview of the Jikes RVM optimizing compiler. The first part of the tutorial covers the structure of the compiler, focusing on the requirements, goals, and design of its intermediate representation (IR). The second part of the tutorial covers some of the compiler's extensive set of analyses and optimizations, ranging from simple local analyses to SSA-based flow-sensitive optimizations with type-based heap analysis. Time permitting, we will highlight the integration of the optimizing compiler into the adaptive optimization system.  * Download: [gzip-compressed PostScript|http://jikesrvm.sourceforge.net/info/talks/pldi02-tutorial6-30-02.ps.gz] (1,055 KB)     {anchor:rvm}     h2. The Design and Implementation of the Jalapeño Research VM for Java     * Presentors: ''Dick Attanasio and Michael Hind''  * Conference: [International Conference on Parallel Architectures and Compilation Techniques|http://recerca.ac.upc.es/pact01], September 9, 2001 (PACT01 Tutorial)  * Abstract:  ** The design and implementation of a high-performing Java virtual machine is a formidable task. Over the past three years IBM researchers have developed the Jalapeno research virtual machine for Java as a high-performing server platform. To address the requirements of servers, performance and scalability in particular, Jalapeño was designed from scratch to be as self-sufficient as possible.  ** Key design features of Jalapeño include  *** the entire VM is implemented in the Java programming language,  *** a flexible online adaptive optimization infrastructure, implemented as concurrent Java threads, utilizes two compilers and no interpreter guided by a cost-benefit model  *** a family of parallel, type-exact garbage collectors,  *** a lightweight thread package with compiler-supported preemption, and  *** an aggressive optimizing compiler with multiplel optimization levels.  ** This full-day tutorial will share the lessons learned from the design and implementation of Jalapeño. Design decisions will be contrasted to other Java implementations.  * Download:  ** [All 12 sections|http://www.research.ibm.com/jalapeno/pact01-tutorial/all.ZIP] (ZIP-compressed PostScript) (2,319K)  ** Individual sections, all in gzip-compressed PostScript:  *** 1. [Introduction|http://www.research.ibm.com/jalapeno/pact01-tutorial/intro.ps.gz] (92K)  *** 2. [VM|http://www.research.ibm.com/jalapeno/pact01-tutorial/vm.ps.gz] (86K) ''Corresponding papers in [IBM Systems Journal|http://jikesrvm.sourceforge.net/info/pubs.shtml#ibmsj00] and [OOPSLA '99|http://jikesrvm.sourceforge.net/info/pubs.shtml#oopsla99_jvm]''  *** 3. [Exception handling|http://www.research.ibm.com/jalapeno/pact01-tutorial/exceptions.ps.gz] (51K)  *** 4. [Dynamic Type Checking|http://www.research.ibm.com/jalapeno/pact01-tutorial/DynamicTypeChecking.ps.gz] (126K) ''[Corresponding paper|http://www.research.ibm.com/people/d/dgrove/papers/jvm01.html] in JVM '01''  *** 5. [Interface invocation|http://www.research.ibm.com/jalapeno/pact01-tutorial/Interface.ps.gz] (216K) ''[Corresponding paper|http://www.research.ibm.com/people/d/dgrove/papers/oopsla01.html] in OOPSLA&nbsp;'01''  *** 6. [Threading and Synchronization|http://www.research.ibm.com/jalapeno/pact01-tutorial/threading.ps.gz] (35K) ''[Corresponding paper|http://jikesrvm.sourceforge.net/info/pubs.shtml#ibmsj00] in IBM Systems Journal''  *** 7. [JNI support|http://www.research.ibm.com/jalapeno/pact01-tutorial/jni.ps.gz] (58K)  *** 8. [Memory Management|http://www.research.ibm.com/jalapeno/pact01-tutorial/MemManage.ps.gz] (126K) ''[Corresponding paper|http://www.research.ibm.com/people/d/dfb/papers.html#Attanasio01Comparative] in LCPC '01''  *** 9. [Optimizing Compiler Overview|http://www.research.ibm.com/jalapeno/pact01-tutorial/optcompiler.ps.gz] (240K) ''[Corresponding paper|http://jikesrvm.sourceforge.net/info/pubs.shtml#grande99] in Java&#153 Grande '99''  *** 10. [Adaptive Optimization System|http://www.research.ibm.com/jalapeno/pact01-tutorial/AOS.ps.gz] (540K) ''[Corresponding paper|http://jikesrvm.sourceforge.net/info/pubs.shtml#oopsla00_aos] in OOPSLA '00''  *** 11. [DejaVu|http://www.research.ibm.com/jalapeno/pact01-tutorial/dejavu.ps.gz] (6817K)  *** 12. [References|http://www.research.ibm.com/jalapeno/pact01-tutorial/conc-refs.ps.gz] (86K)     h2. Optimizing Compilation of Java Programs     * (Revised version of PLDI tutorial)  * Presentor: ''Vivek Sarkar''  * Conference: ACM Java Grande, June 2001 (Java Grande Tutorial)  * Download: [gzip-compressed PostScript|http://www.research.ibm.com/jalapeno/papers/grande2001.ps.gz] 186K     h2. Optimizing Compilation of Java Programs     * Presentor: ''Vivek Sarkar''  * Conference: ACM Conference on Programming Languages Design and Implementation, June 2000  * Download: [gzip-compressed PostScript|http://www.research.ibm.com/jalapeno/papers/pldi2000.ps.gz] 258K     h2. Issues in High-Performance Programming in Java     * Authors: ''Bowen Alpern and Susan Flynn-Hummel''  * Conference: High Performance Computing System, June 13th, 1999 (HPCS '99 Tutorial)  * Abstract:  ** Java is a modern object-oriented type-safe programming language with automatic memory management. These features make it attractive to anyone responsible for developing and maintaining a large software project. Its multithreading support is a further inducement to those anxious to exploit parallel processing hardware. To date, however, there has been a performance penulty for using the language. For the vast majority of programming efforts, this is marginal concern at most. But, for performance programming, any degradation in performance is a potential show stopper.  ** Java performance has improved markedly in the last year or two. The advent of a second generation of Just-In-Time (JIT) compiler technology promises to further close the performance gap between Java and traditional languages for most applications. This raises the question: will Java ever be the language of choice for performance-critical applications?  ** Unfortunately, the jury is still out. The Java Grande forum has been established to address the problems with using Java for computationally intensive science and engineering applications. Under its auspices, a number of interesting projects are underway. Proposals for improving Java performance run a bewildering gamut from idioms to be used by the programmer, through bytecode and JIT optimization techniques, to major language changes.  ** This tutorial will systematically identify and classify the aspects of Java that are problematic from the performance point of view. It will then chart the terrain upon which such issues might be addressed. Finally, it will survey approaches to improving Java performance.  * Download: PostScript file [Part 1|http://www.research.ibm.com/jalapeno/papers/hpcs.99/hpcs99-part1.ps] (764K), [Part 2|http://www.research.ibm.com/jalapeno/papers/hpcs.99/hpcs99-part2.ps] (656K)  * Link to: [presentation|http://www.research.ibm.com/jalapeno/papers/hpcs.99/present.html] (html) View All Revisions | Revert To Version 5 [Less]
Posted over 17 years ago by Steve Blackburn
Page edited by Steve Blackburn Overview This document describes how to add a new garbage collector to Jikes RVM.  We don't address how to design a new GC algorithm, just ... [More] how to add a "new" GC to the system and then build it.  We do this by cloning an existing GC.  We leave it to you to design your own GC! Prerequisites Ensure that you have got a clean copy of the source (either a recent release or the svn head) and can correctly and successfully build one of the base garbage collectors.  There's little point in trying to build your own until you can reliably build an existing one.  I suggest you start with MarkSweep, and that you use the buildit script: $ bin/buildit <targetmachine> BaseBase MarkSweep  Then test your GC: $ bin/buildit <targetmachine> -t gctest BaseBase MarkSweep  You should have seen some output like this: test:      [echo] Test Result for [BaseBaseMarkSweep|gctest] InlineAllocation (default) : SUCCESS      [echo] Test Result for [BaseBaseMarkSweep|gctest] ReferenceTest (default) : SUCCESS      [echo] Test Result for [BaseBaseMarkSweep|gctest] ReferenceStress (default) : SUCCESS      [echo] Test Result for [BaseBaseMarkSweep|gctest] FixedLive (default) : SUCCESS      [echo] Test Result for [BaseBaseMarkSweep|gctest] LargeAlloc (default) : SUCCESS      [echo] Test Result for [BaseBaseMarkSweep|gctest] Exhaust (default) : SUCCESS   If this is not working, you should probably go and (re) read the section in the user guide on how to build and run the VM. Cloning the MarkSweep GC  The best way to do this is in eclipse or a similar tool (see here for how to work with eclipse): Clone the org.mmtk.plan.marksweep as org.mmtk.plan.mygc You can do this with Eclipse: Navigagte to org.mmtk.plan.marksweep (within MMTk/src) Right click over org.mmtk.plan.marksweep and select "Copy" Right click again, and select "Paste", and name the target org.mmtk.plan.mygc (or whatever you like) This will have cloned the marksweep GC in a new package called org.mmtk.plan.mygc or by hand: Copy the directory MMTk/org/mmtk/plan/marksweep to MMTk/org/mmtk/plan/mygc Edit each file within MMTk/org/mmtk/plan/mygc and change its package declaration to org.mmtk.plan.mygc We can leave the GC called "MS" for now (the file names will all be MMTk/org/mmtk/plan/mygc/MS*.java) Clone the BaseBaseMarkSweep.properties file as BaseBaseMyGC.properties: Go to build/configs, and right click over BaseBaseMarkSweep.properties, and select "Copy" Right click and select "Paste", and paste as BaseBaseMyGC.properties Edit BaseBaseMyGC.properties, changing the text: "config.mmtk.plan=org.mmtk.plan.marksweep.MS" to "config.mmtk.plan=org.mmtk.plan.mygc.MS" Now test your new GC: $ bin/buildit <targetmachine> -t gctest BaseBase MyGC You should have got similar output to your test of MarkSweep above. That's it.  You're done. Making it Prettier You may have noticed that when you cloned the package org.mmtk.plan.marksweep, all the classes retained their old names (although in your new namespace; org.mmtk.plan.mygc).  You can trivially change the class names in an IDE like eclipse.  You can do the same with your favorite text editor, but you'll need to be sure that you change the references carefully.  To change the class names in eclipse, just follow the procedure below for each class in org.mmtk.plan.mygc: Navigate to the class you want changed (eg  org.mmtk.plan.mygc.MS) Right click on the class (MS) and select "Refactor->Rename..." and then type in your new name, (eg MyGC) Do the same for each of the other classes:#* MS -> MyGC#* MSCollector -> MyGCCollector MSConstraints -> MyGCConstraints MSMutator -> MyGCMutator MSTraceLocal -> MyGCTraceLocal Edit your configuration/s to ensure they refer to the renamed classes (since your IDE is unlikely to have done this automatically for you) Go to build/configs, and edit each file *MyGC.properties Beyond BaseBaseMyGC You probably want to build with configurations other than just BaseBase.  If so, clone configurations from MarkSweep, just as you did above (for example, clone FastAdaptiveMarkSweep as FastAdaptiveMyGC). What Next? Once you have this working, you have successfully created and tested your own GC without writing a line of code!! You are ready to start the slightly more tricky process of writing your own garbage collector code. If you are writing a new GC, you should definitely be aware of the MMTk test harness, which allows you to test and debug MMTk in a very well contained pure Java environment, without the rest of Jikes RVM.  This allows you to write unit tests and corner cases, and moreover, allows you to edit and debug MMTk entirely from within your IDE View Online Changes between revision 3 and revision 4:  h1. Overview     This document describes how to add a new garbage collector to Jikes RVM.&nbsp; We don't address how to design a new GC algorithm, just how to add a "new" GC to the system and then build it.&nbsp; We do this by cloning an existing GC.&nbsp; We leave it to you to design your own GC\!     h2.        h1. Prerequisites     Ensure that you have got a clean copy of the [source|Get The Source] (either a recent release or the svn head) and can correctly and successfully build one of the base garbage collectors.&nbsp; There's little point in trying to build your own until you can reliably build an existing one.&nbsp; I suggest you start with MarkSweep, and that you use the [buildit|Using buildit] script:  {code}  $ bin/buildit <targetmachine> BaseBase MarkSweep  {code}  &nbsp;Then test your GC:  {panel}  $ bin/buildit <targetmachine> \-t gctest BaseBase MarkSweep  {panel}  &nbsp;You should have seen some output like this:  {code}  test:       [echo] Test Result for [BaseBaseMarkSweep|gctest] InlineAllocation (default) : SUCCESS       [echo] Test Result for [BaseBaseMarkSweep|gctest] ReferenceTest (default) : SUCCESS       [echo] Test Result for [BaseBaseMarkSweep|gctest] ReferenceStress (default) : SUCCESS       [echo] Test Result for [BaseBaseMarkSweep|gctest] FixedLive (default) : SUCCESS       [echo] Test Result for [BaseBaseMarkSweep|gctest] LargeAlloc (default) : SUCCESS       [echo] Test Result for [BaseBaseMarkSweep|gctest] Exhaust (default) : SUCCESS    {code}  If this is not working, you should probably go and (re) read the [section in the user guide|Care and Feeding] on how to build and run the VM.     h1. Cloning the MarkSweep GC     &nbsp;The best way to do this is in eclipse or a similar tool (see [here|Editing JikesRVM in an IDE] for how to work with eclipse):  # Navigagte to _org.mmtk.plan.marksweep_ (within _MMTk/src_)  # Right click over _org.mmtk.plan.marksweep_ and select "Copy"  # Right click again, and select "Paste", and name the target _org.mmtk.plan._{*}{_}mygc{_}* (or whatever you like)  #* This will have cloned the marksweep GC in a new package called _org.mmtk.plan.mygc_  #* We can leave the GC called org.mmtk.plan.mygc.MS for now  # Now clone the BaseBaseMarkSweep properties file:  #* Go to _build/configs_, and right click over _BaseBaseMarkSweep.properties_, and select "Copy"  #* Right click and select "Paste", and paste as _BaseBaseMyGC.properties_  #* Edit BaseBaseMyGC.properties, changing the text: "_config.mmtk.plan=org.mmtk.plan._{*}{_}marksweep{_}{*}_.MS_" to "_config.mmtk.plan=org.mmtk.plan._{*}{_}mygc{_}{*}_.MS_"   # Clone the _org.mmtk.plan.marksweep_ as _org.mmtk.plan._{*}{_}mygc{_}*  #* You can do this with *Eclipse*:     ### Navigagte to _org.mmtk.plan.marksweep_ (within _MMTk/src_)  ### Right click over _org.mmtk.plan.marksweep_ and select "Copy"  ### Right click again, and select "Paste", and name the target _org.mmtk.plan._{*}{_}mygc{_}* (or whatever you like)  ### This will have cloned the marksweep GC in a new package called _org.mmtk.plan.mygc_     #* or *by hand*:     ### Copy the directory _MMTk/org/mmtk/plan/marksweep_ to _MMTk/org/mmtk/plan/_{*}{_}mygc{_}*  ### Edit each file within _MMTk/org/mmtk/plan/_{*}{_}mygc{_}* and change its package declaration to _org.mmtk.plan._{*}{_}mygc{_}*     #* We can leave the GC called "MS" for now (the file names will all be _MMTk/org/mmtk/plan/_{*}{_}mygc{_}{*}_/MS*.java)_  # Clone the BaseBaseMarkSweep.properties file as _BaseBase{_}{*}{_}MyGC{_}{*}_.properties_:        ## Go to _build/configs_, and right click over _BaseBaseMarkSweep.properties_, and select "Copy"  ## Right click and select "Paste", and paste as _BaseBaseMyGC.properties_  ## Edit BaseBaseMyGC.properties, changing the text: "_config.mmtk.plan=org.mmtk.plan._{_}marksweep{_}_.MS_" to "_config.mmtk.plan=org.mmtk.plan._{*}{_}mygc{_}{*}_.MS_"  # Now test your new GC:     {panel}  $ bin/buildit <targetmachine> \-t gctest BaseBase *MyGC*  {panel}  You should have got similar output to your test of MarkSweep above.     That's it.&nbsp; You're done. :-)    h1. Beyond BaseBaseMyGC   h1.    You probably want to build with configurationsn other than just BaseBase.&nbsp; If so, clone configurations from MarkSweep, just as you did above (for example, clone _FastAdaptiveMarkSweep_ as _FastAdaptive{_}{*}{_}MyGC{_}*).     h1. *Making it Prettier*     You may have noticed that when you cloned the package _org.mmtk.plan.marksweep_, all the classes retained their old names (although in your new namespace; _org.mmtk.plan._{*}{_}mygc{_}*).&nbsp; You can trivially change the class names in an IDE like eclipse.&nbsp; You can do the same with your favorite text editor, but you'll need to be sure that you change the references carefully.&nbsp; To change the class names in eclipse, just follow the procedure below for each class in _org.mmtk.plan._{*}{_}mygc{_}*:  # Navigate to the class you want changed (eg&nbsp; _org.mmtk.plan._{*}{_}mygc{_}{*}_.MS)_  # Right click on the class (MS) and select _"Refactor->Rename..."_ and then type in your new name, (eg _MyGC_) # _Do the same for each of the other classes:_#* _MS \-> MyGC_  #* _MSCollector \-> MyGCCollector_   # _Do the same for each of the other classes:_\#\* _MS \-> MyGC_#* _MSCollector \-> MyGCCollector_  #* _MSConstraints \-> MyGCConstraints_  #* _MSMutator \-> MyGCMutator_  #* _MSTraceLocal \-> MyGCTraceLocal_  # Edit your configuration/s to ensure they refer to the renamed classes (since your IDE is unlikely to have done this automatically for you)  #* Go to _build/configs_, and edit each file _\*MyGC.properties_     h1.        h1. Beyond BaseBaseMyGC     You probably want to build with configurations other than just BaseBase.&nbsp; If so, clone configurations from MarkSweep, just as you did above (for example, clone _FastAdaptiveMarkSweep_ as _FastAdaptive{_}{*}{_}MyGC{_}*).     h1. What Next?     Once you have this working, you have successfully created and tested your own GC without writing a line of code\!\! You are ready to start the slightly more tricky process of writing your own garbage collector code.     If you are writing a new GC, you should definitely be aware of the MMTk [test harness|The MMTk Test Harness], which allows you to test and debug MMTk in a very well contained pure Java environment, without the rest of Jikes RVM.&nbsp; This allows you to write unit tests and corner cases, and moreover, allows you to edit and debug MMTk entirely from within your IDE  \\ View All Revisions | Revert To Version 3 [Less]
Posted over 17 years ago by Steve Blackburn
Page edited by Steve Blackburn The following sections give a rough overview on existing coding conventions. Coding Style Coding Conventions WarningJikes RVM is a ... [More] bleeding-edge research project. You will find that some of the code does not live up to product quality standards. Don't hesitate to help rectify this by contributing clean-ups, bug fixes, and missing documentation to the project. We are in the process of consolidating and simplifying the codebase at the moment. One goal of the JikesRVM project over recent years has been the ability to develop JikesRVM in a development environment such as Eclipse.  This has been possible for the MMTk component since 2005, and as of early 2007 (release 2.9.0) it is possible to work with the majority of the JikesRVM codebase in Eclipse and similar environments.  This is not yet as straightforward as we would like, and can be expected to improve with time. Editing JikesRVM in an IDE Compiler DNA Adding a New GC View Online Changes between revision 6 and revision 7:  The following sections give a rough overview on existing coding conventions.  * [Coding Style]  * [Coding Conventions]  {warning:title=Warning}Jikes RVM is a bleeding-edge research project. You will find that some of the code does not live up to product quality standards. Don't hesitate to help rectify this by contributing clean-ups, bug fixes, and missing documentation to the project. We are in the process of consolidating and simplifying the codebase at the moment.  {warning}     One goal of the JikesRVM project over recent years has been the ability to develop JikesRVM in a development environment such as Eclipse.&nbsp; This has been possible for the MMTk component since 2005, and as of early 2007 (release 2.9.0) it is possible to work with the majority of the JikesRVM codebase in Eclipse and similar environments.&nbsp; This is not yet as straightforward as we would like, and can be expected to improve with time.  * [Editing JikesRVM in an IDE]  * [Compiler DNA]   * [Adding a New GC] View All Revisions | Revert To Version 6 [Less]
Posted over 17 years ago by Robin Garner
Page added by Robin Garner The MMTk test harness allows you to run MMTk as a user-level application, step through it in a debugger and do any of the other standard Java ... [More] debugging procedures that being the memory manager of JikesRVM prevents you from doing.  The test harness incorporates a simple interpreted scripting language with just enough features to build interesting data structures, perform GCs and assert properties of them. The test harness is a recent development.  Please don't expect it to be 100% bug-free just yet. Running the test harness The harness can be run standalone or via Eclipse (or other IDE). Standalone ant mmtk-harness java -jar target/mmtk/mmtk-harness <script-file> [options...] There is a collection of sample scripts in the MMTk/harness/test-scripts directory.  In eclipse ant mmtk-harness-eclipse-project Define a new run configuration with main class org.mmtk.harness.Main Test harness options Options are passed to the test harness as 'keyword=value' pairs.  The standard MMTk options that are available through JikesRVM are accepted (leave off the "-X:gc:"), as well as the following harness-specific options: Option Meaning plan The MMTk plan class.  Defaults to org.mmtk.plan.marksweep.MS collectors The number of concurrent collector threads (default: 1) initHeap Initial heap size in pages (default: 64) maxHeap Maximum heap size in pages (default: 64) trace Debugging messages from the MMTk Harness.  Trace options include CALL - trace procedure calls ALLOC - trace object allocation OBJECT - trace object mutation events gcEvery Force frequent GCs.  Options are ALLOC - GC after every object allocation  SAFEPOINT - GC at every GC safepoint View Online [Less]
Posted over 17 years ago by Robin Garner
Page edited by Robin Garner This section describes the practical aspects of getting started using and modifying Jikes RVM. The Quick Start Guide gives a 10 second overview ... [More] on how to get started while the following sections give more detailed instructions. Get The Source Build the RVM Run the RVM Configure the RVM Modify the RVM Test the RVM The MMTk Test Harness Debug the RVM Evaluate the RVM View Online Changes between revision 8 and revision 9:  This section describes the practical aspects of getting started using and modifying Jikes RVM. The [Quick Start Guide] gives a 10 second overview on how to get started while the following sections give more detailed instructions.  # [Get The Source]  # [Build the RVM|Building the RVM]  # [Run the RVM|Running the RVM]  # [Configure the RVM|Configuring the RVM]  # [Modify the RVM|Modifying the RVM]  # [Test the RVM|Testing the RVM]   #* [The MMTk Test Harness]  # [Debug the RVM|Debugging the RVM]  # [Evaluate the RVM|Experimental Guidelines] View All Revisions | Revert To Version 8 [Less]