# Wednesday, 16 March 2011
.NET/C# Generics History

Yesterday Don Syme posted a short history of .NET/C# generics.

Wow. Just wow.

I knew MSR was instrumental in getting generics into the CLR, but not that it was this critical.

Thank you Don Syme, Andrew Kennedy, et al.

Wednesday, 16 March 2011 06:41:40 (W. Europe Standard Time, UTC+01:00)  #    Comments [0]
# Thursday, 03 March 2011
IKVM.NET 0.46 Release Candidate 0

Finally, after way too long, the first 0.46 release candidate is available.

What's New (relative to IKVM.NET 0.44):

  • Integrated OpenJDK 6 b22.
  • Added -Xreference: option to ikvm.exe and ikvm.runtime.Startup.addBootClassPathAssemby() API.
  • The binaries zip now includes lib/ikvm-api.jar to avoid having to run ikvmstub to get access to the IKVM Java APIs.
  • Ported parts of fdlibm to C# to use for StrictMath methods tan, cbrt, floor, pow, hypot, expm1 and log1p.
  • Add support for serializing .NET exceptions in Java. We don't serialize the actual object, but a placeholder instead, to avoid having to implement full .NET serialization interop.
  • Added IL optimization step to code generator.
  • Added SynchronizationContext for AWT event thread.
  • Many IKVM.Reflection improvements and bug fixes.
  • Many Swing/AWT improvements.
  • Implemented IPv6 support (.NET only) for java.net package APIs.
  • The sun.boot.class.path system property now points to VFS to allow javac to work (although a bit slow, because the boot class files are dynamically generated on demand).
  • Resource and generated stub classes are now projected into the virtual IKVM home directory, to make code that assumes that resources live in jars happy.
  • Improvements to @ikvm.lang.Internal handling.
  • Many minor improvements.

Fixes since previous development snapshot:

  • IKVM.Reflection: Added limited support for #- metadata stream ("uncompressed" table heap). ParamPtr table is not yet implemented.
  • IKVM.Reflection: Fixed bug in CustomAttributeData.__ToBuilder(). Array values should be unwrapped.
  • IKVM.Reflection: Added __GetBlob() API extension to allow custom attribute arguments to be parsed/used even when some of the argument types are missing.
  • IKVM.Reflection: Fixed stack height computation bug. For a newobj the parameters should be popped before the new object is pushed. Previously we could set the maximum stack height one slot too high.
  • IKVM.Reflection: Added ConstructorBuilder.__SetSignature() API extension to allow constructor to be defined before the parameter types are available and to allow return type custom modifiers.

Binaries available here: ikvmbin-0.46.0.0.zip

Sources: ikvmsrc-0.46.0.0.zip, openjdk6-b22-stripped.zip

Thursday, 03 March 2011 14:33:03 (W. Europe Standard Time, UTC+01:00)  #    Comments [1]
# Wednesday, 02 March 2011
New Development Snapshot

OpenJDK 6 b22 has been integrated.

Changes:

  • Integrated OpenJDK 6 b22.
  • Fixed runtime to not convert assembly class loader construction exceptions into critical failure, because critical failure is of dubious value and exception might be handleable by client code.
  • Fixed ProtectionDomain. Use Assembly.EscapedCodeBase to construct CodeSource url, instead of unescaped CodeBase.
  • Allow @ikvm.lang.Internal methods to implement an interface method.
  • Fixed ikvmc to ignore @ikvm.lang.Internal annotation on interface methods and emit a warning.
  • IKVM.Reflection: Fixed exception table sorting bug.
  • IKVM.Reflection: Allow mcs to avoid mdb/pdb writer dependencies.
  • IKVM.Reflection: Added Mono Ref.Emit compatibility feature to allow modules currently in use to be overwritten.

Binaries available here: ikvmbin-0.45.4078.zip

OpenJDK 6 b22 stripped sources: openjdk6-b22-stripped.zip

Wednesday, 02 March 2011 09:25:17 (W. Europe Standard Time, UTC+01:00)  #    Comments [0]
# Friday, 25 February 2011
CLR Type Names

Type names look like a simple concept. Every type has a unique name within the assembly that defines it.

It turns out that there is a slight complication. Even though the CLI specification and the reflection API suggest that a type name is simply a string, in reality it is a pair of strings: { namespace, name }

Here's some code that uses IKVM.Reflection to generate an interesting assembly:

using IKVM.Reflection;
using IKVM.Reflection.Emit;

