# Saturday, May 10, 2003
Eclipse on Mono

Zoltan Varga just posted the following to the ikvm-developers list:


I got Eclipse running under IKVM under Mono. A screenshot, Makefiles etc. can be found here:


The port uses a JNI provider written in C which works with mono. Eclipse startup up+shuts down in about 1 minute on an 1Ghz PC, while consuming about 90MB of memory. It works with Mono 0.24 and current mono CVS.

I made some modifications to IKVM which are in the attached patch.

Could they be applied to the official version?

The modifications are:

- ikvm.build: fix case of directory names

- ClassLoaderWrapper.cs: Create Assemblies with Run flag, so the

runtime can apply some memory saving optimizations.

- TypeWrapper.cs: Cache field lookups

- classpath.cs: Make shared library loading work under UNIX

There is one other issue: Mono does not yet support the

GetLoadedModules() method, so this has to be commmented out in classpath.cs and in Handler.java.

BTW: The IBM RVM project includes a nice JNI testsuite:


The Mauve test status of mono:

191 of 7294 tests failed

Would it be possible to post the Mauve test results of IKVM somewhere (with -verbose) so I can compare it to the Mono version?

have fun


Wow! This is great news.

Saturday, May 10, 2003 1:33:40 PM (W. Europe Daylight Time, UTC+02:00)  #    Comments [0]
# Friday, May 9, 2003

Stuart asks:

Can IKVMC handle Class.forName if the target class is in an assembly that isn't directly referenced by the assembly making the call?

Yes, but then you have to specify the assembly qualified name of the class. For example:

