Welcome to MSDN Blogs Sign in | Join | Help

Sharing Silverlight Assemblies with .NET Apps

At the recent PDC, Scott Guthrie announced in his Silverlight 4 keynote that we had implemented a new feature, to enable developers to share certain assemblies between Silverlight and .NET. There are many differences between Silverlight and full .NET including WPF, and this new feature doesn’t solve those differences – in those cases, you’ll still need to compile your code twice. But in some cases, developers will write code that only uses features whose behavior is identical between Silverlight and full .NET, and in those cases, we want to enable that code to be shared. This post provides more detail on that sharing, and explains how developers can target it, and what the restrictions are.

Developer Scenario

Today, many developers write code that is intended to run on both Silverlight and .NET. A good example would be validation code: when writing a client-server application, you want to validate the data at the client (to make sure the user gets quick feedback) and then re-validate it again at the server (to make sure a rogue client implementation can’t send back bad data.) Today, in order to get that scenario to work, developers need to compile their source for Silverlight and also for .NET. In addition to dual-compilation, developers need to manage and deploy those assemblies separately, ensuring that they end up being deployed to the right places and consumed by the right platform (Silverlight or .NET). Today’s model is certainly workable, but it is not ideal.

We’ve heard from many developers that you want something better. We’ve also read quite a number of blog and forum posts stating the same. We’ve even seen some interesting workarounds to try and make the situation better for themselves and other developers. Cool! Specifically, developers want to write and compile their code once and deploy it as part of both their Silverlight and .NET apps, without having to dual-compile or worry about paying attention to the compilation target. This ability has the obvious benefit of avoiding duplication of effort for a number of the steps in your development and deployment processes.

Portability Explained

We named this new feature “assembly portability”, given that the feature allows your code to be “ported” between both Silverlight and .NET. Portability provides the ability to compile your source with the Silverlight tools, and run your built assemblies on both the Silverlight and .NET runtimes. This feature doesn’t change the underlying implementation of either the Silverlight or .NET runtimes; instead, if you write code that only uses APIs that have the same behavior across Silverlight and .NET, it allows you to use one set of binaries to target both. But how do you know if the APIs you are using are compatible? We have identified five key assemblies that are compatible between Silverlight and .NET. (The Silverlight UI layer is of course not one of these – there are some important differences between Silverlight UI and WPF.)

Like most features we build, we had a lot of choice about how to design the feature, and which scenarios we would enable. At the heart of the feature, a major design choice was to enable portability from Silverlight to .NET. The motivation for this choice was that Silverlight exposes an API subset of .NET, and so assemblies built with Silverlight should “just work” on .NET, whereas the reverse direction (.NET assemblies running on Silverlight) would have proven more technically challenging (for us all).

Another important design choice was identifying the set of Silverlight/.NET assemblies that developers could safely use, while still maintaining binary comparability. We looked at the scenarios that would both most benefit from portability, and would be straightforward for developers to use. We looked at a bunch of scenarios, including: the most low-level, typical business logic, networking and also UI. We decided we would start with the most fundamental and requested scenarios for this release. As a result, for .NET 4 and SL4, we have enabled portability for a significant set of low-level assemblies that we believe will enable a variety of interesting scenarios.

For SL 4 and .NET 4, we have made the following assemblies portable:

  • Mscorlib
  • System
  • System.Core
  • System.ComponentModel.Composition
  • Microsoft.VisualBasic

Note again that the Silverlight surface area for these assemblies is what we made portable. There are a great number of types and members in the .NET surface area that cannot run on Silverlight. As a result, you need to write code that targets the Silverlight versions of these assemblies in order to get this scenario to work.

Also note that there may be some behaviors that are not strictly identical across both platforms. We’ve worked to avoid those behaviors, however, those differences are sometimes very subtle and difficult to identify. Please do contact us if you do see behavioral differences between Silverlight and .NET, for portable APIs, which are bothering you.

Visual Studio Experience

Like all .NET features, it is important that we provide good tooling support in Visual Studio. This feature can be used in Visual Studio, in just the way that one might imagine. Developers should write their portable logic in Silverlight Class Library projects, and then are free to reference such projects from both Silverlight and .NET application projects. To clarify, on the .NET side, you can reference such a library from any kind of .NET project (Ex: WPF, winforms, WCF, WF, ASP.NET, …).

The only caveat is that the support in Visual Studio was implemented in such a way that you need to click a few extra times to get a reference to a portable project correct setup. For VS 2010, you must rely on browsing to the binary – AKA “binary reference” – that is built from the Silverlight class library to setup a reference. You cannot just reference the project itself – AKA “project to project reference”. Note that this restriction only exists for .NET apps, and not Silverlight ones.

The following are the basic steps to follow to enable the use of portable code in Visual Studio 2010, followed by a set of screen caps that hopefully make it super clear what to do.

Steps:

  1. Setup projects
    1. Create .NET application
    2. Create or add existing Silverlight class library project
    3. Build Silverlight project
  2. Establish portable code reference
    1. Reference Silverlight class library binary from the .NET project
  3. Code
  4. Run App!

Screen Caps:

Step 1 – Setup projects

clip_image001[4]

Step 2 -- Establish portable code reference to the other project (required going up and back down the directory structure to the Silverlight library project).

image

image

 

Step 3 – Code

image

Step 4 – Run App!

clip_image002[8]

Note: My app is a WPF app that is intended to display how many days there are until the Vancouver 2010 Olympics start, from today. The Silverlight library is the one that does the actual countdown calculation, and is (naturally) usable in both .NET and Silverlight apps. Cool!

Looking Forward and Feedback

It is great to see so much energy around both .NET and Silverlight, and particularly around the maximal sharing of code across the platforms. I encourage you to use this new scenario to its fullest extent, and to communicate back to us where you’d like to see the feature expanded in the future.

