Process and system for run-time inheritance and disinheritance of methods and data6101501Abstract In an object-oriented run-time environment, inheritance and disinheritance of methods and data to and from an object is facilitated. When an object is invoked, a method within the object is called. Execution of this method may, however, not be possible because, e.g., a data type passed to the method may not be supported thereby. In response to this condition, the object invokes a process that inherits a required method and/or datum into the object. For example, a method that does support the previously unsupported data type may be inherited. After inheritance is completed, the object is reinvoked with the previously unsupported data type. Processing may then continue using the inherited method. After the inherited method is no longer needed, it may be disinherited from the object. Claims What is claimed is: Description TECHNICAL FIELD
______________________________________
Matrix Matrix
Class Name Data Type Size
______________________________________
CMATRIX -- --
CMATRIX.sub.-- BIT
Bit --
CMATRIX.sub.-- BIT.sub.-- S
Bit Small
CMATRIX.sub.-- BIT.sub.-- H
Bit Huge
CMATRIX.sub.-- FLOAT
Floating Point
--
CMATRIX.sub.-- FLOAT.sub.-- S
Floating Point
Small
CMATRIX.sub.-- FLOAT.sub.-- H
Floating Point
Huge
CMATRIX.sub.-- FIXED
Fixed Point
--
CMATRIX.sub.-- FIXED.sub.-- S
Fixed Point
Small
CMATRIX.sub.-- FIXED.sub.-- H
Fixed Point
Huge
______________________________________
Matrices are manipulated using objects instantiated from the foregoing classes. In one example, most matrix operations are performed on small sized matrices of fixed-point type elements, and therefore, an object instantiated from the CMATRIX.sub.-- FIXED.sub.-- S class is used. However, it may be become necessary to perform operations on huge matrices of fixed-point type elements. Therefore, according to the techniques disclosed herein, an object is instantiated and includes the required method of the CMATRIX.sub.-- FIXED.sub.-- H class along with the methods from the CMATRIX.sub.-- FIXED.sub.-- S class, at run-time. The footprint of the subject object is thus only enlarged when necessary, at run-time, thereby improving the efficiency of system resource usage. The techniques for inheriting a huge matrix method into an object instantiated from the CMATRIX.sub.-- FIXED.sub.-- S class, at run-time, are described hereinbelow with respect to the flow-diagram of FIG. 2. Specifically, the logic of an object instantiated from the CMATRIX.sub.-- FIXED.sub.-- S class that facilitates run-time method inheritance from the CMATRIX.sub.-- FIXED.sub.-- H class is described. An object is instantiated from the CMATRIX.sub.-- FIXED.sub.-- S class, and during run-time processing the object is passed an INPUT.sub.-- MATRIX for inversion using the objects' INVERSE method, STEP 21. A test is performed within the programmed logic of the object's methods to determine if the INPUT.sub.-- MATRIX is compatible with the methods of the object. Specifically, the INPUT.sub.-- MATRIX is tested to determine if it is a small-sized matrix with elements of the fixed-point type, INQUIRY 23. If the INPUT.sub.-- MATRIX is of the small/fixed-point type then processing proceeds normally, STEP 25. If an INPUT.sub.-- MATRIX other than the small, fixed-point type is presented to the object, tests are performed to determine if INPUT.sub.-- MATRIX is of a type for which method inheritance is desired. For example, INPUT.sub.-- MATRIX is tested to determine if it is of a huge size and has elements of a fixed-point data type, STEP 29. If yes, the INVERSE method for a huge, fixed-point matrix is inherited, STEP 27, as discussed in detail hereinbelow, and processing using the inherited method continues. If no, other tests for other size and type matrices are performed, STEP 31, and inheritance is performed if appropriate, STEP 33. If the INPUT.sub.-- MATRIX is not of a type for which inheritance of an appropriate method is desired, then an error is generated and returned to the invoker, STEP 35. One embodiment of the particular steps for inheriting a method into an object, at run-time, are described below with respect to the flow-diagram of FIG. 3. The steps of FIG. 3 result from a call for inheritance of a method from within an object. This call for inheritance is implemented by a compiler directive that is within the object's programmed logic and is defined, e.g., as follows: @INHERIT.sub.-- METHOD(<class.sub.-- name>, <method.sub.-- name> .linevert split., <new.sub.-- method name>.linevert split.)
______________________________________
class.sub.-- name -
the name of the class where the
method to be inherited is defined.
method.sub.-- name -
the name of the method to be
inherited.
new.sub.-- method.sub.-- name -
an optional name to give the
inherited method in the current
object (by default, the method name
in the current object will equal. the
method name in the class the method
is being inherited from)
______________________________________
When the compiler encounters this directive (i.e., when compiling the object), the directive is translated into programmed logic to implement the below described run-time steps. A first step in inheriting a method into an object includes serializing access to the object, STEP 41. This includes, for example, suspending access to the object (the use of semaphores to serialize invocations of an object's methods is well known). In, e.g., an "MVS" ("Multiple Virtual Storage") computing environment, the serialization can be performed using, for instance, an ENQ ("Enqueue") system macro. In a next step, the desired method ("method.sub.-- name") is retrieved from its class ("class.sub.-- name"), STEP 43, for instantiation into the current object. Such retrieval is performed using, for instance, the multiple inheritance available within object-oriented languages. Before reinstantiating a new object with the desired methods inherited, the old object is deleted using conventional Object Request Broker ("ORB") functions, STEP 49. Thereafter, a new object is instantiated, STEP 51, using the methods from its current class definition (CMATRIX FIXED S) in addition to the methods inherited (e.g., method name=INVERSE) from another class (e.g., class.sub.-- name=CMATRIX.sub.-- FIXED.sub.-- H). An object with the desired methods inherited is thus created. More specifically, one method for instantiating the new object, with the additional methods, is performed using the creation of a temporary file that contains a class definition for the new object. This class definition includes the original class source code (e.g., CMATRIX.sub.-- FIXED.sub.-- S), and the appropriate multiple inheritance from another class (e.g., CMATRIX.sub.-- FIXED.sub.-- H). For example, the original class, CMATRIX.sub.-- FIXED.sub.-- S, is defined as follows: class CMATRIX.sub.-- FIXED.sub.-- S
______________________________________
ADD.sub.-- FIXED.sub.-- S (. . .) { . . .} ;
INVERSE.sub.-- FIXED.sub.-- S (. . .) { . . .} ;
MULTIPLY.sub.-- FIXED.sub.-- S (. . .) { . . .} ;
}
______________________________________
Additionally, the class CMATRIX.sub.-- FIXED.sub.-- H is defined as follows: class CMATRIX.sub.-- FIXED.sub.-- H
______________________________________
ADD.sub.-- FIXED.sub.-- H (. . .) { . . .} ;
INVERSE.sub.-- FIXED.sub.-- H (. . .) { . . .} ;
MULTIPLY.sub.-- FIXED.sub.-- H (. . .) { . . .} ;
}
______________________________________
If it were desirable to include all methods from CMATRIX.sub.-- FIXED.sub.-- H in the new object, a segment could be defined as follows: class CMATRIX.sub.-- FIXED.sub.-- S.sub.-- NEW: CMATRIX.sub.-- FIXED.sub.-- S, CMATRIX.sub.-- FIXED.sub.-- H{ }; Compilation of the class CMATRIX.sub.-- FIXED.sub.-- S.sub.-- NEW would include all methods of classes CMATRIX.sub.-- FIXED.sub.-- S and CMATRIX.sub.-- FIXED.sub.-- H. Temporary class CMATRIX.sub.-- FIXED.sub.-- S.sub.-- NEW could then be used to instantiate a new object having all the methods from the two classes. However, in the current example, it is desirable to only include the INVERSE method from the class CMATRIX.sub.-- FIXED.sub.-- H. To avoid including unnecessary methods from CMATRIX.sub.-- FIXED.sub.-- H in the new class, the unnecessary methods are overridden with NOOPs (no operation codes) in the temporary class. Accordingly, the temporary class CMATRIX.sub.-- FIXED.sub.-- S.sub.-- NEW is defined as follows: class CMATRIX.sub.-- FIXED.sub.-- S.sub.-- NEW: CMATRIX.sub.-- FIXED.sub.-- S, CMATRIX.sub.-- FIXED.sub.-- H
______________________________________
ADD.sub.-- FIXED.sub.-- H (. . .) { }; // NOOP METHOD //
MULTIPLY.sub.-- FIXED.sub.-- H (. . .){ }; // NOOP METHOD //
}
______________________________________
As discussed hereinabove, the new method can have a different name than it had in the class it is being inherited from. For example, the INVERSE.sub.-- FIXED.sub.-- H method from the CMATRIX.sub.-- FIXED.sub.-- H class could be inherited as a method called INVERSE.sub.-- NEW. This would be performed by generating a class definition similar to that shown hereinabove, however, the INVERSE.sub.-- FIXED.sub.-- H method would be NOOPed, and the source code therefrom (conventionally available to the compiler) would be incorporated into a new method definition. For example, the following segment would be generated: class CMATRIX.sub.-- FIXED.sub.-- S.sub.-- NEW: CMATRIX.sub.-- FIXED.sub.-- S, CMATRIX.sub.-- FIXED.sub.-- H
______________________________________
INVERSE.sub.-- FIXED.sub.-- H (. . .) { };
// NOOP METHOD //
INVERSE.sub.-- NEW (. . .) {
// SAME PARAMETER LIST
AS INVERSE.sub.-- FIXED.sub.-- H //
// COPY OF THE CODE FOR
THE INVERSE.sub.-- FIXED.sub.-- H
METHOD //
};
ADD.sub.-- FIXED.sub.-- H (. . .) { };
// NOOP METHOD //
MULTIPLY.sub.-- FIXED.sub.-- H (. . .) { };
// NOOP METHOD //
}
______________________________________
To continue with the method shown in FIG. 3, the new object is registered with the ORB, STEP 53. The ORB is then directed to reinvoke the new object, STEP 55, with the same data that was previously used to invoke the (old) object. As a result, the data will be processed by the new object using the inherited method. For instance, in the current example, the new object is reinvoked with the fixed-point, huge matrix that was previously unprocessable. However, because of the inheritance of the fixed-point, huge matrix processing method (i.e., e.g., INVERSE), this matrix is now processed by the new object. After reinvocation of the object has completed, the object is released for use by other invokers, STEP 57, and processing continues. In, e.g., an "MVS" ("Multiple Virtual Storage") computing environment, the release of the object can be performed using, for instance, a DEQ ("dequeue") system macro. In more specific regard to the above process, a new mechanism is used within the logic of the object's methods to permit reinvocation of the new object's methods using the data from the old object method invocation. Upon initiation of the steps used to inherit a new method, the old object's method's parameter list is stored in e.g. memory or a file. This parameter list includes the data that the old method that was invoked with, along with any internal parameters that are maintained between invocations. After inheritance is complete, and prior to releasing the object for use, the parameter list is read in, and the new object is configured accordingly. Further, the data that the old object's method was invoked with is used to redrive the new method in the newly instantiated object. As discussed above, the inherited method may be used only a few of the times that any of the object's methods are invoked. It may therefore become advantageous to eventually disinherit the inherited method such that the resources required by the inherited method within the object are freed. A determination of when to perform disinheritance may be based on factors including, e.g., how long since the method was last used in time and/or object method invocations. In the foregoing example, if, for instance, one-thousand method invocations of the object have occurred without requiring any inverting of fixed-point, huge matrices (the inherited method), it may be desirable to disinherit the fixed-point, huge matrix invert method such that system resources used by the object are minimized. The particular steps for disinheriting a method from an object, at run-time, are described below with respect to the flow-diagram of FIG. 4. A call for disinheritance of a method from within an object is implemented by a compiler directive that is within the object's programmed logic and defined, e.g., as follows: @DISINHERIT.sub.-- METHOD(<method.sub.-- name>) method.sub.-- name--the name of the method to be disinherited. When the compiler encounters this directive (i.e., when compiling the object), it is translated into programmed logic to implement the below-described steps. A first step in disinheriting a method from an object includes serializing access to the object, STEP 61. Again, this includes suspending invocations of the object. In, e.g., an "MVS" ("Multiple Virtual Storage") computing environment, the serialization can be performed using, for instance, an ENQ ("Enqueue") system macro. In a next step, the (old) object is deleted using conventional ORB functions, STEP 63. After that, a new object is instantiated, STEP 65, from the current class definition (CMATRIX.sub.-- FIXED.sub.-- S) and excluding the method to be disinherited. An object with the desired methods is thus created. The new object is automatically registered with the ORB by way of its instantiation, STEP 67, the object released, STEP 69, and processing continues. In, e.g., an "MVS" ("Multiple Virtual Storage") computing environment, the release of the object can be performed using, for instance, a DEQ ("dequeue") system macro. Described above are examples of techniques for inheriting and disinheriting a method. It will be apparent to those of ordinary skill in the art that the above-described flows and sequences of steps are only examples. There can be many variations to the above, including, for instance, processing more or less than the steps described above, modifying one or more of the steps, or changing the order of some of the steps without departing from the true spirit and scope of the present invention. These variations are, therefore, considered a part of the claimed invention. As one example application, the techniques of the present invention can be used to dynamically adapt (i.e., at run-time) to changing hardware system resources, while maintaining objects with efficient footprints (i.e., system resources required). As an example, the class hierarchy of FIG. 1 is referred to in connection with the additional classes of FIG. 5. These additional classes include methods optimized for matrix manipulation using either a hardware vector processor for performing floating-point calculations, or using software emulation of a vector processor. It is generally more desirable to use a vector processor due to greater execution speed and smaller code requirements (i.e., compared to software emulation that requires extensive code libraries and executes more slowly than hardware based vector floating-point processing). An object that includes both types of processing methods would be inefficient for a situation where a vector processor was available since the program code used for software floating-point emulation would go unused, but would nonetheless increase the footprint of the object. In specific regard to the above example, an object is instantiated for use and impressed with the CMATRIX.sub.-- FLOAT.sub.-- S.sub.-- VECTOR class (i.e., its target machine usually has an installed vector processing facility). The configuration of the target machine's hardware may, however, change during operations, making the vector facility unavailable (i.e., by a hardware failure, or a general system configuration change). Processing can therefore not continue using the current object. Accordingly, upon detection of the vector facility being unavailable, the object may use the techniques disclosed herein to inherit the methods and corresponding software emulation based methods from the CMATRIX.sub.-- FLOAT.sub.-- S.sub.-- EMULATE class and processing may continue. Conversely, when the object detects that the vector facility has become available, the software emulation based methods may be disinherited in favor of the vector facility based methods. The above described techniques for inheriting and disinheriting object methods at runtime can also be used for inheriting and disinheriting object data (i.e., data variables or structures defined in classes that objects are instantiated from) at runtime. Additional syntactic constructs are defined which correspond to the "@INHERIT.sub.-- METHOD" and "@DISINHERIT.sub.-- METHOD" directives discussed hereinabove. For example, the following compiler directives are defined: @INHERIT.sub.-- DATA(<class.sub.-- name>, <datum.sub.-- name> .linevert split., <new.sub.-- datum.sub.-- name>.linevert split.)
______________________________________
class.sub.-- name -
the name of the class where the
datum to be inherited is defined.
datum.sub.-- name -
the name of the datum (i.e.,
variable) to be inherited.
new.sub.-- datum.sub.-- name -
an optional name to give the
inherited datum in the current
object (by default, the datum name
in the current object will equal the
datum name in the class the datum is
being inherited from)
______________________________________
@DISINHERIT.sub.-- DATA(<datum.sub.-- name>)
______________________________________
datum.sub.-- name -
the name of the datum to be disinherited.
______________________________________
Using the foregoing directives, and substituting datum (i.e., variable) names (and/or values) for the method names previously utilized, the same variable. (and/or value) described hereinabove for inheriting and disinheriting methods are useable to inherit and disinherit datum. As an example, class CMATRIX.sub.-- BIT.sub.-- S (FIG. 1) could include in its definition a unitary matrix that has the values of binary 1 along its diagonal and binary 0 elsewhere, represented as an array. Similarly, class CMATRIX.sub.-- BIT.sub.-- H includes the same unitary matrix represented as a list of elements along the diagonal having a binary 1 value, and omits the binary 0 values elsewhere to conserve space. If an object instantiated as an object of CMATRIX.sub.-- BIT.sub.-- S would for any reason inherit (using the method inheritance techniques of the present invention) the method for processing huge, bit matrices, it could similarly inherit the unitary matrix datum appropriate therefor. To summarize, the present invention has several advantages and features associated with it. By facilitating the inheritance and disinheritance of methods and data to and from objects at run-time, efficient system resource utilization is facilitated. Inheriting methods into objects only when needed, and disinheriting them when no longer required, reduces the size (i.e. "footprint") of an object. Smaller objects require less run-time storage and therefore use fewer system resources. Moreover, a single object can have greater versatility since it may adapt to its changing run-time environment by inheriting and disinheriting methods and data. Fewer objects are therefore required for a set of functions, again improving system resource utilization. Accordingly, the techniques disclosed herein advance the art of object-oriented programming. While the invention has been described in detail herein, in accordance with certain preferred embodiments thereof, many modifications and changes thereto may be affected by those skilled in the art. Accordingly, it is intended by the appended claims to cover all such modifications and changes as fall within the true spirit and scope of the invention.
|
Same subclass Same class Consider this |
||||||||||
