ArticlePDF Available

Abstract and Figures

Although dynamic languages are becoming widely used due to the flexibility needs of specific software prod- ucts, their major drawback is their runtime performance. Compiling the source program to an abstract machine's intermediate language is the current technique used to obtain the best performance results. This intermediate code is then executed by a virtual machine developed as an interpreter. Although JIT adaptive optimizing com- pilation is currently used to speed up Java and .net intermediate code execution, this practice has not been em- ployed successfully in the implementation of dynamically adaptive platforms yet. We present an approach to improve the runtime performance of a specific set of structural reflective primitives, extensively used in adaptive software development. Looking for a better performance, as well as interaction with other languages, we have employed the Microsoft Shared Source CLI platform, making use of its JIT compiler. The SSCLI computational model has been enhanced with semantics of the prototype-based object-oriented com- putational model. This model is much more suitable for reflective environments. The initial assessment of per- formance results reveals that augmenting the semantics of the SSCLI model, together with JIT generation of native code, produces better runtime performance than the existing implementations.
Content may be subject to copyright.
Adding Structural Reflection to the SSCLI
Francisco Ortin Jose M. Redondo Luis Vinuesa Juan M. Cueva
Computer Science Department, University of Oviedo
C/Calvo Sotelo s/n, 33007, Oviedo Spain
ortin@uniovi.es redondojose@uniovi.es vinuesa@uniovi.es cueva@uniovi.es
ABSTRACT
Although dynamic languages are becoming widely used due to the flexibility needs of specific software prod-
ucts, their major drawback is their runtime performance. Compiling the source program to an abstract machine’s
intermediate language is the current technique used to obtain the best performance results. This intermediate
code is then executed by a virtual machine developed as an interpreter. Although JIT adaptive optimizing com-
pilation is currently used to speed up Java and .net intermediate code execution, this practice has not been em-
ployed successfully in the implementation of dynamically adaptive platforms yet.
We present an approach to improve the runtime performance of a specific set of structural reflective primitives,
extensively used in adaptive software development. Looking for a better performance, as well as interaction with
other languages, we have employed the Microsoft Shared Source CLI platform, making use of its JIT compiler.
The SSCLI computational model has been enhanced with semantics of the prototype-based object-oriented com-
putational model. This model is much more suitable for reflective environments. The initial assessment of per-
formance results reveals that augmenting the semantics of the SSCLI model, together with JIT generation of
native code, produces better runtime performance than the existing implementations.
Keywords
Dynamic languages, structural reflection, prototype-based object-oriented computational model, Shared Source
CLI, JIT code generation.
1. INTRODUCTION
Since the appearance of the first abstract machine
(UNCOL, 1961 [Ste61]), the notion of using the
specification of a computational processor without
intending to implement it (abstract machine) has
been used in many different contexts [Die00]. The
main objective of the UNiversal Computer Oriented
Language (UNCOL) was simplifying compilers de-
velopment by employing a unique universal interme-
diate code.
A virtual machine involves a specific abstract ma-
chine implementation. The employment of specific
abstract machines implemented by different virtual
machines has brought many benefits to different
computing systems. The most relevant are platform
neutrality (USCD P-machine [Cla82] or Forth
[Moo74]), application distribution (ANDF, Architec-
ture Neutral Distribution Format [OSF91]), direct
support of high-level paradigms (Smalltalk-80 [Gol-
83], SECD [Lan64] or Warren Abstract Machine
[War83]) and application interoperability (PVM,
Parallel Virtual Machine [Sun90]).
1
Despite of the many benefits obtained from using
virtual machines, its main drawback has always been
execution performance. Consequently, there has been
considerable research aimed at improving the per-
formance of virtual machine’s application execution
compared to its native counterparts. Techniques like
adaptive Just In Time (JIT) compilation or efficient
and complex garbage collection algorithms have
reached such a point that Microsoft and Sun Micro-
systems identify this kind of platforms as appropriate
to implement commercial applications. Nowadays,
there are a lot of commercial languages and plat-
forms that employ the concept of virtual machine to
develop software products.
In parallel with the dominant virtual platforms (Sun’s
Java Virtual Machine and Microsoft .net) and its
type-safe programming languages (Java and C#), a
1
The development of is project is funded by Microsoft
Research as the second Rotor Request for Proposals,
awarded in 2004.
Permission to make digital or hard copies of all or part of
this work for personal or classroom use is granted without
fee provided that copies are not made or distributed for
profit or commercial advantage and that copies bear this
notice and the full citation on the first page. To copy oth-
erwise, or republish, to post on servers or to redistribute to
lists, requires prior specific permission and/or a fee.
.NET Technologies’2005 conference proceedings,
ISBN 
Copyright UNION Agency – Science Press, Plzen, Czech Republic
new approach of so called “dynamic languages” is
emerging (examples are Python [Ros03], Ruby
[Tho04] or Dylan [Sha96]). The main objective of
these languages is to model the dynamicity that is
commonly required in building software that is
highly context-dependent due to the mobility of both
the software itself and its users [ECO04]. Features
such as meta-programming, reflection, mobility, dy-
namic reconfiguration and distribution are the do-
main of dynamic languages. Because of the benefits
they offer, dynamic languages are employed in dif-
ferent scenarios such as adaptive programming
[Mer03], dynamic aspect-oriented programming
[Ort04] or high-level parallel software development
[Hin03].
Dynamic languages, which also use abstract machine
platforms, offer a much more relaxed type system at
compile time that Java, C#, or any other type-safe
language, in order to support their flexibility features
–most part of the type system is dynamic. The un-
questionable benefits of type-safe languages could
still be obtained with unit testing suites that are cur-
rently widely used –as an example PyUnit is the Py-
thon version of the well-known JUnit testing frame-
work. Using dynamic languages together with unit
testing suites, the programmer can benefit both from
the robustness of any type-safe language and from
the flexibility of its dynamic features when needed
[Mar03].
Dynamic Languages Performance
Looking for code mobility, portability and distribu-
tion facilities, dynamic languages usually employ the
concept of abstract machine. Since their computa-
tional model offers dynamic modification of its struc-
ture and code generation at runtime, the existing vir-
tual machine implementations are commonly devel-
oped by means of interpreters. Their flexibility and
dynamicity capabilities make JIT native code genera-
tion (and its dynamic optimization) a complex task.
The existing implementations of Python for the Mi-
crosoft .net platform (Python for .Net from the Zope
Community, IronPython, and the Python for .Net
research project from ActiveState) have been devel-
oped as compilers that generate virtual machine’s
intermediate code which simulates Python features
over the .net platform. The implementations that
have used the Java Virtual Machine (Jython or JPy-
thon) have also employed the same approach. Micro-
soft and Sun platforms were created to support static
languages that do not offer structural reflective fea-
tures such as adding attributes (fields) and methods
at runtime. As these virtual machines do not support
those primitives, additional code must be generated
to support these features.
ActiveState tried to modify different free implemen-
tations of the .net platform in order to compile Py-
thon Programming Language to .net native code, but
they abandoned the project because the abstract ma-
chine design “was not friendly to dynamic lan-
guages” [Ude03]. As Java and .net virtual machines
have been designed taking into account their static
features in order to obtain the highest runtime per-
formance, it is difficult to add dynamic features to
their existing implementations.
The main disadvantage of dynamic languages is run-
time performance. The process of adapting an appli-
cation at runtime, as well as the use of reflection,
induces a certain overhead at the execution of an
application [Pop01]. However, as it happened with
the implementation of Java Virtual Machine, speed-
ing up the application execution of dynamic lan-
guages might facilitate their inclusion in commercial
development environments. Since the research done
by Hölzle and Ungar in dynamic JIT optimizing
compilers applied to the Self programming language,
virtual machine implementations have become faster
by generating binary code at runtime [Höl94].
Nowadays, dynamic adaptive HotSpot optimizer
compilers combine fast compilation and runtime op-
timizations of those parts of the code that are exe-
cuted a higher number of times. These techniques
have made virtual machines a real alternative to de-
velop many types of software products.
The work presented in this paper employs these tech-
niques to natively support dynamic languages over a
virtual machine. We will show how we are incorpo-
rating reflective features to the Shared Source CLI
implementation of the Microsoft .net platform. Add-
ing dynamic reflective primitives to the platform
internals will make it possible to compile dynamic
languages directly to .net, obtaining performance
benefits of using JIT native code generation. At the
same time, applications developed in dynamic lan-
guages would be able to interoperate with any .net
application or component, regardless of its program-
ming language.
The rest of this paper is structured as follows. In the
next section, we present the Microsoft Shared Source
CLI and Section 4 introduces the set of reflective
primitives to be added. Section 4 briefly describes
the prototype-based object-oriented model as well as
an analysis of how it can be incorporated to the
SSCLI model. The specification of our new BCL
reflective namespace is described in section 5 and
section 6 summarizes the implementation issues. Fi-
nally, we analyze runtime performance (section 7)
and section 8 presents the ending conclusions.
2. SHARED SOURCE CLI
The Microsoft SSCLI, Shared Source Common Lan-
guage Infrastructure (also known as Rotor), is a
source code distribution that includes fully functional
implementations of both the ECMA-334 C# lan-
guage standard and the ECMA-335 Common Lan-
guage Infrastructure standard, various tools, and a set
of libraries suitable for research purposes [Stu03].
The source code can be built and run under Windows
XP, FreeBSD 4.5 or Mac OS X.
Rotor consists on 3.6 million lines of code that can
be divided into 4 groups:
The Execution Environment. This is the virtual
machine of the .net platform that includes the
JIT compiler, the garbage collector, the class
loaders and the common type system.
The Libraries. The SSCLI distribution includes
the source code of its Base Class Library (BCL),
runtime infrastructure and reflection (introspec-
tion) classes, networking and XML classes, and
floating point and extended array libraries.
Compilers and Tools. Rotor includes a C# com-
piler (ECMA-334) and a Jscript compiler written
entirely in C#.
Platform Abstraction Layer (PAL). This code
implies the abstraction layer between the runtime
environment and the operating system.
Excluding the PAL section, we have performed
modifications and enhancements in every part of the
Rotor structure to develop our project.
3. EXTENDING THE REFLECTIVE
CAPABILITIES OF ROTOR
Reflection has been recognized as a suitable tool to
aid the dynamic evolution of running systems, being
the primary technique to obtain the meta-
programming, adaptiveness, and dynamic reconfigu-
ration features of dynamic languages [Caz04]. Re-
flection is the capability of a computational system to
reason about and act upon itself, adjusting itself to
changing conditions [Mae87]. In a reflective system,
its computational domain is enhanced by its own
representation, offering at runtime its structure and
semantics as computable data.
The main criterion to categorize runtime reflective
systems is taking into account what can be reflected.
Following this classification, we can distinguish:
Introspection: The system’s structure can be
consulted but not modified. Both Java and .net
platforms offer this level of reflection. By means
of the
java.lang.reflect package (Java) and
System.Reflection namespace (.net), the pro-
grammer can get information about classes, ob-
jects, methods and fields at runtime.
Structural Reflection: The system’s structure can
be modified and the changes should be reflected
at runtime. An example of this kind of reflection
is the Python feature of adding fields –
attributes– or methods to both objects and
classes.
Computational (Behavioral) Reflection: The
system semantics can be modified, changing the
runtime behavior of the system. For instance,
metaXa –formerly called MetaJava [Gol97]– is a
Java extension that offers the programmer the
ability to dynamically modify the method dis-
patching mechanism. The mechanism most
commonly employed in this level of reflection is
Meta-Object Protocols (MOPs) [Kic91].
As mentioned above, the runtime reflective features
of Rotor are restricted to the introspection level.
However, the .net platform offers the facility to dy-
namically generate CIL code at runtime in a limited
way (it only permits to create new types, not adding
new methods to the existing classes) by means of its
System.Reflection.Emit namespace.
Dynamic languages offer the structural level of re-
flection in their computational model. This level of
reflection is the one employed by dynamic languages
to develop adaptive software. Much research on
MOPs has revealed that computational reflection
suppose a huge performance penalty in comparison
with the benefits it provides [Tan03]. At the same
time, many behavioral features could be simulated
with structural reflection (e.g., adapting method in-
vocation semantics could be substituted by a method
wrapping service developed with structural reflec-
tion).
Reflective Facilities
We have extended the .net CLI with a set of struc-
tural reflective primitives extensively used in dy-
namic languages, at the abstract machine level. A
new namespace has been added to the Base Class
Library (BCL):
System.Reflection.Structural.
We will show in Section 5 which are its specific
primitives, but its functionality can be grouped into:
Attributes manipulation. It can be modified not
only the structure of a class (altering the struc-
ture of all of its instances), but the composition
of a single object. Attributes may be added, de-
leted or replaced.
Methods manipulation. Methods of classes can
be added and erased dynamically. Therefore, the
set of messages accepted by an object could
change at runtime depending on their dynamic
context. At the same time, a new method could
be placed in a sole object. The body of these
new methods can be obtained as copies of the
existing ones, or it dynamically generated by
means of the
System.Reflection.Emit name-
space.
The programmer could combine these facilities with
the introspective services already offered by the .net
platform, making the CLI an ideal system to develop
language neutral adaptive software.
Conceptual Problems
There exist conceptual inconsistencies between the
class-based object-oriented computational model and
structural reflective facilities. These inconsistencies
were detected and partially solved in the field of ob-
ject-oriented database management systems. In this
area, objects are stored but their structure or even
their types (classes) could be altered afterwards, as a
result of software evolution [Ska87].
The first scenario of modifying class’s structure (at-
tributes) implies updating the composition of every
object that is an instance of this class. This mecha-
nism was defined as schema evolution in the data-
base field. The modification of class’s instances
could be performed when the class is modified (ea-
ger) or when the object is up to be used (lazy)
[Tan89]; it is only necessary to know at runtime the
class an object is instance of. The dynamic evolution
of class’s methods and attributes can produce situa-
tions where code access to attributes or methods that
do not exist in a specific execution point; these situa-
tions should be checked by a dynamic type checking
mechanism, employing exception handling.
Another possibility that a reflective model supports is
much more difficult to be modeled in a class-based
language. How can an object's structure be modified
without altering the rest of its class's instances? This
problem was detected in the development of MetaXa,
a reflective Java platform implementation [Gol97].
The approach they chose was the same as the
adopted by some object-oriented database manage-
ment systems: schema versioning [Rod95]. A new
version of the class (called “shadow” class in
MetaXa) is created when one of its instances is re-
flectively modified. This new class is the type of the
recently customized object.
This model causes different problems such as main-
taining the class data consistency, class identity, us-
ing class objects in the code, garbage collection, in-
heritance or memory consumption, involving a really
complex implementation difficult to manage [Gol97].
One of the conclusions of their research was that the
class-based object-oriented model does not fit well to
structural reflective environments. They finally stated
that the prototype-based model would express reflec-
tive features better than class-based ones [Gol97].
4. PROTYPE-BASED OO MODEL
In the prototype-based object-oriented computational
model the main abstraction is the object, suppressing
the existence of classes [Bor86]. Although this com-
putational model is simpler than the one based on
classes, there is no loss of expressiveness; i.e. any
class-based program can be translated into the proto-
type-based model [Ung91]. A common translation
from the class-based object-oriented model is by fol-
lowing the next scheme (Figure 1):
Similar object's behavior (methods of each class)
can be represented by trait objects. Their only
members are methods. Thus, their derived ob-
jects share the behavior they define.
Similar object's structure (attributes of each
class) can be represented by prototype objects.
This object has a set of initialized attributes that
represent a common structure.
Copying prototype objects (constructor invoca-
tion) is the same as creating instances of a class.
A new object with a specific structure and be-
havior is created.
In class-based languages where classes are first class
Point
x,y:Integer
draw()
move(x,y:Integer)
point:Point
x=245
y=-23
a) Class-based model
b) Prototype-based model
inheritance
Prototype Cloning
Point
pointPrototype
Method implementationmove
Method implementationdraw
0y
0x
-23y
245x
point
Trait
object
Prototype
object
Figure 1. Translation between the class and prototype based computational model.
objects (Java, Smalltalk or C#), classes are repre-
sented by objects at runtime (e.g., in the .net platform
instances of
System.Type are objects that represent
classes or another type). This demonstrates that, be-
sides not existing loss of expressiveness, the transla-
tion of the model is intuitive and facilitates applica-
tion interoperability, no matter whether the pro-
gramming language uses classes or not. This is the
reason why this model has been previously consid-
ered as a universal substrate for object-oriented lan-
guages [Wol96].
Finally, this object-oriented computational model
does model structural reflective primitives in a con-
sistent way –structural reflective languages such as
Moostrap [Mul93] or Self [Ung87] have employed
this model in a successful way [Ort05]. The proto-
type-based object model overcomes the schema ver-
sioning problem stated in Section 3.2. Modifying the
structure (attributes as well as methods) of a single
object is performed directly, because any object
maintains its own structure and even its specialized
behavior. As shared behavior is placed in trait ob-
jects, its customization implies the adaptation of
types (schema versioning).
p2
Point
point
Prototype
0y
0x
point
Method Implementationdistance
Method implementationmove
Method implementationdraw
3z
-23y
245x
methodrotate
2y
1x
Figure 2. Structural reflective modification of
objects.
Figure 2 shows an example scenario. The initial
point and p2 objects are clones of the pointProto-
type
and their shared behavior is placed in the Point
trait object. A new coordinate attribute has been
added only to the
point object. Employing the same
approach, only the
p2 object is capable to rotate its
coordinates. Finally, all the derived objects from the
Point trait object will be able to use the new dis-
tance
method.
Adapting Rotor’s Computational Model
We have seen how the prototype-based object-
oriented model is capable of modeling structural re-
flection in a coherent way. However, the .net plat-
form employs a class-based model all over the CLI.
Moreover, if we want to interoperate with any exist-
ing .net language or application, we must follow the
class-based model. Therefore, our approach consists
on continue using classes but the reflective primitives
will offer a semantic of a prototype-based object
model:
As classes are first class objects in the .net plat-
form, their structure is customized by means
their
System.Type instances. Altering their
methods produces adaptation of shared behavior
as if we were modifying a trait object in the pro-
totype-based object model. In case we adapt at-
tributes of
System.Type objects, what we obtain
is the customization of all the existing instances
of the class adapted (schema evolution). Look-
ing for a good runtime performance, we have
developed a lazy schema evolution mechanism
[Tan89].
Objects are treated as prototypes. Although in
the class-based object model it is not possible to
add specific behavior to a single object, neither
to modify its attributes without adjusting its class
structure, we permit to apply these structural re-
flective services to a specific class instance. Em-
ploying this model, we can dynamically add or
erase both methods and attributes to a specific
object, overcoming the abovementioned schema
versioning problem. Of course, any compiler of
a statically type-checked .net language (e.g., C#)
needs to be modified to make the most of these
reflective features; dynamic languages will em-
ploy them directly.
As an example, we show in Figure 3 a Python syn-
tactic approach of a program that uses this combina-
tion of the class-based and prototype-based object
model, when employing the structural reflective
primitives (last feature shown in the example code is
not really supported by the Python programming
language).
We first create a
Point class with its constructor and
the
move and draw methods. An instance is then cre-
ated (
point) and a draw message passed. Then we
modify the structure of a single object adding a new
z attribute and its respective draw3D method. Finally,
we add a new behavior to the
Point class (the getX
method) and a new
isShowing field to every Point
instance, obtaining the schema evolution mechanism
previously described.
5. EXTENDING THE BCL
The structural reflective features mentioned above
require the enhancement of the .net platform seman-
tics. We have first implemented all of them in a new
namespace called
System.Reflection.Structural.
The primitives were initially developed in C#, mak-
ing extensive use of the .net’s introspection facilities.
This first implementation has empirically demon-
strated the viability of the proposed computational
model, giving us a first assessment of performance.
class Point:
"Constructor"
def __init__(self, x, y):
self.x=x
self.y=y
"Move Method"
def move(self, relx, rely):
self.x=self.x+relx
self.y=self.y+rely
"Draw Method"
def draw(self):
print "("+str(self.x)+
","+str(self.y)+")"
point=Point(1,2)
point.draw() # (1,2)
# Modify attributes of a single object
point.z=3
print point.z # 3
# Modify methods of a single object
def draw3D(self):
print "("+str(self.x)+
","+str(self.y)+
","+str(self.z)+")"
point.draw3D=draw3D
point.draw3D() # (1,2,3)
# Modify methods of a class
def getX(self):
return self.x
Point.getX=getX
print point.getX() # 1
# Modify attributes of
# every Point instance
Point.isShowing=0
Figure 3. Example Python code using structural
reflection services.
This is a resume of the most significant elements we
have added to the BCL (all of them, static methods of
the
Structural utility class):
addMethod and removeMethod methods receive
an object or class (
System.Type) as a first pa-
rameter indicating whether we want to modify a
single object or a shared behavior. The second
parameter is a
MethodInfo object of the Sys-
tem.Reflection
namespace. This object
uniquely describes the identifier, parameters, re-
turn type, attributes and modifiers of a method.
The user could create a new method employing
the
System.Reflection.Emit namespace, and
add it to an object or class by means of its
Meth-
odInfo
.
The
invoke primitive executes the method of an
object or class specifying its name, return type
and parameters. When the programmer uses the
invoke method to pass a message to an object, it
is checked if the object has a suitable method. In
case it exists, it is executed; otherwise the mes-
sage is passed to its class (its trait object). A
MissingMethodException is thrown if the mes-
sage has not been implemented.
The
addField, getField and removeField
methods are used to modify the runtime structure
of single objects or their common schema
(classes). If the first parameter is an object, the
rest of instances of its class will not be modified.
Adding a field to a class ensures that all of the
existing instances contain the specified attribute;
removing it guarantees that none have that at-
tribute.
Employing these primitives, the code in Figure 4
shows the C# version of the Python reflective pro-
gram of Figure 3.
RuntimeStructuralFieldInfo rsfi = new Run-
timeStructuralFieldInfo("z",
typeof(int),3, FieldAttributes.Public);
Structural.addField(point,rsfi);
// Draw3D is the MethodInfo a new method
// created with System.Reflection.Emit
Structural.addMethod(point,draw3D);
Object[] pars={};
Structural.invoke(point,draw3D.ReturnType,
"draw3D",pars);
// getX is another MethodInfo object
Structural.addMethod(typeof(Point),getX);
Console.WriteLine(Structural.invoke(
point,getX.ReturnType,"getX",params) );
rsfi = new RuntimeStructuralFieldInfo(
"isShowing", typeof(bool),false, FieldAt-
tributes.Public);
Structural.addField(typeof(Punto), rsfi);
Figure 4. C# structural reflective program.
We have implemented other useful primitives such as
{
field, method}Exists, getFieldValue, al-
ter
{Method, Field} or getMethod, as well as addi-
tional classes such as
RuntimeStructucturalField-
Info
or {Member, Method, Field}Collection. Now
that we have confirmed that this set of primitives are
suitable to offer the adaptable computational model
presented, we are implementing part of them as an
enhancement of the semantics of specific CIL in-
structions. As an example, the
invoke primitive
should not be only part of the BCL interface; its se-
mantics must also be included in the
call and call-
virt
CIL statements. In order to achieve this func-
tionality we are also modifying the semantic analysis
module of the SSCLI C# compiler –it should be al-
lowed to invoke non-existing methods at compile
time.
6. IMPLEMENTATION
The complexity of Rotor implementation prevented
us from directly implementing the operations inside
the runtime environment. A set of steps were defined
to gradually incorporate structural reflection in Ro-
tor. Modifying different parts of the system one by
one –from BCL to the binary code generated at run-
time– has allowed us to refine the model using the
experience gained.
We have divided the development process into three
steps:
Step 1: BCL-level implementation. In this step
we have implemented all the reflective primi-
tives in C#, making use of .net introspective ca-
pabilities. The runtime environment was not
modified in this step. The programmer should
use all the reflective features explicitly by means
of the BCL.
Step 2: VM-level implementation. In this second
step we have moved the implementation of the
BCL primitives developed in the previous step
to an equivalent C implementation, included into
the execution environment. The BCL interface
was not modified, but the implementation was
included inside the virtual machine getting sig-
nificantly better runtime performance. We used
Rotor internal structures, data types and routines
to our advantage.
Step 3: JIT-level implementation. The final step
in our development has been modifying the Ro-
tor JIT code generation mechanism. We have ex-
tended some CIL instruction semantics modify-
ing the code generated by the JIT, in order to
support structural reflection of existing .net ap-
plications.
The Step 1 implementation employs a central data
structure that uses four C# hash-tables to store rela-
tionships between added members and their owners
(either classes or instances). When accessing mem-
bers, these hash-tables are consulted first and, if the
member has not been reflectively added, the rest of
the process continues searching in the class hierarchy
using introspection. If the top of the hierarchy is
reached without finding the appropriate member, a
MissingMemberException is thrown. This implemen-
tation is much easier than developing this code inside
the runtime environment, but its execution perform-
ance is significantly slower.
Once the first step was developed and tested, we pro-
ceeded to include the implementation of these reflec-
tive services inside the execution environment. The
most important decision to be done was finding the
suitable place to put the data structure that stored the
reflective information. Since direct object structure
manipulation turns to be much more difficult than we
expected, due to its fixed-size object design, we de-
cided to use each object’s
Syncblock to store reflec-
tive data. Thus, we assigned each object (and class) a
specific structure to store its reflective information.
Although the VM-level implementation improved
runtime performance considerably, reflective behav-
ior must still be explicitly stated by the programmer.
That is to say, it is not possible to reflectively adapt
legacy .net binary code, because structural reflection
must be explicitly used. We are currently working on
overcoming this lack, implementing the third step of
the development process.
Project Status
Structural reflective primitives are being included
into the CIL instruction semantics (3
rd
step). We have
already included the attribute-manipulation ones. The
new semantics has already been added to the
ldfld
and
stfld CIL statements of the platform.
The main idea to achieve the new behavior is to
modify the native code generated by the JIT com-
piler. Instead of the original code that uses statically
calculated member offsets, we generate a call to a
helper function. This function explores the object
structure in order to calculate member addresses us-
ing the reflective data included in the object’s
Syncblock
.
Finally, we are working on modifying the JIT com-
piler to support reflective manipulation of methods.
Our planned implementation will generate code to a
new helper function, which will return the method
address (depending on the stored reflective informa-
tion), performing the invocation of the returned ad-
dress.
7. PRIMARY PERFORMANCE AS-
SESSMENT
The use of a JIT compiler in a reflectively adaptive
environment could introduce performance benefits in
comparison with existing interpreted-based imple-
mentations. We have measured the performance of
our second step implementation in comparison with
four well-know Python platforms. This assessment
will give us an idea of the benefits that could be ob-
tained in the future.
We have measured execution time of all the primi-
tives described above in loops of 10,000 iterations,
removing any I/O and graphical routines [Bul00]. All
tests were carried out on a lightly loaded 3.2 GHz
iPIV hyper-threading system with 1 Gb of RAM run-
ning WindowsXP.
The specific well-known Python implementations
used in our tests were:
CPython 2.4 (commonly referred as simply Py-
thon): This is probably the most widely used Py-
thon interpreted implementation; it is called
CPython because it has been developed in C.
ActivePython 2.4.0. Another interpreted distri-
bution of Python (from ActiveState) available
for Linux, Solaris and Windows.
Jython 2.1 (formerly called JPython): A 100%
pure Java implementation of the Python pro-
gramming language. It is seamlessly integrated
with the Java 2 Platform.
IronPython 0.6: is a new promising implementa-
tion of the Python language targeting the Com-
mon Language Runtime (CLR). It compiles py-
thon programs into CIL bytecodes that run on ei-
ther Microsoft's .net or the Open Source Mono
platform. Its current release is a pre-alpha 0.6
version.
We have not used Zope’s Python for .net be-
cause it is not really the same approach as Jython
in Java; it provides an implementation of the Py-
thon language and runtime engine in pure Java.
Python for .net is not a re-implementation of Py-
thon, just an integration of the existing CPython
runtime with .NET. Neither have we employed
ActiveState Python for .net because they have
quit this research project caused by the poor per-
formance results obtained [Ude03].
Table 1 shows the measurement of each primitive
execution called 10,000 times, expressed in millisec-
onds. As we can appreciate in this table, Jython and
IronPython obtain the worst performance results in
all of the tests –IronPython do not implement dele-
tion of members, neither class manipulation. The
requirement to implement Jython as a 100% pure
Java offers a great interoperability with any Java
program, but it causes a significant performance pen-
alty. The same happens to IronPython: generating
CIL code that simulates the Python reflective model
over a platform that does not support it produces low
performance at runtime. Probably, this performance
penalty is caused by the amount of extra code that
must be generated to support the reflective model.
Figure 5 and Table 1 show how our BCL implemen-
tation of structural reflective primitives is faster than
the two systems that generate intermediate code:
Jython and IronPython. Note than, since the range of
values of Jython and IronPython are considerably
different from the rest of implementations, we have
separated both scales in Figure 5. Therefore, the val-
ues of these two implementations are shown on the
right of the figure, whereas the rest appear on the
left. Our BCL implementation is more than 30 times
faster than Jython.
0
500
1,000
1,500
2,000
2,500
3,000
3,500
4,000
4,500
1 3 5 7 9 1113151719
Jython
IronPython
BCL
ActivePython
CPython
JIT
0
5,000
10,000
15,000
20,000
25,000
30,000
35,000
40,000
45,000
Figure 5. Execution time (milliseconds) of each
primitive over different implementations.
Primitive Jython IronPython BCL ActivePython CPython
1. Add
int attributes to an ob
j
ect 20,679 36,032 1,632 590 541
2. Add Object attributes to an ob
j
ect 20,290 32,013 1,762 611 580
3. Add int attributes to a class 20,063 440 551 591
4. Add Object attributes to a class 20,320 460 661 610
5. Delete int attributes from an ob
j
ect 18,406 971 561 591
6. Delete Object attributes from an ob
j
ect 19,028 961 611 601
7. Delete int attributes from a class 18,536 200 540 561
8. Delete Object attributes from a class 18,896 210 581 560
9. Access attributes from an ob
ect 18,607 23,000 530 521 530
10. Access non-existin
g
attributes from an o
b
j
ect 20,019 21,017 1,191 641 601
11. Access attributes from a class 18,577 150 511 481
12. Access non-existin
g
attributes from a class 20,028 370 611 571
13. Add metho
d
s to an ob
j
ect 22,592 30,230 3,364 640 480
14. Add metho
d
s to a class 23,192 2,000 720 560
15. Invoke methods added to an ob
j
ect 20,624 24,010 3,564 760 600
16. Invoke non-existin
g
methods to an ob
j
ect 25,276 25,567 1,840 720 804
17. Invoke methods added to a class 21,064 2,680 720 680
18. Delete metho
d
s added to an ob
j
ect 18,504 1,240 520 520
19. Delete metho
d
s added to a class 18,464 280 520 520
Table 1. Measurement of 10,000 calls to each reflective primitives.
Figure 5 also illustrates how our system performance
is not as good as the native interpreter implementa-
tion (CPython and ActiveState). However, the BCL
implementation is the fastest when modifying class’s
structure. This is due to the laziness of the schema-
evolution mechanism we have implemented.
Best results are obtained by the two platforms that
interpret the Python code by means of a C implemen-
tation: ActiveState and CPython. Both obtain quite
similar results, which are significantly better than the
BCL version when using objects –the most typical
scenario– but worse when employing classes.
As we have mentioned above, we are currently in-
cluding the structural reflective primitives into the
JIT compiler. Although the project is still in an im-
mature point to release definitive performance re-
sults, we have enough information to get a first inter-
esting estimation. Executing the same test suite with
the new attribute semantics added to the SSCLI run-
time environment, employs the 15.76% average time
in comparison with the BCL version (the new im-
plementation is 10.88 times better that the first one).
Furthermore, the execution of JITted structural re-
flective primitives requires an average of 11.58 %
time in comparison with the time required in CPy-
thon. Figure 5 shows these values graphically (JIT).
Although we have not developed the addition and
deletion of methods in objects and classes, these first
results give us an initial estimation of how the use of
a JIT compiler can be employed to obtain good per-
formance of runtime adaptive applications. Certainly,
since we have only developed part of the reflective
computational model of Python –e.g. we have not
implemented the Python feature of modifying the
class an object is instance of–, the results obtained
could not be directly compared with execution per-
formance of complete implementations of the Python
programming language. What our work has revealed
is that JIT compilation techniques are really appro-
priate to improve the performance of adaptive sys-
tems and languages. The key point is to modify the
semantics of the abstract machine instead of generat-
ing intermediate code that simulates this adaptive
behavior. Adding this semantics at the JIT compiler
level is complex task, but appears to be worth the
effort.
8. CONCLUSIONS
Abstract machines have been widely employed to
design programming languages because of the many
advantages they offer. Although performance was
the main drawback in the past, modern techniques
like adaptive (hotspot) Just In Time compilation have
overcome this weakness. That is one of the reasons
why virtual machine platforms are nowadays com-
mercially used.
Currently, due to the special flexibility and adap-
tively needs of specific systems, the so called “dy-
namic languages” are becoming more and more used.
These languages also make use of the process of
compilation to an abstract-machine’s intermediate
code. However, due to the complexity of its flexible
semantics, the virtual machine is commonly devel-
oped as an interpreter.
Looking for better performance results, there have
been different attempts to implement Python and
other highly dynamic languages for.net and Java
platforms. They have resulted in systems with really
poor performance, so bad that they were considered
unusable. Some of them have abandoned this idea.
We have evaluated two, Jython and IronPython, in
comparison with other two interpreted versions –
CPython and ActivePython. The interpreted versions
were much faster than the JIT compiled ones, when
measuring their reflective features. Despite these
results, we think that the use of a JIT compiler in
reflective adaptive environments could obtain better
performance than interpreting the intermediate lan-
guage. Since Java and .net platforms have not been
designed with that purpose, modifying the semantics
of the abstract machine (and, therefore, the imple-
mentation of the virtual machine) might produce the
expected benefits.
In order to obtain a first performance assessment, we
have developed a set of structural reflective primi-
tives as part of the BCL .net platform. These primi-
tives implement the semantics of the prototype-based
object-oriented model over the SSCLI class-based
platform. This first implementation obtains better
performance results that generating CIL code, be-
cause implies quite less code to execute at runtime.
Finally, we have performed an initial assessment of
performance results obtained with the inclusion of
part of the structural reflective primitives into the
SSCLI runtime environment. This initial evaluation
gives us an estimation of the performance benefits
that will be obtained in the future, when the whole
reflective semantics will be included in the code gen-
erated by the JIT compiler. Although we have only
added part of the reflective features of the Python
programming language, the assessment presented
reveals that using an adaptive-designed platform in
conjunction with a JIT compiler involves important
performance benefits to implement dynamic lan-
guages.
9. REFERENCES
[Bor86] Borning, A.H. Classes versus Prototypes in
Object-Oriented Languages. In Proceedings of
the ACM/IEEE Fall Joint Computer Conference,
pp. 36-40, 1986.
[Bul00] Bull, J. M., Smith, L.A., Westhead, M.D.,
Henty, D.S., and Davey, R.A. A Benchmark Suite
for High Performance Java. Concurrency: Prac-
tice and Experience 12, pp. 375-388, 2000.
[Caz04] Cazzola, W., Chiba, S., and Saake, G. In
ECOOP Workshop on Reflection, AOP, and
Meta-Data for Software Evolution. Research Re-
ports on Mathematical and Computing Sciences.
Department of Mathematical and Computing Sci-
ences, Tokyo Institute of Technology, 2004.
[Cla82] Clark, R., and Koehler, S. The UCSD Pascal
Handbook. Prentice-Hall, Englewood Cliffs,
1982.
[Die00] Diehl, S., Hartel, P., and Sestoft, P. Abstract
Machines for Programming Language Implemen-
tation. Elsevier Future Generation Computer Sys-
tems, Vol. 16(7), 2000.
[ECO04] ECOOP’04 Workshop on Object-Oriented
Language Engineering for the Post-Java Era:
Back to Dynamicity. ECOOP 2004 Workshop
Reader, Lecture Notes in Computer Science, Vol.
3344, Oslo, Norway, 2004.
[Gol83] Goldberg, A., and Robson, D. Smalltalk-80,
The Language and Its Implementation. Addison-
Wesley, Reading, MA, 1983.
[Gol97] Golm, M., and Kleinöder, J. MetaJava - A
Platform for Adaptable Operating- System
Mechanisms. Lecture Notes in Computer Science
1357, Springer-Verlag, pp.507-507, 1997.
[Hin03] Hinsen, K. High-Level Parallel Software
Development with Python and BSP. Parallel
Processing Letters, Vol. 13, No. 3, pp. 473-484,
2003.
[Höl94] Hölzle, U., and Ungar, D. A Third-
Generation Self Implementation: Reconciling Re-
sponsiveness with Performance. In Proceedings
of the ACM OOPSLA Conference, Portland, OR,
1994.
[Kic91] Kiczales, G. The Art of the Metaobject Pro-
tocol. The MIT Press, 1991.
[Lan64] Landin, P.J. The mechanical evaluation of
expressions. Computer Journal 6 (4), pp. 308-
320, 1964.
[Mae87] Maes, P. Computational Reflection. PhD.
Thesis, Laboratory for Artificial Intelligence,
Vrije Universiteit Brussel, Belgium, 1987.
[Mar03] Martin, R.C. Are Dynamic Languages Go-
ing to Replace Static Languages? Artima Devel-
oper, April, 2003.
[Mer03] Mertz, D., and Simionato, M. Metaclass
Programming in Python – Pushing Object-
Oriented Programming to the next level. IBM de-
peloperWorks. February 2003.
[Mor74] Moore, C. Forth: A new way to program a
mini-computer, Astronomy & Astrophysics Sup-
plement: 15, pp. 497-511, 1974.
[Mul93] Mulet, P., and Cointe, P. Definition of a
Reflective Kernel for a Prototype-Based Lan-
guage. In the International Symposium on Object
Technologies for Advanced Software, Kanazawa
(Japan), 1993.
[Ort04] Ortin, F., and Cueva, J.M. Dynamic Adapta-
tion of Application Aspects. Journal of Systems
and Software 71(3), pp. 229-243,2004.
[Ort05] Ortin, F., and Diez, D. Designing an Adapt-
able Heterogeneous Abstract Machine by means
of Reflection. Information and Software Tech-
nologies 47(2), pp. 81-94, 2005.
[OSF91] Open Systems Foundation. OSF Architec-
ture-Neutral Distribution Format Rationale, 1991.
[Pop01] Popovici, A., Gross, Th., and Alonso, G.
Dynamic Homogenous AOP with PROSE, Tech-
nical Report, Department of Computer Science,
ETH Zurich, Switzerland, 2001.
[Rod95] Roddick, J. A Survey of Schema Versioning
Issues for Database Systems. Information and
Software Technology 37 (7), 383-393, 1995.
[Ros03] Rossum, G.V., Fred, L., and Drake, Jr. The
Python Language Reference Manual. Network
Theory, 2003.
[Sha96] Shalit, A., Moon, D., and Starbuck, O. The
Dylan Reference Manual. Addison-Wesley, 1996.
[Ska87] Skarra, A.H., and Zdonik, S.B. Type Evolu-
tion in an Object-Oriented Database. Research
Directions in Object-Oriented Programming,
MIT-press, pp. 393-415, 1987.
[Ste61] T.B. Steel Jr. A first version of UNCOL. In
Western Joint Computing Conference, pp. 371–
378. New York, 1961.
[Stu03] Stutz, D., Neward, T., and Shilling, G.
Shared Source CLI Essentials. O’Reilly, 2003.
[Sun90] Sunderam, V. S. PVM: A Framework for
Parallel Distributed Computing. Concurrency:
Practice and Experience 2(4), pp 315-339, 1990.
[Tan89] Tan, L., and Katayama, T. Meta operations
for type management in object-oriented databases
- a lazy mechanism for schema evolution. In Pro-
ceedings of First International Conference on
Deductive and Object-Oriented Databases,
DOOD, pp. 241-258. 1989.
[Tan03] Tanter, E., Noyé, J., Caromel, D., and
Cointe, P. Partial behavioral reflection: spatial
and temporal selection of reification. In Proceed-
ings of the 18th annual ACM SIGPLAN confer-
ence on Object-Oriented Programming, Systems,
Languages, and Applications (OOPSLA). Cali-
fornia, USA, 2003.
[Tho04] Thomas, D., Fowler, C, and Hunt, A. Pro-
gramming Ruby. 2nd Edition. Addison-Wesley
Professional, 2004.
[Ude03] Udell, J. Dynamic languages and virtual
machines. InfoWorld, August, 2003.
[Ung87] Ungar, D., and Smith, R. B. SELF: The
Power of Simplicity. In OOPSLA Conference
Proceedings. SIGPLAN Notices, 22 (12), pp.
227-241, 1987.
[Ung91] Ungar, D., Chambers, D., Chang, B.W., and
U. Hölzl. Organizing Programs without Classes.
Lisp and Symbolic Computation, Kluwer Aca-
demic Publishers, pp. 223-242, 1991.
[War83] Warren, D.H.D. An abstract Prolog instruc-
tion set. Technical Note 309, SRI International,
Menlo Park, CA, 1983.
[Wol96] Wolczko, M., Agesen, O., and Ungar, D.
Towards a Universal Implementation Substrate
for Object-Oriented Languages, Sun Microsys-
tems Laboratories, 1996.
... The zRotor project is aimed at providing direct support of dynamic languages by a JIT-compiler virtual machine that already provides efficient execution of a wide set of programming languages [78]. First, we developed in C# all the reflective primitives provided by common dynamic languages inside the BCL. ...
Article
Dynamically typed languages are becoming increasingly popular for different software development scenarios where runtime adaptability is important. Therefore, existing class-based platforms such as Java and .Net have been gradually incorporating dynamic features to support the execution of these languages. The implementations of dynamic languages on these platforms commonly generate an extra layer of software over the virtual machine, which reproduces the reflective prototype-based object model provided by most dynamic languages. Simulating this model frequently involves a runtime performance penalty, and makes the interoperation between class- and prototype-based languages difficult.Instead of simulating the reflective model of dynamic languages, our approach has been to extend the object-model of an efficient class-based virtual machine with prototype-based semantics, so that it can directly support both kinds of languages. Consequently, we obtain the runtime performance improvement of using the virtual machine JIT compiler, while a direct interoperation between languages compiled to our platform is also possible. In this paper, we formalize dynamic inheritance for both class- and prototype-based languages, and implement it as an extension of an efficient virtual machine that performs JIT compilation. We also present an extensive evaluation of the runtime performance and memory consumption of the programming language implementations that provide dynamic inheritance, including ours.
Conference Paper
This paper presents a step forward on a research trend focused on increasing runtime adaptability of commercial JIT-based virtual machines, describing how to include dynamic inheritance into this kind of platforms. A considerable amount of research aimed at improving runtime performance of virtual machines has converted them into the ideal support for developing different types of software products. Current virtual machines do not only provide benefits such as application interoperability, distribution and code portability, but they also offer a competitive runtime performance. Since JIT compilation has played a very important role in improving runtime performance of virtual machines, we first extended a production JIT-based virtual machine to support efficient language-neutral structural reflective primitives of dynamically typed programming languages. This article presents the next step in our research work: supporting language-neutral dynamic inheritance for both statically and dynamically typed programming languages. Executing both kinds of programming languages over the same platform provides a direct interoperation between them.
Conference Paper
Full-text available
Fine-grained adaptable operating-system services can not be implemented with today's layered operating-system architectures. Structuring a system in base level and meta level opens the implementation of operating-system services. Operating-system and run-time services are implemented by meta objects which can be replaced by other meta objects if the application requires this.
Article
UNCOL--UNiversal Computer Oriented Language--is being designed as an empirical , pragmatic aid to the solution of a fundamental problem of the digital data processing business: automated translation of programs from expressions in an ever increasing set of problem oriented languages into the machine languages of an expanding variety of digital processing devices. By application of a program called a generator , specific to a given problem language, program statements in this problem language are transformed into equivalent UNCOL statements, independent of any consideration of potential target computers. Subsequently, without regard to the identity of the original problem language, the UNCOL statement of the problem is processed by a program called a translator , which is specific to a given target computer, and the result is an expression of the original problem solution in the machine language of the desired processor. The advantage of this apparent complication over the current procedure of employing a program called a compiler for direct transformation from problem language to machine language is evident when one examines the number of languages and machines involved and the not inconsiderable expense of translation program construction. If there are M problem languages and N machines, then M+N compilers are required and only M+N generators and translators. In order to arrive at sensible specifications for UNCOL, certain limitations in its scope are essential. Accordingly, UNCOL is designed to cope with only those problem language and machine language characteristics that can reasonably be expected to enjoy general use in the next decade. Any broader approach shows promise of leading to elegant, impractical results. A glance at the preliminary specifications for UNCOL shows a language akin to a symbolic assembly language for a register-free, single address, indexed machine. The specific commands are few in number and simple in construction, depending on a special defining capability for the expression of more elaborate instructions. The data referencing scheme is complex, allowing the application of a signed index to the primary address, and permitting both the primary and index parts to be delegated to an indefinite level. Each item of data, either input or calculated, must be described as to type, range precision and the like by special data descriptive syntactical sentences in the language. These descriptions, additionally, provide information concerning ultimate storage allocation as well as indicators of contextual meaning for the explicit commands. Supplementary to the instructions and data descriptions are certain declarative sentences, inessential to the explicit statement of the problem solutions being translated, designed to provide information useful to the translator in the introduction of computational efficiency into the object program.
Smalltalk-80, The Language and Its Implementation MetaJava -A Platform for Adaptable Operating-System Mechanisms
  • A Goldberg
  • D Robson
  • M Golm
  • J Kleinöder
[Gol83] Goldberg, A., and Robson, D. Smalltalk-80, The Language and Its Implementation. Addison- Wesley, Reading, MA, 1983. [Gol97] Golm, M., and Kleinöder, J. MetaJava -A Platform for Adaptable Operating-System Mechanisms. Lecture Notes in Computer Science 1357, Springer-Verlag, pp.507-507, 1997. [Hin03] Hinsen, K. High-Level Parallel Software Development with Python and BSP. Parallel Processing Letters, Vol. 13, No. 3, pp. 473-484, 2003. [Höl94] Hölzle, U., and Ungar, D. A Third- Generation Self Implementation: Reconciling Responsiveness with Performance. In Proceedings of the ACM OOPSLA Conference, Portland, OR, 1994.
Designing an Adaptable Heterogeneous Abstract Machine by means of Reflection [OSF91] Open Systems Foundation. OSF Architecture-Neutral Distribution Format Rationale Dynamic Homogenous AOP with PROSE
  • F Ortin
  • D Diez
  • A Popovici
  • Th Gross
[Ort05] Ortin, F., and Diez, D. Designing an Adaptable Heterogeneous Abstract Machine by means of Reflection. Information and Software Technologies 47(2), pp. 81-94, 2005. [OSF91] Open Systems Foundation. OSF Architecture-Neutral Distribution Format Rationale, 1991. [Pop01] Popovici, A., Gross, Th., and Alonso, G. Dynamic Homogenous AOP with PROSE, Technical Report, Department of Computer Science, ETH Zurich, Switzerland, 2001. [Rod95] Roddick, J. A Survey of Schema Versioning Issues for Database Systems. Information and Software Technology 37 (7), 383-393, 1995.
  • R Clark
  • S Koehler
  • Ucsd The
  • Pascal Handbook
  • S Diehl
  • P Hartel
  • P Sestoft
[Cla82] Clark, R., and Koehler, S. The UCSD Pascal Handbook. Prentice-Hall, Englewood Cliffs, 1982. [Die00] Diehl, S., Hartel, P., and Sestoft, P. Abstract Machines for Programming Language Implementation. Elsevier Future Generation Computer Systems, Vol. 16(7), 2000. [ECO04] ECOOP'04 Workshop on Object-Oriented Language Engineering for the Post-Java Era: Back to Dynamicity. ECOOP 2004 Workshop Reader, Lecture Notes in Computer Science, Vol. 3344, Oslo, Norway, 2004.