Class.forName("System.Windows.Forms.Form, " +
    "System.Windows.Forms, " +
    "Version=1.0.3300.0, " +
    "Culture=neutral, " +

Another alternative, when the class hasn't been compiled to an assembly, is to instantiate a class loader and use that to load the class:

URL[] classpath = new URL[1];
classpath[0] = new URL("...");
ClassLoader loader = new URLClassLoader(classpath);
Class clazz = loader.loadClass("...");

Currently, when ikvm.exe isn't used to start your application you don't have an application class loader that loads classes from the directories specified in the CLASSPATH environment variable.

Friday, May 9, 2003 11:16:56 AM (W. Europe Daylight Time, UTC+02:00)  #    Comments [2]
# Monday, April 28, 2003
DotGNU & New Snapshot

Saturday I joined the DotGNU IRC meeting to discuss their Java support. We decided to make sure that our efforts will be interoperable.
They are working on a Java source to IL compiler and this complements IKVM's byte code to IL compiler nicely. We'll be working together to create a standard format for remapping Java classes to .NET classes and define custom attributes to express Java semantics that don't map directly onto the .NET standard attributes.

I made new source and binaries snapshots available. Not many changes:

  • invokespecial byte code now checks for null references before calling the method. I intend to write an item on invokespecial in the future, because it is quite an interesting instruction with a bit of a history.
  • Improved method overriding handling for methods that are less accessible than the method they override. Java allows this, but .NET doesn't. It is handled by giving the overriding method the same (or better) accessibility as the overriden method.
    IMHO this is a design flaw in the CLR, because it makes it a breaking change to widen the access of a virtual method in a new version of a type.
  • Improved ikvmc's handling of -recurse and added wildcard support to file arguments.
Monday, April 28, 2003 10:54:39 AM (W. Europe Daylight Time, UTC+02:00)  #    Comments [2]
# Friday, April 25, 2003
Stuart posted a nice comment:

Well, I now am a legitimate happy IKVM user.

I just found myself in a situation where I wanted to be able to call nrdo code (nrdo is a Java tool for database access, http://nrdo.sab39.org/) from a web application, that also had to read its input files from a windows machine. The individual parts of that aren't a problem: nrdo is reasonably well librarified so it's perfectly possible to call it from a web application, and it's perfectly possible to run Java code on windows (indeed, that's how our normal development is done).

But we don't have any windows machines running any Java application servers, and spawning a Java process from inside ASP.NET didn't appeal very much :)

It's funny how I've been following IKVM for a while but it still took ages before the obvious solution hit me. I compiled a nrdo.dll (okay, this took me longer than I thought because the -recurse option to ikvmc didn't do what I thought it would and neither did path\*.class), created an ASP.NET web application in Visual Studio, added references to classpath.dll, nrdo.dll and ik.vm.net.dll, and started typing.

It was a seriously schizophrenic experience (but in a good way!). I don't normally use an IDE for Java coding so it was the first time I'd ever seen intellisense for my nrdo libraries. And you can get seriously confused as to which language you're using when you write C# code that looks like this:

using java.util;

for (Iterator i = myList.iterator(); i.hasNext(); ) {
MyThing foo = (MyThing) i.next();

But it worked, and it took me about an hour to solve what I'd expected to be a pretty complex problem. The schizophrenic aspect is just an artefact of IKVM being really, *really* good at its job!

Thanks! Patches to make ikvmc more intuitive are always welcome of course ;-)

Friday, April 25, 2003 8:53:56 AM (W. Europe Daylight Time, UTC+02:00)  #    Comments [3]
# Monday, April 14, 2003

I checked in my value type changes, along with a bunch of other changes and made new snapshots.

Here are the highlights:

  • (limited) support for using value types
  • support for calling methods with ByRef arguments
  • better support in map.xml for redirecting to Java classes
  • moved parts of StringHelper & ObjectHelper from C# to Java
  • updated to be compatible with current Classpath cvs

Source and binaries snapshots are in the usual locations.

Monday, April 14, 2003 12:32:48 PM (W. Europe Daylight Time, UTC+02:00)  #    Comments [1]
# Friday, April 11, 2003
More value type feedback

Stuart Ballard commented on yesterday's entry:

I definitely think these changes should be included.

As I understand it, without them it is impossible to use C# structs, enums and other value types in Java code at all, and also impossible to call methods which require ref or out parameters.

This is correct (except that enums were already usable from Java, they are visible as classes containing public static final int fields and arguments are just int arguments).

To me this scenario is very disappointing - the dream of IKVM, for me, was to see Java as a first-class .NET language while still remaining "true java". Eliminating support for value types and reference arguments clashes with the first of these goals; requiring a hacked compiler violates the second.

I'd even go so far as to ask whether it would be possible to actually *write* a "struct" in java, along the lines of the following:

public class JavaStruct extends system.ValueType {
int structMember;

Presumably it would be possible for ikvm to detect classes that inherit from ValueType and compile them as structs rather than classes...

I briefly considered it, but dismissed it at the time because I didn't need it. You've convinced me to take another look at this.

To summarize, not only do I think this is cool functionality (even if the implementation *is* a little bit of a hack) I think it's extremely important functionality and I'd like to see further fine-tuning of the "hack" and further enhancements to the functionality, rather than leaving it out entirely.

The reason I didn't comment earlier, though, is that I don't really have any right to comment, as I don't actually use IKVM at all (although I may in the future to save my co-developers from downloading the JRE to run a single java program). I'm only commenting now to provide at least some positive feedback on the idea of checking it in, so that you don't throw it out on the basis that nobody thinks it's valuable (although of course I fully respect your right to throw it out for any other reason).

Thanks for commenting, I really appreciate it! I will go ahead and polish up the changes and check them in.

Friday, April 11, 2003 1:16:11 PM (W. Europe Daylight Time, UTC+02:00)  #    Comments [0]
# Thursday, April 10, 2003
More on value types

David Jeske commented on the previous entry

Can ValueType local variables be treated as ValueTypes instead of pointers to ValueTypes? If this were the case, then av[1] could be the pointer to the interior of the valuetype array, and av[1].foo = 42; would work correctly. This would also make the IL for using local ValueType variables most similar to how it would turn out if it had been C#.

The boxing/unboxing would only occur when coercing/converting from a local variable of a ValueType to a ReferenceType (i.e. Object foo = v; )

Remember that I'm working with a standard Java compiler. All the value type support is in the byte code to CIL compiler, because of this I wanted to stay as close to the Java semantics as possible, to prevent problems caused by Java compiler differences (there really isn't any guarantee that local variables in the source end up as local variables in the byte code). Also, the current design a lot easier to implement ;-)

Having said that, treating locals as value types still wouldn't allow av[1].foo = 42; to work. This would require the aaload instruction to return a pointer to the array element, in itself this isn't hard but the introduction of pointers would complicate the type system greatly.

Ultimately, the reason I added this (limited) value type support, is to enable me to write more "native" Java methods in Java. I haven't checked in these changes and I'm still not sure that doing so would be a good idea. Without Java compiler support it will always be a hack.

Thursday, April 10, 2003 12:26:21 PM (W. Europe Daylight Time, UTC+02:00)  #    Comments [1]
# Saturday, April 5, 2003
Value Types & Reference Arguments

I've added experimental support for using value types and reference arguments in Java. The challenge is to do this without having to build a new Java compiler.

Here is a value type I constructed in C# for testing purposes:

public struct ValType {

  public int foo;


  public ValType(int f) {

    foo = f;



  public override string ToString() {

    return "ValType:" + foo;



  public static void Increment(ref ValType v) {




Here is a Java example that uses value types and calls a method with a reference argument:

import system.DateTime;


class ValTest {

  static DateTime dt;


  public static void main(String[] args) {

    ValType v = new ValType(0);

    v.foo = 42;



    ValType[] av = new ValType[1];

    av[0] = v;




    dt = DateTime.get_Now();

    DateTime d = new DateTime(0);

    d = AddDay(d);





  private static DateTime AddDay(DateTime dt) {

    return dt.AddDays(1);



How is this code compiled? Whenever a value type is loaded from a field or array, instantiated or returned from a method it is boxed. Local variables are references to boxed instances of the value type. When a boxed value type instance is assigned to a field, stored in an array or passed to a method, it is unboxed. Referenced method arguments are exported by NetExp as arrays.

Let's look at a few examples:

    ValType v = new ValType(0);

Is compiled as:


newobj     instance void ValType::.ctor(int32)

box        ValType


The local variable v is of type object and contains a reference to the boxed value.

    v.foo = 42;

Assigning a field in the boxed value:


ldc.i4.s   42


unbox      ValType


stfld      int32 ValType::foo

After loading the reference to the boxed value, the constant (42) gets stored in a temporary local and then reference gets unboxed, this leaves a managed pointer to the interior of the boxed value on the stack and the stfld instruction uses this pointer to set the field.

    av[0] = v;

Setting an array element:





ldelema    ValType


unbox      ValType

ldobj      ValType

stobj      ValType

The address of element 0 of the array is loaded, v is unboxed and copied into the array.


Calling a method with a reference argument:


stloc.s    V_4

ldloc.s    V_4


ldelema    ValType

call void ValType::Increment(valuetype ValType&)

The Java code passes an array and the byte code to CIL compiler takes the address of the first element of the array and passes that to the method. BTW, if the array is of length zero, ldelema throws a System.IndexOutOfRangeException.

Pros and Cons of this Approach

The advantage of enabling value type of reference arguments are that it is easier to leverage .NET framework code from within Java code (targetted at IKVM.NET) and it enables me to write more glue code in Java.

The downside is the non-intuitive behavior. Compare these two lines:

    v.foo = 42;

    av[0].foo = 42;

The first line does what you'd expect, it assigns 42 to the field foo of the boxed value type. However, the second line has no effect, because it results in a boxed copy being loaded from the array, that boxed copy's field foo is assigned the value 42, but it is not copied back into the array. This also applies to fields, only local variables contain boxed value types and can be manipulated safely.

Finally, a small problem with arrays of value types is that the Java compiler will happily compile:

    Object[] array = new ValueType[1];

Obviously this isn't legal.

I'd like to get feedback from people who either like or dislike this new functionality. Of course, any ideas for alternative approaches would be most welcome too.

Saturday, April 5, 2003 4:03:00 PM (W. Europe Daylight Time, UTC+02:00)  #    Comments [1]
# Monday, March 31, 2003
I completed most of the Socket code and fixed a few bugs. Mauve results (with current Classpath CVS code): 172 of 7707 tests failed.

I updated to BlogX rev 20 and this means that the RSS will now contain xhtml:body (for the new entries). Chris says: "So, if you favorite aggregator isn't showing the full text of my blog, send them a mail and get them to support <xhtml:body>!"

I've updated the source and binaries snapshots
Monday, March 31, 2003 5:06:44 PM (W. Europe Daylight Time, UTC+02:00)  #    Comments [2]
# Wednesday, March 19, 2003

At first sight, it might seem that System.arraycopy is not a very interesting method, but once you dig into it, it turns out to be an interesting case study.

.NET has a very similar method Array.Copy and one of its overloads has the exact same signature as its Java cousin, but throws slightly different exceptions and there is a tiny difference in behavior. So an initial naïve implementation of System.arraycopy would look as follows:

public static void arraycopy(object src, int srcStart,
       object dest, int destStart, int length) {
    try {
        Array.Copy(src, srcStart, dest, destStart, length);
    } catch(ArgumentNullException) {
        throw new NullReferenceException();
    } catch(ArgumentException) {
        throw new ArrayIndexOutOfBoundsException();
    } catch(ArrayTypeMismatchException) {
        throw new ArrayStoreException();
    } catch(InvalidCastException) {
        throw new ArrayStoreException();

This works fairly well, but it has two problems. The first problem is that it is too powerful. Array.Copy allows widening conversions for primitive types. This means, for example, that it is possible to copy a byte array to an int array. Java doesn’t allow this. The second problem is more subtle, Javadocs for System.arraycopy say:

“Otherwise, if any actual component of the source array from position srcPos through srcPos1 cannot be converted to the component type of the destination array by assignment conversion, an ArrayStoreException is thrown. In this case, let k be the smallest nonnegative integer less than length such that src[srcPosk] cannot be converted to the component type of the destination array; when the exception is thrown, source array components from positions srcPos through srcPosk-1 will already have been copied to destination array positions destPos through destPosk-1 and no other positions of the destination array will have been modified.”

In other words, if an ArrayStoreException is thrown, all elements prior to the one that failed are copied. In contrast to this, the .NET documentation for Array.Copy says:

“If this method throws an exception while copying, the state of destinationArray is undefined.”

So to be strictly correct, we cannot rely on Array.Copy to implement copying of reference arrays that might throw an exception during copying. Here is a better implementation of System.arraycopy:

public static void arraycopy(object src, int srcStart,
       object dest, int destStart, int length) {
    // fast path if source and destination are same
    if(src != dest) {
        Type type_src = src.GetType();
        Type type_dst = dest.GetType();
        // fast path if arrays are of identical type
if(type_src != type_dst) {
            if(len < 0) {
                throw newArrayIndexOutOfBoundsException();
            try {
                Object[] src1 = (Object[])src;
                Object[] dst1 = (Object[])dest;
                for(; len > 0; len--) {
                    dst1[destStart++] = src1[srcStart++];
            } catch(InvalidCastException) {
                throw JavaException.ArrayStoreException();
    try {
        Array.Copy((Array)src, srcStart,
                   (Array)dest, destStart, length);
    } catch(ArgumentNullException) {
        throw new NullReferenceException();
    } catch(ArgumentException) {
        throw new ArrayIndexOutOfBoundsException();
    } catch(InvalidCastException) {
        throw new ArrayStoreException();

I think this is a correct implementation of System.arraycopy. It’s still not perfect though, because it turns out to be really slow. Here is a small benchmark:

class arraycopy {
    public static void main(String[] args){
        test(10, 10000000);
        test(100, 1000000);
        test(1000, 100000);

    private static void test(int size, int count) {
        int[] a = new int[size];
        int[] b = new int[size];
        long start = System.currentTimeMillis();
        for(int i = 0; i < count; i++) {
            System.arraycopy(a, 0, b, 0, a.length);
        long end = System.currentTimeMillis();
        System.out.println(end - start);

Here are the results for the JDK 1.1 Symantec JIT, JRE 1.4.1 HotSpot Client VM and IKVM running on .NET 1.0:


JRE 1.4.1














It’s obvious that for small arrays, the overhead is really large. The reason this is so much slower than the Java version is probably because of the cost of the call to GetType combined with the extra checking going on inside Array.Copy. If Sun had only provided overloaded versions of System.arraycopy for each type of primitive array, we wouldn’t need to do so much type checking! It turns out that even without these overloads we can still get the same result (in many cases), because the verifier often knows the types of the arguments. In compiles.cs I added some code to the invokestatic handler to check for invocations of System.arraycopy and if the array arguments are known to be primitive arrays, the call gets redirected to a more efficient arraycopy implementation.

Here is where the call to System.arraycopy in the above benchmark gets redirected to:

public static void arraycopy_primitive_4(Array src,
       int srcStart, Array dest, int destStart, int len) {

    try {

        checked {

            Buffer.BlockCopy(src, srcStart << 2,
                       dest, destStart << 2, len << 2);



    } catch(ArgumentNullException) {

        throw new NullReferenceException();

    } catch(OverflowException) {

        throw new ArrayIndexOutOfBoundsException();

    } catch(ArgumentException) {

        throw new ArrayIndexOutOfBoundsException();



No more calls to GetType and no more casts to Array are required. In addition, since we know that the arrays are both of the same primitive type, we can use the more efficient Buffer.BlockCopy instead of Array.Copy.

Here are the performance results for the new implementation:


JRE 1.4.1














Obviously a worthwhile improvement. For completeness, here are the performance results for doing the arraycopy with a simple for loop (i.e. in a modified version of the benchmark that doesn't call System.arraycopy , but instead has simple simple method that copies the array using a for loop):

for(; len > 0; len--)
    src[srcStart++] = dest[destStart++];


JRE 1.4.1














Wednesday, March 19, 2003 6:00:14 PM (W. Europe Standard Time, UTC+01:00)  #    Comments [0]