We are aware of some scenarios that are not currently enabled to be portable, but that developers will probably run up against pretty quickly. The most obvious ones are XML, networking, calling WCF web-services and UI code. Another interesting one is portable XAML. It would be really useful to hear from you on the specific scenarios that you would like to implement in portable code, but cannot implement due to the limitations that I’ve mentioned. I’d also like to hear why you saw being able to implement that scenario in portable code as being such a benefit. Your feedback will help guide us with future changes in the portable code space.

 

      CLR Inside Out - In-Process Side-by-Side

      MSDN Magazine December 2009 Cover 

       

      The new installment of the “CLR Inside Out” column in MSDN Magazine is now available on line.  This month we have an article from Jesse Kaplan and Luiz Fernando Santos on In-Process Side-by-Side.  The article contains details on this new .NET Framework 4 feature and the problems it solves.  It is especially useful for add-in or COM component developers and those wishing to write managed shell extensions.

      You can find a list of all “CLR Inside Out” articles here.  It’s a new link this month, as MSDN Magazine has updated their site.  As always, please let us know if you have topics you’d like to see covered in the column.

      CLR-Related PDC 2009 Sessions

      If you’re at PDC this year and are reading the CLR Team’s blog, there are a few sessions that might be of interest to you.

       

      ·         Future of Garbage Collection is a session by the creator of the CLR’s GC, Patrick Dussud.  Come hear him talk Wednesday at 1:00PM in Petree Hall C.

      ·         Code Contracts and Pex: Power Charge Your Assertions and Unit Tests is a session by Mike Barnett and Nikolai Tillmann from Microsoft Research about some of the latest advances in these tools for design-by-contract and unit-testing.  It’s on Tuesday at 4:30PM in 408A.

      ·         Building Sensor- and Location-Aware Applications with Windows 7 and .NET Framework 4 includes a discussion of the Location APIs that were added to .NET Framework 4.  It’s being presented by Gavin Gear on Tuesday at 4:30PM in 515A.

      Posted by CLRTeam | 1 Comments

      How to Make the Most of Your .NET Server Code

      One of our team’s field engineers recently sent a link to a Channel 9 video: Steve Michelotti of e.magination on High Performance Web Solutions. This company built a 64-bit web server that handles over 3 billion transactions a day and guarantees a 250 ms response time.  And it goes without saying that they built it on top of .NET.

      The team optimized their code to avoid implicit allocations, pool and reuse objects and allocate large collections directly on the Large Object Heap. But they still saw some latencies that were greater than their contract allowed. So they worked with their field engineer and the GC team to get a new feature implemented in .NET 3.5 SP1 that let them work around the problem.

      The problem comes from the size of their managed heaps. When you try to manage memory on a 16 GB server it can take a few seconds to run through the heaps. There’s not much you can do on a single machine besides keeping your heaps reasonably sized. Having millions of objects in memory is expensive. But their architecture is such that they can direct requests from the web server to any of a set of identical application servers. This means that they can take any individual server offline for the few seconds it takes to do a full collection. All they needed is to know when a GC is going to happen and when it’s completed. Full GC notifications is a new feature in 3.5 SP1 that gave e.magination necessary insight into the GC’s behavior that lets them redirect requests away from servers that are doing full GCs.

      This video is only about 20 minutes long but it’s packed with great insights into how to make the most of your .NET server code. It shows the team at e.magination doing a fantastic job of analyzing and tuning their system for optimum performance. I found it interesting and inspiring. I hope you do too.

      Posted by CLRTeam | 2 Comments
      Filed under: ,

      CLR Inside Out - Exploring the .NET Framework 4 Security Model

       

      The new installment of the “CLR Inside Out” column in MSDN Magazine is now available on line.  This month we have an article from Andrew Dai on Exploring the .NET Framework 4 Security Model.  This article discusses how the new .NET Framework 4 security model makes it easier to work with partially trusted code.

      You can find a list of all “CLR Inside Out” articles here.  As always, please let us know if you have topics you’d like to see covered in the column.

      Visual Studio 2010 – Beta 2 : Announcements

      ·         Visual Studio 2010 and .NET Framework 4 Beta 2 availability – The Visual Studio 2010 and .NET Framework 4 Beta 2 will be available to MSDN subscribers on Monday, October 19th, with general availability on October 21st.

       

       

      ·         Launch date for Visual Studio 2010 and .NET Framework 4 – The official launch of Visual Studio 2010 and .NET Framework 4 is March 22nd, 2010.

       

      ·         Visual Studio 2010 pricing, licensing and packaging details Microsoft is announcing a new packaging lineup and licensing options for MSDN and Visual Studio 2010, including the “Ultimate Offer.” For more information on the new packaging, licensing, and pricing of Visual Studio 2010 and MSDN, visit http://microsoft.com/visualstudio.

       

      ·         MSDN redesign, Microsoft’s premier developer networkMicrosoft is unveiling a renovated MSDN, which includes new benefits for all MSDN subscribers. Benefits for MSDN subscribers include:

       

      -          A more community-driven, modern resource to help developers maximize their success on the Microsoft platform.

      -          Azure compute hours

      -          eLearning

       

       

      Automatically Capturing a Dump When a Process Crashes

      I recently received the following question from a customer:

       

      “During our test runs (which might run for hours), if a process crashes, we’d like to create full memory dumps for later diagnosis. Can I configure the machine to do this automatically?”

       

      I’ve actually gotten this question numerous times over the past couple of years. It comes in various forms but the general scenario is: A user wants to be able to diagnose application crashes and the environment does not lend itself to live debugging. The latter criterion could be for a number of reasons, but the most common I see are:

      ·         We have an intermittent failure in production and want to gather a dump to debug the issue offline.

      ·         I’m running a bunch of tests and when one crashes I don’t want to interrupt the whole run to diagnose the issue at failure time. Let’s just get gather some information for triaging.

      ·         Our issue isn’t reproducible under a debugger. E.g. a stress bug.

       

      These essentially reduce to: You want to get as much data as you can, while minimizing the impact to the environment. Given these requirements, the solution I find meeting most people’s needs is to configure a just-in-time (JIT) debugger to launch, grab a dump, and exit whenever a process crashes.

       

      Support for just-in-time debugging has been in the CLR since V1x and in the OS for as long as I can remember. The basic idea behind a JIT debugger is: when a process crashes, launch and attach a debugger so you can figure out why.

       

      There are registry keys which provide this general ability for both managed and native code (support for the latter might actually be in Win.ini for 9x/Me). If your application is written in managed code (which is the case I’m often presented) you might ask, “My application is managed code, why do I care about native code?” Given that even the most simple managed applications run native code (e.g. the runtime itself), if your requirement is to gather data for any crash, you’ll need to set the keys for both types of code. In CLR V4 we’ve actually unified the key which controls the managed JIT debugger with the native one. However, that change does not change my guidance since, for the time being, we’ll be living in a world where V2 managed code exists alongside V4.

       

      How do I configure the debugger?

       

      1.       Download and install the latest “Debugging Tools for Windows.”

      a.       If you’re running a 64-bit OS, you’ll want both the 32- and 64-bit versions*

      b.      You can either install the entire set of tools on the machine (it’s a quick, small install) or you can install to one machine and copy “cdb.exe” from the install directory to any number of target machines.

       

      *Note: My sample .reg files below assume you install the 32-bit debugger to c:\debuggers\x86\ and the 64-bit version to c:\debuggers\x64\.

       

      2.       Create/set the following registry keys and values (If you’re working on a 64-bit version of Windows, you’ll need to set these keys under the Wow6432node as well.†):

      a.       Key: HKLM\Software\Microsoft\Windows NT\Current Version\AeDebug:

                                                                     i.      Value: “Debugger”

      1.       Type: String

      2.       Value data: <path to cdb> -pv -p %ld -c “.dump /u /ma <dump file path\name.dmp>;.kill;qd"

                                                                   ii.      Value: “Auto”

      1.       Type: String

      2.       Value data: “1”

      b.      Key: HKLM\Software\Microsoft\.NETFramework

                                                                     i.      Value: “DbgManagedDebugger

      1.       Type: String

      2.       Value data: <path to cdb> -pv -p %ld -c ".dump /u /ma <dump file path\name.dmp>;.kill;qd"

                                                                   ii.      Value: DbgJITDebugLaunchSetting

      1.       Type: DWORD (32-bit)

      2.       Value data: 2

       

      Note: You should set the keys to point to the appropriate “bitness” debugger. I.e. you want the OS/CLR to launch the 64-bit debugger for 64-bit process crashes and the 32-bit version for 32-bit crashes. Make sure your debugger paths are set accordingly.

       

      The following sample .reg file will set cdb.exe to auto-launch and generate a crash dump for every process crash on the machine. Note the assumptions the file makes about debugger paths and the dump-file-placement path.

       

      Windows Registry Editor Version 5.00

       

      ;This reg file installs just-in-time debuggers to capture a dump of all process
      ;crashes for the machine.

      ;

      ;Assumes 32-bit debugger is cdb.exe and is installed to c:\debuggers\x86\.

      ;Assumes 64-bit debugger is cdb.exe and is installed to c:\debuggers\x64\.

      ;

      ;Assumes crash dumps can be written to c:\crash_dumps\.

      ;Make sure all users have write access to this directory.

       

      [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework]

      "DbgManagedDebugger"="\"c:\\debuggers\\x64\\cdb.exe\" -pv -p %ld -c \".dump /u /ma c:\\crash_dumps\\crash.dmp;.kill;qd\""

      "DbgJITDebugLaunchSetting"=dword:00000002

       

      [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AeDebug]

      "Debugger"="\"c:\\debuggers\\x64\\cdb.exe\" -pv -p %ld -c \".dump /u /ma c:\\crash_dumps\\crash.dmp;.kill;qd\""

      "Auto"="1"

       

      ;The following keys are only used on 64-bit versions of Windows (note Wow6432Node).

      ;They can be safely created with no side-effects on 32-bit versions of Windows.

      ;Alternatively, you can delete the remainder of this file if you’re running a

      ;32-bit version of Windows.

       

      [HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows NT\CurrentVersion\AeDebug]

      "Debugger"="\"c:\\debuggers\\x86\\cdb.exe\" -pv -p %ld -c \".dump /u /ma c:\\crash_dumps\\crash.dmp;.kill;qd\""

      "Auto"="1"

       

      [HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\.NETFramework]

      "DbgManagedDebugger"="\"c:\\debuggers\\x86\\cdb.exe\" -pv -p %ld -c \".dump /u /ma c:\\crash_dumps\\crash.dmp;.kill;qd\""

      "DbgJITDebugLaunchSetting"=dword:00000002

       

       

      What do these keys do?

       

      The “Debugger” and “DbgManagedDebugger” value data are basically command lines (printf format strings) that are run when a process crashes. The OS or CLR will substitute values for the format specifiers (e.g. in the case above it substitutes the crashing process ID for the “%ld”) and run the command in the user context of the crashing process. The command line I’ve supplied:

      ·         launches cdb.exe, the debugger.

      o   Obviously, you must specify the correct path to the debugger.

      ·         “-pv %ld” : Attaches non-invasively (just suspends the threads) to the crashing process (the OS or the CLR will actually fill in the PID for you).

      ·         “.dump /u /ma <dump file path\name.dmp>”: Takes a full memory dump with a unique name (appends the date, time and process ID) and stores it in the path defined.

      o   The path and file name can be whatever you want them to be. Since the debugger is launched in the context of the crashing process, make sure the path points to a location all accounts can write to.

      ·         “.kill”: Kills the target process (you’ve gotten the data you need).

      ·         qd”: Quits the debugger.

       

      The “Auto” and “DbgJITDebugLaunchSetting” values set the policy for when to launch the debugger. As I wrote above, we want to get our data as quickly as possible and move on, so we don’t want to require any user intervention. For example, in the server scenario, there may be no one logged into the machine to click some “OK” button. The settings I described will automatically launch the registered debugger for all processes on the machine, without prompting (see Enabling JIT-attach Debugging for more details on the settings). Note that when these settings are in place, the debugger will be launched for crashes in all processes running on the machine and you will not have the option of submitting the crash through “Windows Error Reporting.” In future posts I’ll discuss ways of enabling both.

       

      I don’t care about most processes on a machine. Can I just target specific ones?

       

      The answer depends on the version of the OS and the version of CLR. Here are the rules:

      ·         For native code: your OS must be Vista/Server 2008 or higher.

      ·         For managed code: Your version of the CLR must be V4 (or higher, if you’re reading this from the future).

       

      And here is how you configure:

      1.       Set the debugger keys (AeDebug\Debugger and .NETFramework\DbgManagedDebugger) just as you did in 2.a.i and 2.b.i, above.

      2.       Ensure AeDebug\Auto and .NETFramework\DbgJITDebugLaunchSetting are not set to auto-launch (again, see Enabling JIT-attach Debugging for more details on the settings).

      a.       Or you can delete them.

      3.       Create the following registry keys and values:

      a.       HKLM\Software\Microsoft\Windows\Windows Error Reporting\DebugApplications

                                                                     i.      Value: <Name of application executable> (e.g. “myapp.exe”)

      1.       Type: DWORD (32-bit)

      2.       Value data: 1

      b.      Repeat this for each application you want the debugger to be auto-launched.

       

      You can set the DebugApplications key and values in HKCU if you prefer per-user control. When these settings are in effect the debugger will be launched for only the processes you specify and normal error handling will occur for all other processes (e.g. for most default configurations, a prompt to submit an error report to Microsoft).

       

      The following sample .reg file will set cdb.exe to be auto-launched only for HelloWorld.exe. Replace HelloWorld.exe with the name(s) of the application(s) for which you’re interested in generating crash dumps.

       

      Windows Registry Editor Version 5.00

       

      ;This reg file installs just-in-time debuggers to capture a dump of only the
      ;processes listed under the [DebugApplications] key, below.

      ;

      ;Assumes 32-bit debugger is cdb.exe and is installed to c:\debuggers\x86\.

      ;Assumes 64-bit debugger is cdb.exe and is installed to c:\debuggers\x64\.

      ;

      ;Assumes crash dumps can be written to c:\crash_dumps\.

      ;Make sure all users have write access to this directory.

       

      [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework]

      "DbgManagedDebugger"="\"c:\\debuggers\\x64\\cdb.exe\" -pv -p %ld -c \".dump /u /ma c:\\crash_dumps\\crash.dmp;.kill;qd\""

      "DbgJITDebugLaunchSetting"=dword:00000000

       

      [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AeDebug]

      "Debugger"="\"c:\\debuggers\\x64\\cdb.exe\" -pv -p %ld -c \".dump /u /ma c:\\crash_dumps\\crash.dmp;.kill;qd\""

      "Auto"="0"

       

      ;The following keys are only used on 64-bit versions of Windows (note Wow6432Node).

      ;They can be safely created with no side-effects on 32-bit versions of Windows.

      ;Alternatively, you can delete the remainder of this file if you’re running a

      ;32-bit version of Windows.

       

      [HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows NT\CurrentVersion\AeDebug]

      "Debugger"="\"c:\\debuggers\\x86\\cdb.exe\" -pv -p %ld -c \".dump /u /ma c:\\crash_dumps\\crash.dmp;.kill;qd\""

      "Auto"="0"

       

      [HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\.NETFramework]

      "DbgManagedDebugger"="\"c:\\debuggers\\x86\\cdb.exe\" -pv -p %ld -c \".dump /u /ma c:\\crash_dumps\\crash.dmp;.kill;qd\""

      "DbgJITDebugLaunchSetting"=dword:00000000

       

      ;For each application you want the debugger to be auto-launched, add a row below

      ;similar to “HelloWorld.exe"=dword:00000001 but replacing HelloWorld.exe with

      ;your application .exe name.

       

      [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\Windows Error Reporting\DebugApplications]

      "HelloWorld.exe"=dword:00000001

       

      Can I do more than just capture a dump?

       

      More information on the command-line switches for the Windows Debuggers can be found in the documentation included with the Debugging Tools for Windows. You’re not limited just to dumps. You can perform quite a bit of debugger automation if you choose.

       

      So what happened?

       

      Now that you have your dump, it’s time to figure out why your application crashed. For those of you familiar with dump debugging, at this point you’re about to fire up WinDbg + SOS (the managed debugging extension) and dive in. But wait! If your application runs on V4 of the CLR (.Net Framework 4.0) you can debug the dump in Visual Studio 2010. Our desire for the experience in VS 2010 is that it feels very similar to stopped-state live debugging (like you’ve hit a breakpoint). The fact that you’re often debugging optimized code can make this a bit trickier, but that’s a topic for another day.

       

      For more information about how to debug crashes in managed code, a search for “managed dump debugging” yields quite a few helpful results. A great place to start is Tess Ferrandez’s blog (a support engineer at Microsoft). She has a number of great posts on the topic, including a post on dump debugging in VS 2010, and some labs/walkthroughs as well.

       

      Jon Langdon,

      PM, CLR

      Posted by CLRTeam | 3 Comments

      Five Myths about Managed Code

      My name is Immo Landwerth and I was a Program Manager intern this year in the CLR team. In this blog post I am not going to showcase any of the fantastic features that will ship with .NET 4.0 – my colleagues in the CLR team know them much better and already did a fabulous job discussing them here, over there and on Channel 9.

      Instead I want to discuss the following five myths about managed code and in particular about the CLR:

      · Managed code is always JIT compiled

      · Generic co- and contra variance are new in .NET 4.0

      · Everything is an object

      · .NET only supports statically typed languages

      · Microsoft is not using Managed Code

      Myth Five – Managed code is always JIT compiled

      Having a JIT compiler has many advantages because a lot of things are becoming much easier when a JIT compiler is available:

      1. On-the-fly code generation (System.Reflection.Emit) is much easier because you only have to target one virtual machine architecture (IL) instead all the processor architectures the runtime supports (such as x86 and x64).

      2. To some degree it solves the fragile base class library problem. That means we can share class definitions across modules without having the problem that changes such as adding fields or adding virtual methods crashes dependent code.

      3. The working set can be improved because the JIT only compiles methods that are actually executed.

      4. Theoretically, you could take situational facts into consideration, such as which processor-architecture is actually used (e.g. is it SSE2 capable), the application usage patterns etc. and optimize differently for them.

      However, JIT compilation also has downsides such as:

      1. It takes time. That means JIT compilation always has to trade-off time vs. code quality.

      2. The code is stored on private pages so the compiled code is not shared across processes.

      Therefore we created a tool called NGEN that allows you to pre-create native images during the setup. You could call this ahead-of-time compilation (as opposed to just-in-time). Certain special conditions left aside (such as some hosting scenarios or profiling), the runtime will now pick up the native images instead of JIT-compiling the code.

      Why did we not allow you to pre-create the native images during build time and let you ship the native images directly? Well, because we then run into the fragile base class library problem mentioned above. In that case, your native images would get invalid every time the .NET Framework is updated. Today we solve this problem by re-running NGEN on the customer’s machine when the framework is serviced. In .NET Framework 4 we ship a new feature called targeted patching, that allows us for method-body only changes to minimize or to even to fully avoid recompilation. For more details about NGEN in general see here and for more details about NGEN in .NET Framework 4 see here.

      Even if you are not using NGEN for you application code: for desktop CLR applications all the assemblies that are part of the .NET Framework itself are not JIT compiled – instead the runtime will bind to the native images. So even in these cases only your application code will be JIT compiled and therefore both ahead-of-time as well as just-in-time technologies are used simultaneously. Thus, stating that all code is JITted is simply wrong.

      Myth Four – Generic co- and contra variance are new in .NET 4.0

      The short answer is ‘no’. The longer answer is ‘well, sort of’.

      But I am getting ahead of myself. Let’s first see what co- and contravariance actually means. Generic covariance allows you to call a method that takes an IEnumerable<Shape> with an IEnumerable<Circle> (if Circle is derived from Shape). This is useful if Shape contains, e.g. a method that allows you to compute the area. This way you can write a method that computes the area for any collection of shapes. Contravariance on the other hand allows you to call a method that takes an IComparer<Circle> with an IComparer<Shape>. This is handy if someone wants to compare circles and you already have created a general comparer for any shape (this works because if your comparer knows how to compare two instances of Shape it certainly is also able to compare two instances of Circle).

      The support for co- and contra variance has always been in the CLR since generics came up in the .NET Framework 2.0. However, as Rick Byers pointed out you would have to use ILASM for creating covariant and contravariant type definitions:

      In IL, covariant type parameters are indicated by a ‘+’, and contravariant type parameters are indicated by a ‘-‘ (non-variant type parameters are the default, and can be used anywhere).

      What has been added in the .NET 4.0 release is language support for C# and Visual Basic. For example, the following uses the C# syntax (in and out modifiers for the generic type declaration) to create some covariant and contra variant types:

      // Covariant parameters can be used as result types

      interface IEnumerator<out T> {

      T Current { get; }

      bool MoveNext();

      }

      // Covariant parameters can be used in covariant result types

      interface IEnumerable<out T> {

      IEnumerator<T> GetEnumerator();

      }

      // Contravariant parameters can be used as argument types

      interface IComparer<in T> {

      bool Compare(T x, T y);

      }

      Myth Three – Everything is an object

      “Wait a minute – this is the number one programming promise everyone was making about .NET!” you might say now. Yes, and yet it is false. Many .NET or C# books make this mistake in one form or the other. “Everything is an object”. Although we believe there is a lot of value in simplifying things for didactic reasons (and hence many authors just claim it that way) we would like to take this opportunity to tell you “sorry, it is not completely true”.

      Before we discuss this issue we should first define what the sentence “everything is an object” is supposed to mean. The interpretation we will use here is this:

      Every type is derived from a single root (System.Object). This means, that every value can be implicitly casted to System.Object. More precisely, this means that every value is representable as an instance of System.Object.

      So why is this not true for the CLR? The counter example is a whole class of types that are not derived from System.Object: pointers (such as int*). So you cannot pass a pointer to a method that takes an object. In addition you cannot call the ToString or GetHashCode methods on a pointer.

      We could also use a different interpretation of “everything is an object” such as:

      Every type is derived from a single root (System.Object). This means, that every value is an object at all times.

      Why is this different? Simple values (i.e.. values that have types derived from System.ValueType) are not objects by the definition of an object (they lack identity). But every value can be casted implicitly to System.Object (because System.ValueType is derived from System.Object). However, in that case an object instance that contains the value is created. This process is called boxing. The resulting object instance (the “box”, not to be confused with Don Box) has indeed a notion of identity (which is in particular also true for Don Box).

      As you can see, the CLR uses the first interpretation and yet it is still not completely true as pointers do not derive from System.Object.

      Myth Two – .NET only supports statically typed languages

      It is true that the CLR uses a static type system. But this does not necessarily mean that it is only suited for programming languages that use a static type system. At the end, the programming language is implemented using the CLR but it is not identical with the CLR. So do not be fooled by the fact that the type system and mechanics of C# almost map directly to first class CLR-concepts. In fact, there are many concepts in C# that the CLR is not aware of:

      1. Namespaces. As far as the CLR is concerned namespaces do not even exist. They are just implemented as type prefixes separated by dots (so instead of saying ‘the class Console is contained in the namespace System’ the CLR would just say ‘there is a class called System.Console’).

      2. Iterators. The CLR does not provide any support for it. All the magic is done by the compiler (if you want to know, the compiler turns your method into a new type that internally uses a state-machine to track the current point of execution. Details can be found here).

      3. Lambdas. They are just syntactic sugar. For the runtime these are just delegates, which in turn can also be considered syntactic sugar. In fact, a delegate is nothing more than a class derived from System.MulticastDelegate that provides an Invoke, BeginInvoke and EndInvoke method with the appropriate parameters.

      Please note that this list is not complete. Instead it is only used to show you that even C# has to implement itself on top of the CLR and hence it is not a 1:1 mapping of the concepts the runtime provides. What does this have to do with static typing vs. dynamic typing? The answer is simply: you can implement a dynamically typed system on top of a statically typed system.

      If you know see a huge business opportunity here, we have to disappoint you. Some smart people already had the same idea. This effort is called the Dynamic Language Runtime, or DLR for short. If you are like me then you immediately think of native code when someone mentions the term ‘runtime’. However, the DLR is completely implemented in C# and is just a class library that can be used by programming languages to implement dynamic systems on top of the CLR. The DLR shares the fundamental design principle of the CLR, i.e. it provides a platform for more than one language. That means you can share IronPython objects with IronRuby objects because they are implemented with the same underlying runtime (the DLR).

      With .NET 4.0 the DLR ships as part of the box. So while .NET has first-class support for statically typed languages through the CLR it also provides first-class support for dynamically typed languages through the DLR.

      Myth One – Microsoft is not using Managed Code

      We often hear this (“Office and Windows are still not built on top of managed code!”) when customers ask about performance and future investments of Microsoft in managed code. The reasoning goes like this:

      Since Microsoft is not implementing Windows and Office in managed code that means that it must be significantly flawed/runs much slower than native code and therefore their long term strategy will still be C++. This in turn means that we should not use managed code either.

      In fact Microsoft has a huge investment in managed code (although it is still true that Office and Windows are not implemented in managed code). However, there are a bunch of products that are significantly (if not completely) implemented in managed code:

      1. Windows components, such as

           a. PowerShell

           b. System Center

      2. Office components, such as

           a. Exchange

           b. SharePoint/Office Server

      3. Developer Tools, such as

           a. Visual Studio and Visual Studio Team System

           b. Expression

      4. Dynamics

      This list if by far not complete but it should be large enough to convince you that we are in fact ‘eating our own dog food’.

      The reason that not all products are written in managed is not only related to performance. Sometimes the wins of re-implementing working native code in managed code do not outweigh its costs. On the other hand, there are still scenarios in which managed code simply cannot be used today (such as building the CLR itself or the debugger).

      However, we will not deny that there are scenarios in which we cannot compete with the performance of native code today. But this does not mean that we have given up on this. In fact, projects like Singularity should show you that we are really very ambitious about redefining the limits of the managed world.

      The last thing to keep in mind is that manually optimized assembler code is also faster than plain C-code. But this does not mean that all operating systems are completely written in assembler.

      Thus our vision is more like this: native code where it makes sense, managed code where it makes sense with the bigger portion being managed.

      Posted by CLRTeam | 9 Comments

      CLR Inside Out - Profiling the .NET Garbage-Collected Heap

       

      The new installment of the “CLR Inside Out” column in MSDN Magazine is now available on line.  This month we have an article from Subramanian Ramaswamy and Vance Morrison on Profiling the .NET Garbage-Collected Heap.  This article provides instructions on using the CLR Profiler for memory investigations of the .NET Garbage-Collected heap.

      You can find a list of all “CLR Inside Out” articles here.  As always, please let us know if you have topics you’d like to see covered in the column.

      CLR Inside Out - What's New in the .NET Framework 4 Base Class Library

      September 2009 MSDN Magazine cover 

      Sorry for the delay in the post, but in case you haven’t seen it yet, the new installment of the “CLR Inside Out” column in MSDN magazine is available on line.  This month we have an article from Justin Van Patten on What’s New in the .NET Framework 4 Base Class Library, covering mainly the new features that were available in .NET 4 Beta 1. 

      You can find a list of all “CLR Inside Out” articles here.  As always, please let us know if you have topics you’d like to see covered in the column.

      IL Stub Diagnostic Tool

       

      The IL Stub Diagnostic Tool enables real-time inspection of the contents of IL stubs. Developers now have a powerful tool to troubleshoot issues in interop marshalling,

      Introduction

      Jesse posted a great blog talking about the concept, history, and improvements of Intermediate Language (IL) stubs for CLR v4. He mentions

      The remainder of this post continues the discussion that Jesse started in the “Easier Debugging” section of his blog.

      Get the tool

      You are encouraged to download the tool from CodePlex.

      Usage of the IL Stubs Diagnostics Tool

      To begin using the tool, follow these basic steps:

      1) Launch the IL Stub Diagnostic tool. Note: you need to be an administrator of the machine because the tool utilizes the Event Tracing for Windows (ETW) feature to receive ETW events.

      clip_image002

      There are three key features of the tool:

      · Starting and Controlling the IL stubs monitoring session

      The upper-left button, Start, is the most important aspect of starting a session. After clicking the Start button, the tool begins monitoring all the stubs generated by CLR on the machine. It will keep monitoring the IL stubs until you click it again (i.e., Start button will turn to Stop after it is clicked).

      · Filtering to find a specific IL Stub

      The IL Stub List section shows all the IL stubs collected by the tool. Sometimes you will receive a huge number of stubs. In this case, you can set several filters using the Filters feature to find the exact stub.

      · Navigating and Inspecting the contents of an IL Stub

      Once you find the IL Stub, the contents of it (the IL code) will be shown in the IL Code section. We provide some features like navigation to help you read and understand the IL code.

      2) Start monitoring IL stubs by clicking the Start button.

      3) Run a program involving interop. For example, the sample program sample\pinvoke.exe, which is included with the tool on CodePlex, generates a p/invoke from managed code to native code. Running this sample from the command line will generate several entries in the IL Stub List section. We will use this for illustration purposes below.

      In this example, each item represents an IL Stub. Select an entry and notice its corresponding IL code shown in the IL Code Section.

      clip_image004

      Features which Enable Inspection and Navigation of IL Stubs

      IL Stubs are generated on the fly by the CLR for Interop, and bridge the gap between managed and native methods. Since they are dynamically generated, it is difficult for developers to investigate or troubleshoot issues because the stubs are further JIT-compiled into machine code. The IL Stub Diagnostic tool eases the interop debugging experience by enabling the inspection of every stub. Let’s take a look at some of the key features which enable the inspection and navigation of IL stubs.

      Detailed information of IL Stub

      By default, the tool shows the following categories for each IL stub: MethodName, CreateTime, ProcessName, Category, ManagedSignature and NativeSignature. These categories are important for developers to identify an IL stub. In special cases (e.g., debugging with windbg), developers may also be interested in information like ModuleId and ManagedMethodToken. These are available by right clicking the table header of the IL Stub list.

      clip_image006

      IL Stub Filters

      You may find that the CLR generates a lot of IL Stubs during the execution of a managed program. To quickly locate the stub we’re seeking, filters can be set to reduce the number of IL stub entries in the IL Stub list. Using the pinvoke.exe sample (included with the tool on CodePlex), you can use the following filter:

      clip_image008

      Once the filter has been entered, click the Refresh button to obtain the filtered list.

      To remove a filter, you can right click on the row header of the first filter condition and select Delete Filter. It will take effect after clicking Refresh button.

      clip_image010

      Navigation buttons for IL Stub code

      The code may not be well-formatted for first time display. To make the code more reader-friendly, the tool provides navigation buttons that allow you to view the code block by block. As you can see, each IL stub contains the following color-coded blocks: Initialize, Marshal, the calling method, and Unmarshal blocks. In the IL code, StubHelpers are used to do some complex work. Most of the functionality of each stub helper can be figured out by its name. The tool also provides a Stub API button to look up its usage.

      clip_image012

      Please note that stub helpers are internal to the runtime and their names/signatures/description should only be used for informational purposes. We may change any of these in the next version of the CLR so no one should establish any dependencies on them.

      Troubleshooting marshalling issues with IL Stub Diagnostic tool

      As mentioned earlier, developers can use the tool to investigate and debug marshalling issues. Here is an example.

      Case description

      There is an issue with the following p/invoke scenario. The signature of the native method is:

      void DumpString(WCHAR *pStr)

      {

      printf("%ws", pStr);

      }

      In managed code, we declare it as:

      [DllImport("testNative.dll")]

      public static extern void DumpString(string str);

      When invoking from managed side with the following code, it shows nothing on the console.

      DumpString("Hello World");

      Our job is to discover what happens during the p/invoke call.

      Troubleshooting

      Since the native code simply dumps the string, the problem must be occuring during the marshaling phase.

      First, locate the stub by following these steps:

      1. Launch IL Stub Diagnostic tool.

      2. Click Start Button.

      3. Run the program again.

      4. Set the following filter as shown below and click the Refresh button.

      clip_image014

      Next, navigate to the block of code which handles the marshaling by following these steps:

      1. Click the “IL Code” button to get a bigger view.

      2. Click the “Next Block” and navigate to the Marshal block.

      3. Usually, StubHelpers APIs are the most informational code here. Move the mouse over it to see the explanation of the method (shown in the green box below):

      clip_image016

      4. The description tells us that the StubHelpers method is used to convert an Ansi string. However, our native method expects a WCHAR string, which results in the marshaling issue. The fix is to specify Unicode, as the highlighted code below.

      [DllImport("testNative.dll", CharSet=CharSet.Unicode)]

      public static extern void DumpString(string str);

      Summary

      As you can see, the IL Stubs Diagnostic Tool provides a window into what used to be a black box, and allows you to look into the very core of interop marshaling – the IL Stub itself.

      Acknowledgements

      We would like to specially thank Yifeng Fu for being one of the key developers of IL Stub Diagnostic tool during his internship with us.

      See Also

      The MSDN topic “MSIL Stub Customization” contains detailed reference and usage information.

       

       

      Yongtai Zhu,

      Developer, CLR.

      Posted by CLRTeam | 1 Comments

      The good and the bad of exception filters

      Every so often we get asked questions about the CLR’s support for exception filters. Why do some languages support them and others do not? Is it a good idea to add them to my new language? When should I use a filter vs. catch/rethrow? Etc. I’ll try to answer some of these questions for you here, and while I won’t go into all of them hopefully you’ll walk away with enough info to form your own opinion on the rest. Like so many things there’s good things and bad things about exception filters…

      So what’s a filter?

      The CLR provides a number of exception handling primitives that higher level languages can build upon. Some are fairly obvious, and map readily to language constructs that most of us know and love: try/catch and try/finally, for instance. I’d hazard to guess that everyone knows what those do, but just in case, let’s consider a quick example in C#:

          try

          {

              try

              {

                  Console.Write(“1”);

                  if (P) throw new ArgumentException();

              }

              finally

              {

                  Console.Write(“2”);

              }

          }

          catch (ArgumentException e)

          {

              Console.Write(“3”);

          }

          Console.Write(“4”);

      If P is true, then that will print out “1234”, of course. If P is false, then it will print “124”. Groovy.

      But the CLR also provides two more EH primitives: fault and filter. A fault clause is much like a finally clause; it runs when an exception escapes its associated try block. The difference is that a finally clause also runs when control leaves the try block normally, whereas the fault clause will only run when control leaves the try block due to an exception. In the case above, if we replaced the “finally” with “fault” (there’s no C# syntax for that, but suspend your disbelief for a moment) then it would print “1234” if P is true, and “14” is P is false. See the difference? Most languages don’t expose this as a first-class language construct, but we do have a few that use fault clauses under the covers for specific scenarios.

      So that leaves us with filters. I suppose the simplest definition of a filter is that it is a construct that allows one to build a conditional catch clause. In fact, that’s exactly what VB uses filters for. Let’s consider a more complicated example in VB:

          Function Foo() As Boolean

              Console.Write("3")

              Return True

          End Function

          Sub Main()

              Dim P As Boolean = True

              Try

                  Try

                      Console.Write("1")

                      If (P) Then

                          Throw New ArgumentNullException()

                      End If

                      Console.Write(“P was False!”)

                  Finally

                      Console.Write("2")

                  End Try

              Catch ex As ArgumentNullException When Foo()

                  Console.Write("4")

              Catch ex As ArgumentException

                  Console.Write("5")

              End Try

              Console.Write("6")

          End Sub

      Here you’ll note the “Catch ex As ArgumentNullException When Foo()” line is a conditional catch statement. The catch handler will only execute and print “4” when the exception is an ArgumentNullException and when Foo() returns true. If Foo() returns false, then the catch clause doesn’t execute, and the system continues to search for a catch clause that can handle the exception. In this case, the very next clause would handle the exception, and print “5”.

      So, what do you think this program prints? Don’t cheat by attempting to compile and run it! Using what you know about exception handling and looking at the program structure and syntax, what would you imagine this program prints? I suspect most people would guess “12346”. I even gave you a clue with the numbering.

      I think most of us would look at the example above and conclude that the result should be “12346” because when we look at the syntax above we, quite rightly, see lexically scoped language constructs. We expect that when the code in the inner finally clause starts executing that no more code anywhere in the associated try block will execute. For instance, in the example above, if P is true then when we enter the Finally we know that no more code will execute in the try block, and that we’ll never print “P was False!”. Likewise, when we evaluate one of the catch clauses, we expect that all the code in the associated try block is done executing.

      And here comes the bad…

      It turns out that program actually prints “13246”. My clue with the numbering was an evil ruse. After the throw, Foo() is executed first as part of evaluating the first catch clause, and then the finally within the associated try block executes. And that’s just freaky… what happened to our lexically scoped language constructs?!

      This is a surprising result for most. It breaks our intuitive reasoning about the language based on the lexically scope exception handling constructs provided. Here, when we evaluate the conditional catch clause, all the code in the associated try block has not, in fact, finished executing.

      Why does this happen?

      The reason we see “3” before “2” is subtle, and founded in the CLR’s implementation of exception handling. The CLR’s exception handling model is actually a “two pass” model. When an exception is thrown, the runtime searches the call stack for a handler for the exception. The goal of the first pass is to simply determine if a handler for the exception is present on the stack. If it sees finally (or fault) clauses, it ignores them for a moment.

      The handler may be in the form of a typed catch clause, i.e., “Catch ex as ArgumentException)”. When the runtime sees a typed catch clause, it can determine itself if this clause will handle the exception by performing a simple check to determine if the exception object is of a type that inherits from (or is) the type in the clause.

      But when the runtime sees a filter, it must execute the filter in order to determine if the associated handler will handle the exception. If the filter evaluates to true, then a handler has been found. If it evaluates to false, then the runtime will keep searching for a handler.

      Once a handler has been found, the first pass is over and the second pass begins. On the second pass, the runtime again runs the call stack from the point of throw, but this time it executes all finally (or fault) clauses it finds on the way to the handler it identified on the first pass. When the handler is reached, it is executed, and the exception has finally been handled.

      But why is that bad?

      “Okay”, you say, “I get it. I understand that filters run during the first pass. I can deal with that… what’s the big deal?” Well, let’s first consider what a finally clause is for. We typically use finally clauses to ensure that our program state remains consistent when exiting a function even in the face of an exception. We put back temporarily broken invariants. Consider that the C# “using” statement is built using try/finally, and then consider all the things one might do with that.

      But when your filter runs, none of those finally clauses have executed. If you called into a library within the associated try block, you may have not actually completed the call when your filter executes. Can you call back into the same library in that case? I don’t know. It might work. Or it might yield an assert, or an exception, or, well, your guess is as good as mine. The point is that you can’t tell.

      Using filters wisely (or, “the good”)

      But the notion of a conditional catch clause really is quite appealing, and there are ways to use these without getting caught by the problems of when the filter actually executes. The key is to only read information from either the exception object itself, or from immutable global state, and to not change any global state. If you limit your actions in a filter to just those, then it doesn’t matter when the filter runs, and no one will be able to tell that the filter ran out of order.

      For instance, if you have a fairly general exception, like COMException, you typically only want to catch that when it represents a certain HRESULT. For instance, you want to let it go unhanded when it represents E_FAIL, but you want to catch it when it represents E_ACCESSDEINED because you have an alternative for that case. Here, this is a perfectly reasonable conditional catch clause:

                      Catch ex As System.Runtime.InteropServices.COMException When ex.ErrorCode() = &H80070005

      The alternative is to place the condition within the catch block, and rethrow the exception if it doesn’t meet your criteria. For instance:

                      Catch ex As System.Runtime.InteropServices.COMException

                                      If (ex.ErrorCode != &H80070005) Then Throw

      Logically, this “catch/rethrow” pattern does the same thing as the filter did, but there is a subtle and important difference. If the exception goes unhandled, then the program state is quite different between the two. In the catch/rethrow case, the unhandled exception will appear to come from the Throw statement within the catch block. There will be no call stack beyond that, and any finally blocks up to the catch clause will have been executed. Both make debugging more difficult. In the filter case, the exception goes unhandled from the point of the original throw, and no program state has been changed by finally clauses.

      The problem is that we rely on programmer discipline in order to use filters correctly, but it’s easy to use them incorrectly and end up with infrequently executed code (exceptions, after all, are for exceptional circumstances) that has subtle and hard to diagnose bugs due to inconsistent program state that should have been cleaned up by finally clauses further down the stack.

      Why does the CLR use a two-pass exception handling model?

      The CLR implements a two-pass exception handling system in order to better interoperate with unmanaged exception handling systems, like Win32 Structured Exception Handling (SEH) or C++ Exception Handling. We must run finally (and fault) clauses on the second pass so they run in order with unmanaged equivalents. Likewise, we must not execute filters later (say, on the second pass) because one of those unmanaged systems may have remembered that it was supposed to be responsible for handling the exception. If we were to run a filter late on the second pass and decide that a managed clause really should catch the exception after previously having not declared that on the first pass, then we would violate our contract with those unmanaged mechanisms with unpredictable results.

      So, in short, it’s for interop, and like many things involving interop, we have a compatibility burden that we can’t ignore.

      Would a one-pass model be better?

      Many have wondered over the years if perhaps the two-pass model in general is bad, and if a one-pass model would be better. Like so many things in the world, it’s just not that clear. A one-pass model would simplify the exception handling implementation, and it would make more sense in the cases shown above. However, there are advantages to the two-pass model that can’t be ignored. Perhaps the most important one is that if the search for a handler fails on the first-pass the exception goes unhandled and in general no program state has changed, even though filters are run since filters tend not to change things. The call stack is still intact, and all values that lead to the exception are still present on the stack and on the heap (assuming no race conditions.) This is frequently essential when debugging an unhandled exception. In a one-pass model, all of the finally clauses would have been run before the exception goes unhandled.

      Wrapping up

      Of the languages that MS ships, only VB and F# support filters, and both do so via conditional catch clauses. In F#, you have to really go out of your way to attempt to inspect mutable global state, or to actually have a side effect, so you’re fairly safe there. In VB, though, you can call a function from the “when” clause of their catch statement, and in there you have free reign to do whatever you please. You can, without a doubt, get yourself into trouble attempting to do too much complicated work within such a filter. To keep your world safe and simple try to limit yourself to expressions that only access the exception object, and don’t modify anything. If you go beyond that, you need to consider carefully all the code executed in the try block, and if your actions in the filter will work if the backout code below has not finished executing yet.

      Mike Magruder,

      Developer, CLR.

      Improvements to Interop Marshaling in V4: IL Stubs Everywhere

       

      When the CLR needs to transition between managed and native code – usually because of P\Invoke or COM interop – we need to generate marshaling stubs (little chunks of code) to handle that specific call and transform the data from managed to native format and back again. . These stubs are little pieces of code that are usually generated at runtime to do their work behind the scenes and, hopefully, without making developers or users aware of their presence. In .Net 4 we’ve improved our marshaling infrastructure substantially with a feature we call “IL Stubs Everywhere.” For those who have a deep interest in interop marshaling we get into the details of this feature below. For everyone else, here are a few key benefits of this feature:

      · Faster interop marshaling: the more complex the signature the greater the speed-up

      · x86 and x64 behavior matches: we’ve updated the x64 marshaling to behave exactly as x86 always has and mostly without impact to x64

      · Better debugging: when something goes wrong in marshaling we now give you the ability, and specialized tools, to find the problem

      History

      The 1.0 and 1.1 versions of the CLR had several different techniques for creating and executing these stubs that were each designed for marshaling different types of signatures. These techniques ranged from directly generated x86 assembly instructions for simple signatures to generating specialized ML (an internal marshaling language)* and running them through an internal interpreter for the most complicated signatures. This system worked well enough – although not without difficulties – in 1.0 and 1.1 but presented us with a serious maintenance problem when 2.0, and its support for multiple processor architectures, came around.

      We realized early in the process of adding 64 bit support to 2.0 that this approach was not sustainable across multiple architectures. Had we continued with the same strategy we would have had to create parallel marshaling infrastructures for each new architecture we supported (remember in 2.0 we introduced support for both x64 and IA64) which would, in addition to the initial cost, at least triple the cost of every new marshaling feature or bug fix. We needed one marshaling stub technology that would work on multiple processor architectures and could be efficiently executed on each one: enter IL stubs.

      With x64 and IA64 bit support in v2 we introduced IL stubs to perform the marshaling on these platforms. With IL stubs we generate actual IL rather than assembly code or the specialized language in our ML stubs. On these platforms we only used the IL stubs and were thus able to have a single implementation, for all stubs, across both processor architectures. These IL stubs were much faster than the ML stubs but were also much slower than x86 stubs. Because of the performance regress and our resource constraints, we left the x86 platform with its original marshaling stubs implementation.

      New in V4: IL Stubs Everywhere

      One of the largest features the interop team worked on in the v4 product was the “IL Stubs Everywhere” feature. With this work we moved to uniformly using the same IL stubs infrastructure for all marshaling on all platforms. Sometimes when we spend a lot of time developing, or reworking, a feature there is a concern that it will be expensive for developers to start taking advantage of it: the good news with this one is that this will change will occur automatically and the majority of the benefits will happen just by running your app on v4.0.

      A few of the benefits you will see with this feature are:

      Increased performance:

      The original x86 stubs for the simplest signatures were pretty fast – often a simple copy operation -- but as soon as you needed marshaling for more complex signatures you were forced onto the slow path with the ML interpreter. We heavily optimized our IL stub infrastructure and now IL stubs are faster across the board (even compared to x86 stubs) and are orders of magnitude faster than the interpreted stubs you used to get for the more interesting signatures. Additionally, for those that use NGEN you’ll find that we include most of your IL stubs in the NGEN images to improve this scenario even further.

      Consistent behavior:

      One of the common problems people ran into in interop in the v2 days is that with different marshaling technologies used for 32 and 64 bit the behaviors didn’t line up exactly the same. There were a few places where the same code behaved differently based on platform. With every platform running off of IL stubs we now have the same behavior across all platforms.

      Note: when we did this we had a choice between giving the 4.0 IL stubs the behavior of the v2.0 64 bit IL stubs or the v2.0 32 bit stubs. We chose to use the 2.0 32 bit behavior for the 4.0 because of the much larger percentage of interop apps that have been built on 32bit to date.

      This means that you should not see any behavioral differences moving a 32 bit app to the v4.0 NetFX but you may see some for 64 bit interop apps.  Because of the nature of these changes we expect the impact of them to 64 bit apps to be very minimal: most of the changes involve relaxing behavior that was stricter in 64 bit than 32 bit. The biggest change in reverting to 32 bit behavior was to stop clearing ‘out’ parameters during certain error conditions and should be completely non-breaking to 64 bit applications.

      Easier Debugging:

      One of the other problems with the old 32 bit marshaling infrastructure was that it worked essentially as a black box that was very difficult to debug if something went wrong. It was very difficult to figure out how/what the runtime was trying to marshal when something went wrong. By moving to IL stubs it is actually possible to see the IL instructions that we’re executing and determine where your problem is.

      Since Visual Studio does not support debugging IL, the move to IL stubs alone wouldn’t help debugging very much if that was all we did. Instead we updated our IL stubs infrastructure to fire an ETW event detailing each stub as they get generated and built a tool, which we recently released on codeplex, which lets you easily see all the stubs being generated and quickly search for the ones for the methods you are most interested in. In an upcoming post we will have more details and a walkthrough of the tool, but in the meantime you can find it here: http://clrinterop.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=29745

       

      *ML Stubs: it is a little known fact that up until v4 the CLR, at runtime, converted complex signatures into an internal CLR language called ML (marshaling language) which it then ran through the CLR’s internal ML interpreter each time the method was invoked. This little interpreter is almost another separate runtime just for interop marshaling. You can imagine how replacing this with IL and thus getting all the advantages of the perf work that goes into NGEN and the JIT allowed us to massively speed up these scenarios. There was much rejoicing on our team when we removed this interpreter in v4.

       

       

      Jesse Kaplan,

      PM, CLR

      Posted by CLRTeam | 4 Comments
      Filed under: ,

      Upgrading to Windows 7 with .NET 4 Beta 1

      If you’re the kind of early adopter who installs .NET 4 Beta 1 and also wants the latest and greatest operating system (Windows 7), please check out Scott Hanselman’s recent blog post http://www.hanselman.com/blog/VistaUsersUninstallVisualStudio2010Beta1BeforeUpgradingToWindows7.aspx
       
      While .NET 4 Beta 1 works well on both Vista and Windows 7, you’ll run into trouble if you try to upgrade from Vista or Windows 7 RC to Windows 7 RTM without first uninstalling .NET 4 Beta 1.  Scott’s blog has the details.  
      Posted by CLRTeam | 0 Comments

      CLR Inside Out - Code Contracts

       

      The new installment of the “CLR Inside Out” column in MSDN magazine is available on line.  This month we have an article from Melitta Andersen on Code Contracts.  It provides an overview of the feature, and includes some recommendations the Base Class Libraries team figured out as they added Code Contracts to the BCL.

      You can find a list of all “CLR Inside Out” articles here.  As always, please let us know if you have topics you’d like to see covered in the column.

      More Posts Next page »
       
      Page view tracker