As is generally known, computers are used to manipulate data under the control of software. Software is typically written in a high level programming language such as C, which is then compiled by a compiler program into binary machine language instructions which can be executed by a central processing unit in the computer. Software written in programming languages other than the machine language instructions are relatively much easier to understand and use. A very common strategy to simplify computer programming is to group frequently called portions of a program in subroutines, or functions, which perform a certain task. Functions may generally be called or executed as needed from anywhere else in the program each time the task is to be performed. Thus, rather than repeating the program instructions for the task each time the task is performed, the program instructions appear only once in the software, reducing the size of the resulting software.
However, including functions in software can have a negative impact on the performance of the software. Information must often be passed along to the functions as formal parameters, and functions may return information as return values. Passing formal parameters and return values to and from functions requires that a compiler generate additional machine language instructions, making extra work which slows the computer. Additionally, each time a function is called, the computer must save the state of the processor before jumping to the function in the program, in effect saving its place before executing the function. Once the function has finished executing, the computer must restore the state of the processor before returning to the instruction following the function call. These additional tasks can greatly slow the execution of software, particularly if the software includes many small functions. In the extreme, these additional tasks such as passing parameters and return values and saving the state of the processor can be more work for the processor than the actual function.
Most compilers include optional optimization tools which give the programmer the option of optimizing the software for speed as it is compiled. One such tool, called inlining, replaces function calls with the body of the function each time the function call appears. Thus multiple copies of a function will appear inline with the rest of the program, rather than being a single independent copy which can be called from multiple places. Actual arguments to an operation are substituted for formal parameters and the state-saving instructions are omitted. Since this increases the size of the software, compilers typically attempt to determine which functions would be good candidates for inlining and which are not. The criteria used by compilers include information such as the size of a function, the frequency with which it is called, and the number of places from which it is called. For example, large functions which are called infrequently but from many points, or call sites, in a program would be poor candidates for inlining as they would greatly increase the size of the software. In contrast, small functions which are called frequently from only a few call sites would be good candidates for inlining.
However, the traditional software environment in which a program is written, compiled, then executed on a single type of computer is changing with the increasing desire for hardware independent software which can be executed on multiple different types of computers. To achieve hardware independence in software, software is typically either manipulated after compilation (e.g., translated) or is compiled piecemeal as the software is executed.
Another departure from the traditional compilation environment is dynamic translation, wherein software in binary machine language form, written for execution on a first type of computer, is translated as it is executed on a second type of computer. Dynamic translators operate by translating each word of the non-native code into a corresponding word or words of native code for execution by the computer. However, dynamic translators do not scan, evaluate and modify software before executing, and thus do not have detailed information about the software prior to execution. Without additional information about the code it is very difficult, if not impossible, to achieve full inlining of the program to improve performance, particularly in machine language code.
A need therefore exists for a method of enabling function inlining and related optimizations during execution of a program, whether native or non-native to the computer. A further need exists for a method of enabling function inlining and related optimizations during execution of a program in machine language binary format. A further need exists for a method of providing information about an executing program to facilitate dynamic optimization of the program.