date
[mono.git] / mcs / mcs / TODO
index caafabf90e88e40114fc11eabd7558cca4495047..6dfd9d98eab1351c5c5778cceae7d6e006d124f6 100644 (file)
-BUGS
+EmitContext.ResolveTypeTree
+---------------------------
+
+       We should investigate its usage.  The problem is that by default
+       this will be set when calling FindType, that triggers a more expensive
+       lookup.
+
+       I believe we should pass the current EmitContext (which has this turned off
+       by default) to ResolveType/REsolveTypeExpr and then have the routines that
+       need ResolveType to pass null as the emit context.
+
+Idea
 ----
 
 ----
 
-* While reworking the return system
+       Keep a cache of name lookups at the DeclSpace level
 
 
-       I might have dropped a few features from EmitTopBlock return
-       code path.
+Large project:
+--------------
 
 
-* Adding variables.
+       Drop FindMembers as our API and instead extract all the data
+       out of a type the first time into our own datastructures, and
+       use that to navigate and search the type instead of the
+       callback based FindMembers.     
 
 
-       We do add variables in a number of places, and this is erroneous:
+       Martin has some some of this work with his TypeHandle code
+       that we could use for this.
 
 
-       void a (int b)
-       {
-               int b;
-       }
+Notes on memory allocation
+--------------------------
+
+       A run of the AllocationProfile shows that the compiler allocates roughly
+       30 megabytes of strings.  From those, 20 megabytes come from
+       LookupType.  
+
+       See the notes on current_container problems below on memory usage.  
+
+GetNamespaces
+-------------
+
+       Obtaining the list of namespaces is an expensive process because
+       Reflection.Emit does not provide a quick way of pulling the data out,
+       and it is too slow to load it.
+
+       Calling GetNamespaces on my machine (1Ghz):
+
+               * Takes half a second with the standard assemblies (corlib + System);
+                 Fetching the types from it takes 0.0028650 seconds. 
+
+               * Loading the top 10 largest assemblies we ship with Mono makes MCS take 
+                 8 seconds to startup the first time, subsequent invocations take 2 seconds.
+
+                 Fetching all the types (Assembly.GetTypes ()) for all the assemblies takes
+                 0.0069170 seconds.
+
+       So pulling all the types takes very little time, maybe we should look into our
+       Hashtable implementation to make it more optimal.
+
+       This prohibits re-writting SimpleName to take advantage of
+       knowing the namespace names in advance.  Knowing the namespaces in advance
+       would allow me to reduce the guesswork in which we are currently engaged
+       to find a type definition.
+
+LookupTypeReflection:
+---------------------
+
+       With something like `System.Object', LookupTypeReflection will be called
+       twice: once to find out that `System' is not a type and once
+       for System.Object.
+
+       This is required because System.Reflection requires that the type/nested types are
+       not separated by a dot but by a plus sign.
+
+       A nested class would be My+Class (My being the toplevel, Class the nested one).
+
+       It is interesting to look at the most called lookups when bootstrapping MCS:
 
 
-       Also:
+    647        LTR: ArrayList
+    713        LTR: System.Globalization
+    822        LTR: System.Object+Expression
+    904        LTR: Mono.CSharp.ArrayList
+    976        LTR: System.Runtime.CompilerServices
+    999        LTR: Type
+   1118        LTR: System.Runtime
+   1208        LTR: Mono.CSharp.Type
+   1373        LTR: Mono.Languages
+   1599        LTR: System.Diagnostics
+   2036        LTR: System.Text
+   2302        LTR: System.Reflection.Emit
+   2515        LTR: System.Collections
+   4527        LTR: System.Reflection
+  22273        LTR: Mono.CSharp
+  24245        LTR: System
+  27005        LTR: Mono
 
 
-       void a (int b)
-       {
-               foreach (int b ...)
-                       ;
+       Analysis:
+               The top 9 lookups are done for things which are not types.
+
+               Mono.CSharp.Type happens to be a common lookup: the class Type
+               used heavily in the compiler in the default namespace.
+
+               RED FLAG:
+
+               Then `Type' is looked up alone a lot of the time, this happens
+               in parameter declarations and am not entirely sure that this is
+               correct (FindType will pass to LookupInterfaceOrClass a the current_type.FullName,
+               which for some reason is null!).  This seems to be a problem with a lost
+               piece of context during FindType.
+
+               System.Object is also used a lot as a toplevel class, and we assume it will
+               have children, we should just shortcut this.
+
+    A cache:
+
+       Adding a cache and adding a catch for `System.Object' to flag that it wont be the
+       root of a hierarchy reduced the MCS bootstrap time from 10.22 seconds to 8.90 seconds.
+
+       This cache is currently enabled with SIMPLE_SPEEDUP in typemanager.cs.  Memory consumption
+       went down from 74 megs to 65 megs with this change.  
+
+Ideas:
+------
+
+       Instead of the hack that *knows* about System.Object not having any children classes,
+       we should just make it simple for a probe to know that there is no need for it.
+
+The use of DottedName
+---------------------
+
+       We could probably use a different system to represent names, like this:
+
+       class Name {
+               string simplename;
+               Name parent;
        }
 
        }
 