class Program {
  static void Main() {
    var universe = new Universe();
    var ab = universe.DefineDynamicAssembly(new AssemblyName("Test"), AssemblyBuilderAccess.Save);
    var modb = ab.DefineDynamicModule("Test", "Test.dll");
    modb.__DefineType("A.B", "C").CreateType();
    modb.__DefineType("A", "B.C").CreateType();
    ab.Save("Test.dll");
  }
}

This creates a valid (and verifiable) assembly containing two different types, both named A.B.C.

If you disassemble this assembly with ildasm and the resulting IL is reassembled with ilasm you won't end up with the same assembly. I don't know if there are any obfuscators that use this trick, but maybe they should.

Reflection APIs assume that the last dot in the type name separates the namespace from the name, so doing Type.GetType("A.B.C") will return the first type {"A.B", "C"}. You can get the second type by enumerating all types in the assembly.

Note that static binding just works, because in that case the {namespace, name} pair is specified explicitly.

Friday, 25 February 2011 09:09:01 (W. Europe Standard Time, UTC+01:00)  #    Comments [0]
# Monday, 21 February 2011
Exception Performance Part 3

This is the final part of three part series on exception performance that started in 2008. Previous parts are:
Exception Performance Part 1
Exception Performance Part 2

Let's introduce a slight variation of ExceptionPerf1 where we throw 10000 exceptions instead of 100000 and throw the exception from a method, instead of directly in the loop.

using System;
using System.Diagnostics;

class ExceptionPerf5 {
  static void Main() {
    var sw = Stopwatch.StartNew();
    for (int i = 0; i < 10000; i++) {
      try {
        Foo();
      } catch { }
    }
    sw.Stop();
    Console.WriteLine(sw.ElapsedMilliseconds);
    Console.ReadLine();
  }

  private static void Foo() {
    throw new Exception();
  }
}

When this is compiled with the standard Debug configuration in Visual Studio 2010 it yields the following performance numbers (times in milliseconds) when run either with Ctrl-F5 (i.e. no debugger attached) or F5 (debugger attached):

  HotSpot 1.6 .NET 2.0 .NET 4.0
  x86 x86 x64 x86 x64
Ctrl-F5 25 286 413 292 305
F5   16950 16134 45223 114790

For comparison, the table also includes the time it takes to run the equivalent code in HotSpot 1.6 Client VM on x86.

As we saw in the previous two articles on exception performance, .NET is significantly slower in handling exceptions, so that is not surprising. However, what is surprising is how much the overhead is of simply having the debugger attached.

Another depressing thing to note is that things have gotten much worse with .NET 4.0.

Unfortunately, many developers have the habit of always running their code in the debugger, so when they first try code IKVM.NET compiled code from within Visual Studio they often get a very bad impression of the performance, simply because the debugger sucks.

I considered filing a connect bug for this, but you know they'll just close it as By Design. I guess the CLR is only a Common Language Runtime, if you language doesn't use exceptions for control flow.

Monday, 21 February 2011 09:46:12 (W. Europe Standard Time, UTC+01:00)  #    Comments [5]
# Thursday, 17 February 2011
Mono 2.10 Released

Mono 2.10 was released this week. It includes a version of the Mono C# compiler that uses IKVM.Reflection as its back end.

Last year in the two days before FOSDEM I hacked mcs to use IKVM.Reflection and while at FOSDEM I showed this hack to Miguel and was met with his usual enthusiasm and he told me that he was already planning on talking to me about using IKVM.Reflection for mcs.

In May, Kornél Pál did a, much more complete than my hack, prototype port of mcs to IKVM.Reflection and that resulted in a number of IKVM.Reflection bug fixes and enhancements.

Last November, Marek Safar starting work on integrating IKVM.Reflection support for real and made sure that everything was production ready. This resulted in some mcs restructuring and yet more IKVM.Reflection fixes, features and also performance improvements.

The result of all this is that now IKVM.Reflection is a great library to use if you have a codebase that has both a dynamic and a static compilation mode (as both IKVM.NET and mcs have), because you can easily share the bulk of your code between System.Reflection and IKVM.Reflection without having to suffer from the (significant) limitations of System.Reflection for the static scenario.

Thursday, 17 February 2011 06:59:38 (W. Europe Standard Time, UTC+01:00)  #    Comments [0]
# Tuesday, 15 February 2011
New Development Snapshot

I decided to delay the 0.46 release to wait for OpenJDK 6 build 22, which will be a security update and should be available soon. In the mean time, here is a new development snapshot.

