The present invention relates to tools for automating the development of applications for computer systems.
During application development, it is quite common for a programmer to move a method from one class to another class. This is typically accomplished by manually moving the method from the source class to the destination class, and then fixing up references within the moved method to be compatible with the destination class. For example, the source instance (referred to as “this”) for the source class can become a parameter in the moved method, and the “source parameter” whose class matches the destination class becomes the destination instance (“this”) in the moved method.
When the method is moved, it is customary to replace the original method in the source class with a forwarding method, so that invoking the forwarding method in the source class causes the moved method to be invoked in the destination class. In this way, references to the original method in the source class are automatically forwarded to the moved method in the destination class.
However, using a forwarding method can be tricky because of a simple problem: the source parameter (which becomes “this” in the destination class) may be null. If the forwarder is constructed by simply converting the source parameter into the destination instance as described above, a problem may arise because the destination instance (“this”) in the destination class can never be null. Hence, if the source parameter is null, and the original method in the source class performs some action based on the null value of the source parameter, the moved method in the destination class may not perform the same action.
One embodiment of the present invention provides a system that facilitates moving an original method from a source class to a destination class and for constructing a corresponding forwarding method in the source class that preserves null semantics. During operation, the system translates the original method from the source class into a corresponding moved method, and then incorporates the moved method into the destination class. The system also constructs a forwarding method that invokes the moved method in the destination class. The system then replaces the original method in the source class with the forwarding method. In this way, invoking the forwarding method in the source class causes the moved method to be invoked in the destination class. While constructing the forwarding method, the system generates code that checks whether a “source parameter” of the original method whose class matches the destination class is null. If so, the generated code executes the body of the original method. Otherwise, the generated code invokes the moved method in the destination class. The system also optimizes the generated code to produce optimized code for the forwarding method, whereby portions of the original method can possibly be optimized away.
In a variation on this embodiment, translating the original method into the corresponding moved method involves replacing references through the source parameter with references through a destination instance associated with the destination class.
In a variation on this embodiment, translating the original method into the corresponding moved method involves adding a destination parameter to the moved method, wherein the destination parameter contains a backpointer to a source instance associated with the original method. It also involves replacing references through the source instance with references through the destination parameter.
In a variation on this embodiment, optimizing the generated code involves using compiler-based techniques to optimize the generated code.
In a variation on this embodiment, optimizing the generated code involves performing value propagation and exception propagation operations on the generated code. In a further variation, the system additionally performs algebraic manipulations to simplify the optimized code.
In a variation on this embodiment, optimizing the generated code can involve inserting exception-throwing code, which throws a null-pointer exception, into the forwarding method. In a further variation, the system eliminates the exception-throwing code, if possible, through algebraic simplification.
Tables 1A-1F illustrate a first example of moving a method between classes in accordance with an embodiment of the present invention.
Tables 2A-2F illustrate a second example of moving a method between classes in accordance with an embodiment of the present invention.
Tables 3A-3E illustrate a second example of moving a method between classes in accordance with an embodiment of the present invention.
Tables 4A-4E illustrate a second example of moving a method between classes in accordance with an embodiment of the present invention.
The following description is presented to enable any person skilled in the art to make and use the invention, and is provided in the context of a particular application and its requirements. Various modifications to the disclosed embodiments will be readily apparent to those skilled in the art, and the general principles defined herein may be applied to other embodiments and applications without departing from the spirit and scope of the present invention. Thus, the present invention is not intended to be limited to the embodiments shown, but is to be accorded the widest scope consistent with the principles and features disclosed herein.
The data structures and code described in this detailed description are typically stored on a computer-readable storage medium, which may be any device or medium that can store code and/or data for use by a computer system. This includes, but is not limited to, magnetic and optical storage devices, such as disk drives, magnetic tape, CDs (compact discs) and DVDs (digital versatile discs or digital video discs), and computer instruction signals embodied in a transmission medium (with or without a carrier wave upon which the signals are modulated). For example, the transmission medium may include a communications network, such as a LAN, a WAN or the Internet.
Moving a Method
The process of moving the method also involves constructing a forwarding method 106, wherein invoking forwarding method 106 in source class 102 causes moved method 108 to be invoked in destination class 110. Note forwarding method 106 is constructed in a way that preserves null semantics (This is described in more detail below with reference to
The system then replaces original method 104 in source class 102 with forwarding method 106, so that invocations to original method 104 are now directed to forwarding method 106, and wherein forwarding method 106 causes moved method 108 in destination class 110 to be invoked.
Referring to
Note that the above-described process for moving a method can be performed by a software development tool that automatically performs most if not all of the manipulations required to move the method, fix up the references, and generate a forwarding method.
How References are Modified
Original method 104 may also contain references through a source parameter “x” to program elements associated with destination class 110. During the above-described translation process, these references are translated into corresponding references through a destination instance associated with the destination class (“this” in the destination class).
Process of Moving a Method
Translating the Original Method into the Moved Method
Generating a Forwarding Method
Next, the system optimizes the generated code to produce optimized code for forwarding method 106 (step 504). (Note that code within moved method 108 can also be optimized.) This optimization process hopefully eliminates some of the code from the body of original method 104.
More specifically, referring to
In the sections that follow, we present a number of examples illustrating how methods are moved between classes.
In the first example, we move the method firstStatPos ( ) to class com.sun.tools.javac.v8.tree.Tree. The original method appears below.
This original method is translated into the moved method that follows.
In this case, the first parameter has become “this” and there is no need for a back reference to the original object.
Next, after a cleanup operation, the moved method appears as follows.
The cleanup involves collapsing the if and return statements into a single return with a conditional.
The basic strategy for constructing the forwarding method is to check for null, execute the original method body if null, and otherwise invoke the moved method. The raw forwarding method appears below.
After truth and exception propagation operations the forwarding method appears as follows.
The truth propagator realizes that enclosing the “if” implies tree==null, which in turn implies that “tree.tag” must throw a NullPointerException.
Next, after a cleanup operation, the forwarding method appears as follows.
Note that the if and throw get eliminated through algebraic simplification because tree.firstStatPos( ) implicitly subsumes them.
In the second example, we move the method iSEmpty( ) to class com.sun.tools.javac.v8.tree.Tree. The original method appears below. This method is tricky because the original method has non-exceptional behavior in the null case.
The original method is translated into the moved method that follows.
Note that “this” in the moved method is never null, so the initial if statement can be eliminated.
Next, after a cleanup operation, the moved method appears as follows.
The raw forwarding method appears below.
After truth and exception propagation operations the forwarding method appears as follows.
Note that the second null check is clearly implied to be true, and t.tag clearly throws a NullPointerException, but this throw will be eliminated since the preceding return is always taken.
Next, after a cleanup operation, the forwarding method appears as follows.
This cleanup operation may not be obvious. The
if(t==null) return tree; else return . . .
becomes return t==null?true: . . . , which in turn becomes t==null∥ . . . .
In the third example, we move the method deblock( ) to class com.sun.tools.javac.v8.tree.Tree. Themajorcomplexityhereis that the parameter that will be mapped to “this” is assigned to. This can be handled straightforwardly by declaring a local variable that starts out shadowing “this.” The original method appears below.
The original method is translated into the following moved method.
The raw forwarding method appears below.
After truth and exception propagation operations the forwarding method appears as follows.
Next, after a cleanup operation, the forwarding method appears as follows.
This simplifies nicely: “while (t!=null)” drops out because t is known to be null on first entry to the loop.
In the fourth example, we move the method statement( ) to class com.sun.tools.javac.v8.tree.Tree. The major complexity here is that the original method references methods in the containing class. To deal with this problem, a synthetic parameter “theOperator” is added, which provides a backpointer to the original object. All references that had been to “this” are now replaced with the new parameter. The original method appears below.
The original method is translated into the following moved method.
The raw forwarding method appears below. Note that the forwarding method now passes the backpointer as an extra argument.
After truth and exception propagation operations the forwarding method appears as follows.
Next, after a cleanup operation, the forwarding method appears as follows.
The foregoing descriptions of embodiments of the present invention have been presented for purposes of illustration and description only. They are not intended to be exhaustive or to limit the present invention to the forms disclosed. Accordingly, many modifications and variations will be apparent to practitioners skilled in the art. Additionally, the above disclosure is not intended to limit the present invention. The scope of the present invention is defined by the appended claims.
This application hereby claims priority under 35 U.S.C. §119 to U.S. Provisional Patent Application No. 60/612,595 filed on 22 Sep. 2004, entitled “Method and Apparatus for Preserving NULL Semantics During Use of a Forwarding Method,” by inventor James A. Gosling.
Number | Name | Date | Kind |
---|---|---|---|
5481712 | Silver et al. | Jan 1996 | A |
5560009 | Lenkov et al. | Sep 1996 | A |
5812850 | Wimble | Sep 1998 | A |
5815415 | Bentley et al. | Sep 1998 | A |
6347342 | Marcos et al. | Feb 2002 | B1 |
6591272 | Williams | Jul 2003 | B1 |
6880126 | Bahrs et al. | Apr 2005 | B1 |
6975628 | Johnson et al. | Dec 2005 | B2 |
7058935 | Kawahito et al. | Jun 2006 | B2 |
7080366 | Kramskoy et al. | Jul 2006 | B2 |
7093242 | Bernadat et al. | Aug 2006 | B2 |
7113939 | Chou et al. | Sep 2006 | B2 |
7139766 | Thomson et al. | Nov 2006 | B2 |
7194543 | Robertson et al. | Mar 2007 | B2 |
7275079 | Brodsky et al. | Sep 2007 | B2 |
7280558 | Grunkemeyer et al. | Oct 2007 | B1 |
7346897 | Vargas | Mar 2008 | B2 |
20030091028 | Chang et al. | May 2003 | A1 |
20050256834 | Millington et al. | Nov 2005 | A1 |
20060039371 | Castro et al. | Feb 2006 | A1 |
Number | Date | Country | |
---|---|---|---|
60612595 | Sep 2004 | US |