-* Visibility
+       So `System.ComponentModel' becomes:
+
+               x: (System, null)
+               y: (ComponentModel, x)
 
 
-       I am not reporting errors on visibility yet.
+       The problem is that we would still need to construct the name to pass to
+       GetType.
 
 
-* Interfaces
+current_container/current_namespace and the DeclSpace
+-----------------------------------------------------
 
 
-       For indexers, the output of ix2.cs is different from our
-       compiler and theirs.  They use a DefaultMemberAttribute, which
-       I have yet to figure out:
+       We are storing fully qualified names in the DeclSpace instead of the node,
+       this is because `current_namespace' (Namepsace) is not a DeclSpace like
+       `current_container'.
 
 
-       .class interface private abstract auto ansi INTERFACE
-       {
-               .custom instance void [mscorlib]System.Reflection.DefaultMemberAttribute::.ctor(string) 
-               = ( 01 00 04 49 74 65 6D 00 00 )                      // ...Item..
-               ...
+       The reason for storing the full names today is this:
+
+       namespace X {
+               class Y {
+               }
        }
 
        }
 
-* Interface indexers
+       namespace A {
+               class Y {
+               }
+       }
 
 
-       I have not figured out why the Microsoft version puts an
-       `instance' attribute, and I am not generating this `instance' attribute.
+       The problem is that we only use the namespace stack to track the "prefix"
+       for typecontainers, but they are not typecontainers themselves, so we have
+       to use fully qualified names, because both A.X and A.Y would be entered
+       in the toplevel type container.  If we use the short names, there would be
+       a name clash.
 
 
-       Explanation: The reason for the `instance' attribute on
-       indexers is that indexers only apply to instances
+       To fix this problem, we have to make namespaces DeclSpaces.
 
 
-* Handle destructors specially
+       The full size, contrasted with the size that could be stored is:
+               corlib:
+                       Size of strings held: 368901
+                       Size of strings short: 147863
 
 
-       Turn ~X () { a () } into:
-       void Finalize () { try { a (); } finally { base.Finalize (); } }
+               System:
+                       Size of strings held: 212677
+                       Size of strings short: 97521
+               
+               System.XML:
+                       Size of strings held: 128055
+                       Size of strings short: 35782
+               
+               System.Data:
+                       Size of strings held: 117896
+                       Size of strings short: 36153
+               
+               System.Web:
+                       Size of strings held: 194527
+                       Size of strings short: 58064
+               
+               System.Windows.Forms:
+                       Size of strings held: 220495
+                       Size of strings short: 64923
 
 
-       The code is mostly done, but `base' is missing.  The reason it is 
-       missing is because we have to implement visibility first.
+       
+TODO:
 
 
-* Method Names
+       1. Create a "partial" emit context for each TypeContainer..
 
 
-       Method names could be; `IFACE.NAME' in the method declaration,
-       stating that they implement a specific interface method.
+       2. EmitContext should be partially constructed.  No IL Generator.
 
 
-       We currently fail to parse it.
+       interface_type review.
 
 
-* Arrays
+       parameter_array, line 952: `note: must be a single dimension array type'.  Validate this
 
 
-       We need to make sure at *compile time* that the arguments in
-       the expression list of an array creation are always positive.
+Dead Code Elimination bugs:
+---------------------------
 
 
-* Implement dead code elimination in statement.cs
+       I should also resolve all the children expressions in Switch, Fixed, Using.
 
 
-       It is pretty simple to implement dead code elimination in 
-       if/do/while
+Major tasks:
+------------
 
 
-* Indexer bugs:
+       Pinned and volatile require type modifiers that can not be encoded
+       with Reflection.Emit.
 
 
-       the following wont work:
+       Properties and 17.6.3: Finish it.
 
 
-       x [0] = x [1] = N
+       Implement base indexer access.
 
 
-       if x has indexers, the value of x [N] set is set to void.  This needs to be
-       fixed.
+readonly variables and ref/out
+       
+BUGS
+----
 
 
-* Array declarations
+* Check for Final when overriding, if the parent is Final, then we cant
+  allow an override.
 
 
-       Multi-dim arrays are declared as [,] instead of [0..,0..]
+* Interface indexers
+
+       I have not figured out why the Microsoft version puts an
+       `instance' attribute, and I am not generating this `instance' attribute.
+
+       Explanation: The reason for the `instance' attribute on
+       indexers is that indexers only apply to instances
 
 * Break/Continue statements
 
 
 * Break/Continue statements
 
@@ -96,10 +245,12 @@ BUGS
        They should transfer control to the finally block if inside a try/catch
        block.
 
        They should transfer control to the finally block if inside a try/catch
        block.
 
-* Conversions and overflow
+* Method Registration and error CS111
 
 
-       I am not using the checked state while doing type casts,
-       they should result in conv.ovf.XXX
+       The way we use the method registration to signal 111 is wrong.
+       
+       Method registration should only be used to register methodbuilders,
+       we need an alternate method of checking for duplicates.
 
 *
 > // CSC sets beforefieldinit
 
 *
 > // CSC sets beforefieldinit
@@ -113,100 +264,76 @@ BUGS
 PENDING TASKS
 -------------
 
 PENDING TASKS
 -------------
 
-       * Implement explicit interface implemenation.
+* Merge test 89 and test-34
 
 
-       * Implement Goto.
+* Revisit
 
 
-       * Unsafe code.
+       Primary-expression, as it has now been split into 
+       non-array-creation-expression and array-creation-expression.
+               
+* Code cleanup
 
 
-       * Implement `base' (BaseAccess class)
+       The information when registering a method in InternalParameters
+       is duplicated, you can always get the types from the InternalParameters
 
 
-* OUT Variables passed as OUT variables.
+* Emit modreq for volatiles
 
 
-       Currently we pass the pointer to the pointer (see expression.cs:Argument.Emit)
+       Handle modreq from public apis.
 
 
-* Function Declarations
+* Emit `pinned' for pinned local variables.
 
 
-       Support PINvoke/Internallcall and extern declarated-functions.
+       Both `modreq' and pinned will require special hacks in the compiler.
 
 
-* Manual field layout in structures
-
-* Make the rules for inheritance/overriding apply to 
-  properties, operators and indexers (currently we only do this
-  on methods).
-
-* Handle volatile
-
-* Support Re-Throw exceptions:
-
-       try {
-               X ();
-       } catch (SomeException e){
-               LogIt ();
-               throw;
-       }
-
-* Static flow analysis
-
-       Required to warn about reachability of code and definite
-       assignemt as well as missing returns on functions.
-
-* Implement `goto case expr'
+* Make sure that we are pinning the right variable
 
 
+* Merge tree.cs, rootcontext.cs
 
 OPTIMIZATIONS
 -------------
 
 
 OPTIMIZATIONS
 -------------
 
-* Emitcontext
+* User Defined Conversions is doing way too many calls to do union sets that are not needed
 
 
-       Do we really need to instanciate this variable all the time?
-
-       It could be static for all we care, and just use it for making
-       sure that there are no recursive invocations on it.
-
-* Static-ization
-
-       Since AppDomain exists, maybe we can get rid of all the stuff
-       that is part of the `compiler instance' and just use globals
-       everywhere.
+* Add test case for destructors
 
 
+* Places that use `Ldelema' are basically places where I will be
+  initializing a value type.  I could apply an optimization to 
+  disable the implicit local temporary from being created (by using
+  the method in New).
 
 
-* Constructors
+* Dropping TypeContainer as an argument to EmitContext
 
 
-       Currently it calls the parent constructor before initializing fields.
-       It should do it the other way around.
+       My theory is that I can get rid of the TypeBuilder completely from
+       the EmitContext, and have typecasts where it is used (from
+       DeclSpace to where it matters).  
 
 
-* Reducer and -Literal
+       The only pending problem is that the code that implements Aliases
+       is on TypeContainer, and probably should go in DeclSpace.
 
 
-       Maybe we should never handle -Literal in Unary expressions and let
-       the reducer take care of it always?
+* Use of local temporary in UnaryMutator
 
 
-* Use of EmitBranchable
+       We should get rid of the Localtemporary there for some cases
 
 
-       Currently I use brfalse/brtrue in the code for statements, instead of
-       using the EmitBranchable function that lives in Binary
+       This turns out to be very complex, at least for the post-version,
+       because this case:
 
 
-* Create an UnimplementedExpcetion
+               a = i++
 
 
-       And use that instead of plain Exceptions to flag compiler errors.
+       To produce optimal code, it is necessary for UnaryMutator to know 
+       that it is being assigned to a variable (the way the stack is laid
+       out using dup requires the store to happen inside UnaryMutator).
 
 
-* ConvertImplicit
+* Emitcontext
 
 
-       Currently ConvertImplicit will not catch things like:
+       Do we really need to instanciate this variable all the time?
 
 
-       - IntLiteral in a float context to generate a -FloatLiteral.
-       Instead it will perform an integer load followed by a conversion.
+       It could be static for all we care, and just use it for making
+       sure that there are no recursive invocations on it.
 
 * Tests
 
        Write tests for the various reference conversions.  We have
        test for all the numeric conversions.
 
 
 * Tests
 
        Write tests for the various reference conversions.  We have
        test for all the numeric conversions.
 
-* Remove the tree dumper, cleanup `public readonly' 
-
-       And make all the stuff which is `public readonly' be private unless
-       required.
-
 * Optimizations
 
        In Indexers and Properties, probably support an EmitWithDup
 * Optimizations
 
        In Indexers and Properties, probably support an EmitWithDup
@@ -214,30 +341,28 @@ OPTIMIZATIONS
        in the stack, so that later a Store can be emitted using that
        this pointer (consider Property++ or Indexer++)
 
        in the stack, so that later a Store can be emitted using that
        this pointer (consider Property++ or Indexer++)
 
+* Optimizations: variable allocation.
+
+       When local variables of a type are required, we should request
+       the variable and later release it when we are done, so that
+       the same local variable slot can be reused later on.
 
 * Add a cache for the various GetArrayMethod operations.
 
 
 * Add a cache for the various GetArrayMethod operations.
 
-* Use of temporary values in Assign
+* TypeManager.FindMembers:
 
 
-       We generate suboptimal code for assignments, as we always
-       store the result in a temporary.  
+       Instead of having hundreds of builder_to_blah hash table, have
+       a single one that maps a TypeBuilder `t' to a set of classes
+       that implement an interface that supports FindMembers.
 
 
-       When implenenting `using' on
+* MakeUnionSet Callers
 
 
-               using (a = new XXX)
+       If the types are the same, there is no need to compute the unionset,
+       we can just use the list from one of the types.
 
 
-       Two instances of XXX were created, we need to research this.
+* Factor the lookup code for class declarations an interfaces
+  (interface.cs:GetInterfaceByName)
 
 
-               //
-               // FIXME! We need a way to "probe" if the process can
-               // just use `dup' to propagate the result.
-               //
-               // I Think I figured this out, have EmitAssign take an
-               // argument: leave result on stack or not.  If true,
-               // then we can dup ahead of time if we know about this,
-               // and we get rid of the temporary value
-               // 
-  
 RECOMMENDATIONS
 ---------------
 
 RECOMMENDATIONS
 ---------------
 
@@ -265,16 +390,3 @@ RECOMMENDATIONS
        Not sure that this grammar is correct, we might have to
        resolve this during semantic analysis.
 
        Not sure that this grammar is correct, we might have to
        resolve this during semantic analysis.
 
-
-* Try/Catch
-
-       Investigate what is  the right value to return  from `Emit' in
-       there (ie, for the `all code paths return')
-       
-
-* Optimizations
-
-       Only create one `This' instance per class, and reuse it.
-
-       Maybe keep a pool of constants/literals (zero, 1)?
-