Changes:

  • Fixed some compilation warnings.
  • Fix for the timezone used to convert .NET DateTime to Java timezone in the JDBC-ODBC bridge.
  • Fix for bug # 3129981.
  • Fixed .NET 4.0 build verification issue.
  • IKVM.Reflection: Enabled framework unification support.
  • IKVM.Reflection: Avoid re-firing the assembly resolve event for missing assemblies.
  • IKVM.Reflection: Several performance tweaks by Marek Safar.
  • IKVM.Reflection: Added feature to (optionally) allow resolving of missing methods.
  • IKVM.Reflection: Added [Constructor|Method]Builder.__ReleaseILGenerator() API to eagerly bake the method body and release the ILGenerator.

Binaries available here: ikvmbin-0.45.4062.zip

Tuesday, 15 February 2011 07:54:58 (W. Europe Standard Time, UTC+01:00)  #    Comments [1]
# Tuesday, 25 January 2011
New Development Snapshot

A new snapshot with OpenJDK 6 b21 integrated. If you want to build from cvs, from now on you'll need the OpenJDK 6 b21 sources (available in the zip linked below).

Changes:

  • Integrated OpenJDK 6 b21.
  • IKVM.Reflection: Mark modules as executable when running on Mono.

Binaries available here: ikvmbin-0.45.4042.zip

OpenJDK 6 b21 stripped sources: openjdk6-b21-stripped.zip

Tuesday, 25 January 2011 06:07:07 (W. Europe Standard Time, UTC+01:00)  #    Comments [0]
# Monday, 24 January 2011
New Development Snapshot

More IKVM.Reflection fixes to support mcs. Many thanks to Marek for his work.

OpenJDK 6 b21 has been released, so after this snapshot that needs to be integrated and we start preparing for the 0.46 release.

