Exceptions: Difference between revisions

2,223 bytes added ,  31 January 2008
ooms
(new intro for new plan)
(ooms)
Line 1: Line 1:
This is a discussion and planning document for refactoring [[Mozilla]] to use C++ exceptions. Exceptions will likely arrive after Mozilla 2, but we hope to improve out-of-memory (OOM) handling for Mozilla 2 and maybe take a few steps closer to exception safety.
This is a discussion and planning document for refactoring Mozilla to use C++ exceptions. Exceptions will likely arrive after [[Mozilla 2]], but we hope to improve out-of-memory (OOM) handling for Mozilla 2 and maybe take a few steps closer to exception safety.


Originally, this page suggested the goal would be to enable exceptions while preserving current behavior. But it looks like preserving current behavior exactly would make the code too ugly (e.g., needing try statements with empty catch blocks for ignored error codes), defeating the main purpose of going to exceptions. The new goal is to go more slowly, improving error handling functionality and cleaning up the code so it looks really nice once exceptions can be turned on.
Originally, this page suggested the goal would be to enable exceptions while preserving current behavior. But it looks like preserving current behavior exactly would make the code too ugly (e.g., needing try statements with empty catch blocks for ignored error codes), defeating the main purpose of going to exceptions. The new goal is to go more slowly, improving error handling functionality and cleaning up the code so it looks really nice once exceptions can be turned on.
Line 13: Line 13:
These steps are explained in more detail below. And by the way, we'd love to have community help with any of these.  
These steps are explained in more detail below. And by the way, we'd love to have community help with any of these.  


= Foo =
= Improved OOM Handling =
 
== Background ==
 
As of Mozilla 1.9, the general strategy for handling OOMs is this:
 
* Functions that allocate memory check for a null pointer (returned from new or malloc) and return NS_OUT_OF_MEMORY if allocation failed.
 
* Other functions check for NS_FAILED return codes or NS_OUT_OF_MEMORY errors and try to respond accordingly.
 
This doesn't really work. In practice, if an allocation fails, Firefox crashes within a second. There are many problems with this strategy, but the important ones for exceptions purposes are: (1) no call site should ever ignore an OOM (and it's not practical to achieve that with nsresult NS_OUT_OF_MEMORY), and (2) most of the time, the right response is to activate a centralized routine that tries to free memory (which is best done with exceptions or an allocation failure handler rather than sprinkling OOM checks everywhere).
 
So the new OOM strategy will go something like this:
 
* Allocation operations (new, malloc) will never return null pointers.
 
* No method will return NS_OUT_OF_MEMORY.
 
* No code will check for NS_OUT_OF_MEMORY.
 
* General OOM conditions will go to an OOM handler that immediately crashes. (Later, the handler may be upgraded to try to free memory--this is a separate issue.)
 
* A few allocations that "predictably" cause OOM will be able to check for and respond to OOMs using a special mechanism (e.g., calling a special allocator). The prime example of this kind of allocation is buffers for downloaded images: a huge image could easily cause OOM, and this can be relatively easily handled by the local image code (by not displaying the image).
 
This strategy will be more robust, more easily improved in the future, and it will reduce code size by removing all the OOM checks.
 
== Rewriting OOMs ==
 
There are two rewriting tasks for OOMs:
 
First, we want to '''remove all allocation null checks'''. For example,
 
    Foo *p = new Foo();
    if (p == NULL) return NS_OUT_OF_MEMORY;
    use(p);
 
will be replaced by
 
    Foo *p = new Foo();
    use(p);
 
Second, we want to '''remove all explicit OOM checks'''. For example, in
 
    nsresult rv = p->foo();
    if (rv == NS_OUT_OF_MEMORY) { ... }
 
the if statement would be deleted.


== Benefits of Exceptions ==
== Benefits of Exceptions ==
313

edits