2.2.1 Dynamic Analysis.
In recent years there has been a revival of interest in dynamic analysis [70]. System analysis of runtime behavior is vital for performance analysis to detect hotspots of activity and bottlenecks of execution or memory allocation problems such as unnecessary object retention. In a reverse engineering context, dynamic analysis is used is to extract high-level views about the behavior of low-level components to facilitate the comprehension
of the system [64, 71, 135].
Dynamic analysis yields precise information about the runtime behavior of systems [3]. However, the task of writing tools to abstract runtime data is not trivial. Tool builders are faced with many options as there are numerous techniques that address the task of collecting runtime data.
Reflection is an interesting implementation technique for dynamic anal-ysis and has been used in the past, for example to record traces [24, 74]. The benefit of using reflection for dynamic analysis is that we can for example introduce tracers at runtime and retract them without the need to restart the system. In addition, we do not need to run the program in a special environment. For example, there is no need for a special virtual machine.
Partial behavioral reflection is especially suited as a basis for dynamic analysis [42], as we can precisely select what to reflect on and what data of the application to pass to the meta-object. To support dynamic analysis for long-running systems, we need to make sure that when not used, the reflective feature should not cost anything. We need to be able to introduce the reflective features on-demand at runtime, we need unanticipated partial behavioral reflection.
An important property of any technique for dynamic analysis is what parts of the system it can be applied on. A problem with reflection based approaches is that we face the recursion problem as soon as we reflect on core system features, like Numbers or Arrays. These are used in the code of the tracer itself, which leads to the problem of meta-object call recursion. In practice, reflection-based dynamic analysis is thus restricted to application level code. In addition, when implementing tools leveraging behavioral reflection, it would be interesting to analyze these tools themselves. This dynamic meta-level analysis is not practical to realize with current reflective systems. We will show that the cause for both problems is a missing representation of meta-level execution.
Requirements: (i) unanticipated partial behavioral reflection and (ii) we need to apply behavioral reflection to the whole system
2.2.2 Integrated Development Environments.
Development environments (IDEs) and tools can benefit from reflection:
any IDE needs a representation of the program to work with. This rep-resentation is then used to drive code browsers, code highlighting and refactoring functionality. But most IDEs provide a distinct representation separate from the reflective representation already made available by the language [130]. With a sufficiently powerful reflective model, no special IDE data structures for the language are needed. Instead, the tools can use
the one representation that is the reflective model of the language itself.
In the light of long-running systems this is especially interesting as the boundaries between development and deployment start to blur. An IDE working on the reflective structure of a system facilitates development at runtime. A prime example for such a system is Smalltalk [60]. In the Smalltalk IDE, the code browser is just a very thin user interface layer that directly modifies the reflective structure of the language. Classes and methods are objects, the classes are responsible to compile and install new code as methods.
But even in systems where the IDE uses structural reflection, reflective representation of the system does not provide any support for the structure of methods themselves besides the low-level bytecode and source code. A representation of complete program structure would be interesting for any IDE feature working on sub-method abstraction, for example for debuggers, profilers or code refactoring tools.
For tools working on the level of classes and whole methods (e.g., a class browser), structural reflection eases tool-building as all tools use the same representation [130]. The system should provide the same for sub-method structure.
Requirement: sub-method reflection.
2.2.3 Language Experiments
Reflection provides means to experiment with new language features without the need to develop completely new languages. For exam-ple, behavioral reflection has been used to introduce new language fea-tures in several languages, for instance multiple inheritance[16], distribu-tion [5, 102], instance-based programming [4], active objects [25], concur-rent objects [134], futures [105] and atomic messages [57, 99], as well as backtracking facilities [91]
An interesting example is the existing structural reflection found in Squeak Smalltalk. In the past, Squeak has already provided a platform for many experiments with new language features [6]. Examples of such language experiments include:
Traits are building blocks that can be composed to classes [52, 11]. Traits have been realized in Squeak without the need to change the virtual machine or the grammar of the language by using reflection.
Classboxes [10, 9, 8, 7] provide a module system that supports local re-binding.
Changeboxes [41, 136] provide a mechanism for encapsulating change as a first-class entity in a running software system. Changeboxes provide for running different versions of code in the same system.
All these examples use either the standard reflective facilities of Smalltalk [113] or those added to the Squeak dialect, for example the ability to replace any method by an object that interprets the message sent [6].
These examples show that limited reflective properties are already very useful in supporting language experiments. Improving reflective features will help to make language experiments even easier.
Requirements:(i) sub-method reflection, (ii) unanticipated behavioral reflection.
2.2.4 Three Requirements for Reflective Systems
Reflection will play a crucial role to enable us to build both the languages and tools for the future. We have already seen many examples of how reflection has been useful for these kinds of experiments in the past. At the same time, we found three shortcoming that we plan to solve in this dissertation:
• Analyzing a long-running systems demands unanticipated use of par-tial behavioral reflection.
• We need to extend structural reflection with sub-method support to serve as a basis for tool building and behavioral reflection.
• We need to solve the recursion problem to be able to use tools based on behavioral reflection on the complete system including system classes and the code of the tool itself.
Before we discuss these requirements in detail, we give a brief overview of reflection.