Changes:

  • Several AWT fixes.
  • Image improvements.
  • Added ikvm.runtime.Startup.addBootClassPathAssemby() API.
  • Added -Xreference: option to ikvm.
  • Fix scope id in IPv6 server socket accepted connections.
  • Added support for loading resources from assemblies loaded in the LoadFrom context.
  • Treat unrecognized ikvmc options as errors, instead of warnings.
  • Added ikvm.internal.NotYetImplementedError and throw that instread of sun.reflect.generics.reflectiveObjects.NotImplementedException.
  • Fixed bug that caused reflecting on a field of an unfinished type to throw an exception.
  • IKVM.Reflection: Fix for big endian systems. Thanks to Marek Safar for reporting this.
  • IKVM.Reflection: Add support for NETCF in rendering pseudo DllImportAttribute (i.e. skip fields that don't exist).
  • IKVM.Reflection: Changed __ReadTypeName() to __TryReadTypeName() because it should fail when the type is a nested type (because the name of a nested type cannot be expressed by namespace + name).
  • IKVM.Reflection: Type.Namespace property should not returned escaped string.
  • IKVM.Reflection: Added Type.__Name and Type.__Namespace properties to allow the real (from the ECMA CLI point of view) namespace and names of types to be queried (for TypeDef and TypeBuilder only).
  • IKVM.Reflection: Fixed a bunch of type name escaping bugs.
  • IKVM.Reflection: Added support for nested types that use a namespace.
  • IKVM.Reflection: Type.Name/Namespace/FullName fixes to make everything more compatible (including bugs) with .NET reflection.
  • IKVM.Reflection: Added ModuleBuider.__DefineType() and TypeBuilder.__DefineNestedType() APIs.
  • IKVM.Reflection: Prevent external subclassing. It's not part of the design to support that, now it is also enforced.
  • IKVM.Reflection: Fixed copy/paste bug. A TypeRef pointing to ModuleRef should resolve the type in that module, not the assembly.
  • IKVM.Reflection: Fixed Type.GetNestedType() and be more compatible with .NET reflection (i.e. ignore the namespace).
  • IKVM.Reflection: Added Universe.CreateMissingAssembly() to create an assembly that automatically resolves any type that it is supposed to contain.
  • IKVM.Reflection: Added Type.__IsMissing and Type.__ContainsMissingType properties to detect missing types.
  • IKVM.Reflection: Patch by Marek Safar to implement framework unification for managed implementation of Universe.CompareAssemblyIdentity().
  • IKVM.Reflection: Improved partial trust support.
  • IKVM.Reflection: Added support for saving to a stream instead of a file.
  • IKVM.Reflection: Fixed type resolution to match namespace and name separately, like Mono and the CLR do.
  • IKVM.Reflection: Added Universe.EnableMissingTypeResolution() to enable missing type resolution in all assemblies.
  • IKVM.Reflection: Various fixes to improve support for building mscorlib.

Binaries available here: ikvmbin-0.45.4041.zip

Monday, 24 January 2011 07:08:30 (W. Europe Standard Time, UTC+01:00)  #    Comments [8]
# Monday, 27 December 2010
New Development Snapshot

Several IKVM bug fixes as well as more IKVM.Reflection bug fixes and a couple of new APIs for issues found by Marek during his Mono C# compiler work.

I've also modified the build process to generate a stub jar for the IKVM.NET specific Java APIs, to remove the need to run ikvmstub on IKVM.OpenJDK.Core.dll. The stubs are now available in the binaries zip file (ikvm/lib/ikvm-api.jar).

  • Fixed ikvmstub to not mark abstract methods as native.
  • Changed registry access (for java.util.prefs) on Windows to be more compatible with JDK and UAC aware.
  • Added support for encoding incorrect annotation values and reporting the exception back when the annotation is queried.
  • Fixed ikvmstub encoding of boolean annotation method defaults.
  • System.mapLibraryName() should throw NPE for null arg.
  • Ported parts of fdlibm to C# to use for StrictMath methods tan, cbrt, floor, pow, hypot, expm1 and log1p.
  • Several awt fixes.
  • Added ikvmstub -out: option and improved usage message.
  • Added ikvmstub -namespace: option to only process types in the specified namespace(s).
  • Generate lib/ikvm-api.jar to expose the ikvm API more easily to java code (by shipping this jar as part of ikvmbin.zip).
  • Fix for NullReferenceException in ClassLoaderWrapper.LoadGenericClass() if type parameter type cannot be loaded.
  • IKVM.Reflection: Delay creation of tokens for base type and interfaces until CreateType, to avoid problems when a non yet completely defined type is used as a base type or interface.
  • IKVM.Reflection: Don't clear properties and events fields during CreateType.
  • IKVM.Reflection: Call CreateType on TypeBuilder created by DefineInitializedData.
  • IKVM.Reflection: Emit Param table records is correct order.
  • IKVM.Reflection: HashAlgId in assembly manifest record turns out to be useless (SHA1 is always used).
  • IKVM.Reflection: Custom attributes applied to GenericTypeParameterBuilder were attached to the type token, instead of the type parameter token.
  • IKVM.Reflection: Added support for reading decimal parameter default values with ParamterInfo.RawDefaultValue.
  • IKVM.Reflection: Added support for emitting assemblies with non-existing cultures.
  • IKVM.Reflection: Fixed several ILGenerator bugs when __CleverExceptionBlockAssistance is used.
  • IKVM.Reflection: Removed NotImplementedException for unsorted GenericParam table, because we don't really care.
  • IKVM.Reflection: Exception block end label should be marked regardless of exception assistance mode.
  • IKVM.Reflection: The end label of an exception block should always be marked, because you can also backward branch to it.
  • IKVM.Reflection: Don't emit unnecessary leave instructions in "clever" mode.
  • IKVM.Reflection: Added ModuleBuilder.__AddAssemblyReference() API to explicitly add assembly references. This can be used in conjunction with AssemblyBuilder.__AddModule() to add the assemblies referenced by the module to the assembly manifest module. It's not clear to me whether this is required, but Microsoft does it and Assembly.GetReferencedAssemblies() only returns the assemblies referenced from the manifest module.
  • IKVM.Reflection: Added Module.__GetReferencedAssemblies() API.
  • IKVM.Reflection: Sort PropertyMap table. Not required by the spec, but .NET does it and Mono requires it.
  • IKVM.Reflection: Made CustomAttributeData more lazy (when all custom attributes are queried, regardless of type).
  • IKVM.Reflection: Added CustomAttributeData.__ReadTypeName() to get the type name without resolving it.
  • IKVM.Reflection: Fixed copy/paste bug in AssemblyBuilder.GetTypeImpl(). The modules list was iterated twice instead of looking through both modules and addedModules.
  • IKVM.Reflection: AssemblyResolve event should fire before resolving to AssemblyBuilder.
  • IKVM.Reflection: Don't create duplicate ClassLayout table records when using the DefineType overload that specifies the size and also applying a StructLayoutAttribute.

Binaries available here: ikvmbin-0.45.4013.zip

Monday, 27 December 2010 06:53:23 (W. Europe Standard Time, UTC+01:00)  #    Comments [0]