Merge some useful changes from MD
[mono.git] / mcs / mcs / TODO
index 425ba33d379291e7652236235a069c7b4feca3f4..1abb0382b7bdc02b935afae54b8f06a9774130fe 100644 (file)
-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.  
+* Value Parameter
 
-       See the notes on current_container problems below on memory usage.  
+       I believe that `Value Parameter' might have been introduced
+       after C# 1.0, also notice than in the treatment of Value Parameter
+       the parameters are defined in four categories:
 
-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.
+       Section 9.3 in the latest spec.
 
-       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:
----------------------
+Large project:
+--------------
 
-       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.
+New
+---
 
-       This is required because System.Reflection requires that the type/nested types are
-       not separated by a dot but by a plus sign.
+       It would be nice to optimize the case of:
 
-       A nested class would be My+Class (My being the toplevel, Class the nested one).
+               Method (new ValueType ())
 
-       It is interesting to look at the most called lookups when bootstrapping MCS:
+       So that no temporary is created, and we only use a newobj call
+       that remains on the stack, as opposed to ldloca, initobj, ldloc
+       call.
 
-    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
+NEW NOTES:
+----------
 
-       Analysis:
-               The top 9 lookups are done for things which are not types.
+       ImplicitStandardConversionExists and ImplicitStandardConversion
+       should always be the same, but there are a few diverging lines that
+       must be studied:
 
-               Mono.CSharp.Type happens to be a common lookup: the class Type
-               used heavily in the compiler in the default namespace.
+                       if (expr_type == target_type && !(expr is NullLiteral))
+                               return expr;
 
-               RED FLAG:
+       vs:
 
-               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.
+                       if (expr_type == target_type)
+                               return true;
 
-               System.Object is also used a lot as a toplevel class, and we assume it will
-               have children, we should just shortcut this.
-
-       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.
-
-Ideas:
-------
+****************************************************************************************
+* 
+*   The information on the rest of this file is mostly outdated, and its kept here for
+*   historical reasons
+*
+****************************************************************************************
+Error Reporting:
+----------------
 
-       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.
+       * Make yyerror show a nice syntax error, instead of the current mess.
 
-The use of DottedName
----------------------
+Optimization ideas
+------------------
 
-       We could probably use a different system to represent names, like this:
+       Currently when we build a type cache, it contains private members,
+       internal members, and internal protected members;   We should trim
+       these out, as it shows up on the profile.
 
-       class Name {
-               string simplename;
-               Name parent;
-       }
+       We create too many Arraylists;  When we know the size, we should create
+       an array;
 
-       So `System.ComponentModel' becomes:
+       During parsing we use arraylists to accumulate data, like this:
 
-               x: (System, null)
-               y: (ComponentModel, x)
+               thing:
+               
+               thing_list
+                       : thing { $$ =new ArrayList (); $$.Add ($1); }
+                       | thing_list thing { ArrayList a = $1; a.Add ($2); $$ = a; }
 
-       The problem is that we would still need to construct the name to pass to
-       GetType.
+       We probably could start using "Pairs" there:
 
-current_container/current_namespace and the DeclSpace
------------------------------------------------------
+               thing_list
+                       : thing { $$ = new Pair ($1, null); }
+                       | thing_list thing { Pair p = $1; $$ = new Pair ($2, $1); }
 
-       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'.
 
-       The reason for storing the full names today is this:
+EmitContext.ResolveTypeTree
+---------------------------
 
-       namespace X {
-               class Y {
-               }
-       }
+       We should investigate its usage.  The problem is that by default
+       this will be set when calling FindType, that triggers a more expensive
+       lookup.
 
-       namespace A {
-               class Y {
-               }
-       }
+       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.
 
-       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.
+DeclareLocal audit
+------------------
 
-       To fix this problem, we have to make namespaces DeclSpaces.
+       DeclareLocal is used in various statements.  The audit should be done
+       in two steps:
 
-       The full size, contrasted with the size that could be stored is:
-               corlib:
-                       Size of strings held: 368901
-                       Size of strings short: 147863
+               * Identify all the declare locals.
 
-               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
+               * Identify its uses.
 
-       
-TODO:
+               * Find if we can make wrapper functions for all of them.
 
-       1. Create a "partial" emit context for each TypeContainer..
+       Then we can move DeclareLocal into a helper class.
 
-       2. EmitContext should be partially constructed.  No IL Generator.
+       This is required to fix foreach in iterators.
 
-       interface_type review.
+Ideas:
+------
 
-       parameter_array, line 952: `note: must be a single dimension array type'.  Validate this
+       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.
 
 Dead Code Elimination bugs:
 ---------------------------
@@ -179,30 +115,13 @@ Dead Code Elimination bugs:
 
 Major tasks:
 ------------
-
-       Pinned and volatile require type modifiers that can not be encoded
-       with Reflection.Emit.
-
        Properties and 17.6.3: Finish it.
 
-       Implement base indexer access.
-
 readonly variables and ref/out
        
 BUGS
 ----
 
-* Check for Final when overriding, if the parent is Final, then we cant
-  allow an override.
-
-* 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
 
        A finally block should reset the InLoop/LoopBegin/LoopEnd, as
@@ -213,13 +132,6 @@ BUGS
        They should transfer control to the finally block if inside a try/catch
        block.
 
-* Method Registration and error CS111
-
-       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
 > class X {
@@ -234,11 +146,6 @@ PENDING TASKS
 
 * Merge test 89 and test-34
 
-* Revisit
-
-       Primary-expression, as it has now been split into 
-       non-array-creation-expression and array-creation-expression.
-               
 * Code cleanup
 
        The information when registering a method in InternalParameters
@@ -248,12 +155,6 @@ PENDING TASKS
 
        Handle modreq from public apis.
 
-* Emit `pinned' for pinned local variables.
-
-       Both `modreq' and pinned will require special hacks in the compiler.
-
-* Make sure that we are pinning the right variable
-
 * Merge tree.cs, rootcontext.cs
 
 OPTIMIZATIONS
@@ -277,38 +178,11 @@ OPTIMIZATIONS
        The only pending problem is that the code that implements Aliases
        is on TypeContainer, and probably should go in DeclSpace.
 
-* Use of local temporary in UnaryMutator
-
-       We should get rid of the Localtemporary there for some cases
-
-       This turns out to be very complex, at least for the post-version,
-       because this case:
-
-               a = i++
-
-       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).
-
-* Emitcontext
-
-       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.
-
 * Tests
 
        Write tests for the various reference conversions.  We have
        test for all the numeric conversions.
 
-* Optimizations
-
-       In Indexers and Properties, probably support an EmitWithDup
-       That emits the code to call Get and then leaves a this pointer
-       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
@@ -317,12 +191,6 @@ OPTIMIZATIONS
 
 * Add a cache for the various GetArrayMethod operations.
 
-* TypeManager.FindMembers:
-
-       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.
-
 * MakeUnionSet Callers
 
        If the types are the same, there is no need to compute the unionset,
@@ -353,8 +221,3 @@ RECOMMENDATIONS
        Notice how numbering of the arguments changes as the
        { oob_stack.Push (lexer.Location) } takes a "slot"  in the productions.
 
-* local_variable_declaration
-
-       Not sure that this grammar is correct, we might have to
-       resolve this during semantic analysis.
-