-Major tasks:
-------------
+EmitContext.ResolveTypeTree
+---------------------------
- Pinned and volatile require type modifiers that can not be encoded
- with Reflection.Emit.
+ We should investigate its usage. The problem is that by default
+ this will be set when calling FindType, that triggers a more expensive
+ lookup.
- Properties and 17.6.3: Finish it.
+ 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.
- Implement base indexer access.
+Idea
+----
-MethodGroupExpr
+ Keep a cache of name lookups at the DeclSpace level
- These guys should only appear as part of an Invocation, so we
- probably can afford to have a special callback:
+Large project:
+--------------
- Expression.ResolveAllowMemberGroups
+ 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.
- This is only called by Invocation (or anyone that consumes
- MethodGroupExprs)
+ Martin has some some of this work with his TypeHandle code
+ that we could use for this.
- And the regular DoResolve and DoResolveLValue do emit the error
- 654 `Method referenced without argument list'.
+Notes on memory allocation
+--------------------------
- Otherwise, a resolution will return a MethodGroupExpr which is
- not guaranteed to have set its `Expression.Type' to a non-null
- value.
+ A run of the AllocationProfile shows that the compiler allocates roughly
+ 30 megabytes of strings. From those, 20 megabytes come from
+ LookupType.
-readonly variables and ref/out
-
-BUGS
-----
+ See the notes on current_container problems below on memory usage.
-* Check for Final when overriding, if the parent is Final, then we cant
- allow an override.
+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:
+
+ 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
+
+ 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:
-* Do not declare a .property on things that are just implementations, that
- comes from the parent, just do the method.
+ 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.
-* Currently the code path for 108/109 reporting is not being ran for methods
- as we need to compare method signatures. But since we retrieve the expensive
- method arguments in the method, we probably should do 108/109 processing there.
+ System.Object is also used a lot as a toplevel class, and we assume it will
+ have children, we should just shortcut this.
-* Emit warning on hiding members without NEW not only in members.
+ A cache:
-* Implement visibility.
+ 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.
-* Adding variables.
+ This cache is currently enabled with SIMPLE_SPEEDUP in typemanager.cs. Memory consumption
+ went down from 74 megs to 65 megs with this change.
- We do add variables in a number of places, and this is erroneous:
+Ideas:
+------
- void a (int b)
- {
- int b;
+ 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;
}
- Also:
+ So `System.ComponentModel' becomes:
+
+ x: (System, null)
+ y: (ComponentModel, x)
+
+ The problem is that we would still need to construct the name to pass to
+ GetType.
+
+current_container/current_namespace and the DeclSpace
+-----------------------------------------------------
+
+ 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:
- void a (int b)
- {
- foreach (int b ...)
- ;
+ namespace X {
+ class Y {
+ }
}
-* Visibility
+ namespace A {
+ class Y {
+ }
+ }
- I am not reporting errors on visibility yet.
+ 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.
-* Interface indexers
+ To fix this problem, we have to make namespaces DeclSpaces.
- I have not figured out why the Microsoft version puts an
- `instance' attribute, and I am not generating this `instance' attribute.
+ The full size, contrasted with the size that could be stored is:
+ corlib:
+ Size of strings held: 368901
+ Size of strings short: 147863
- Explanation: The reason for the `instance' attribute on
- indexers is that indexers only apply to instances
+ 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
-* Arrays
+
+TODO:
- We need to make sure at *compile time* that the arguments in
- the expression list of an array creation are always positive.
+ 1. Create a "partial" emit context for each TypeContainer..
-* Implement dead code elimination in statement.cs
+ 2. EmitContext should be partially constructed. No IL Generator.
- It is pretty simple to implement dead code elimination in
- if/do/while
+ interface_type review.
-* Indexer bugs:
+ parameter_array, line 952: `note: must be a single dimension array type'. Validate this
- the following wont work:
+Dead Code Elimination bugs:
+---------------------------
- x [0] = x [1] = N
+ I should also resolve all the children expressions in Switch, Fixed, Using.
- if x has indexers, the value of x [N] set is set to void. This needs to be
- fixed.
+Major tasks:
+------------
-* Array declarations
+ Pinned and volatile require type modifiers that can not be encoded
+ with Reflection.Emit.
- Multi-dim arrays are declared as [,] instead of [0..,0..]
+ 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
Method registration should only be used to register methodbuilders,
we need an alternate method of checking for duplicates.
-* We need to catch:
-
- extern string Property {
- get { }
- }
-
- The get there should only have a semicolon
-
*
> // CSC sets beforefieldinit
> class X {
* Merge test 89 and test-34
-* Constant Folding
-
- Constant Folding does not take into account Enumerations, we should maybe
- extract the underlying value, and constant fold on it.
-
* Revisit
Primary-expression, as it has now been split into
non-array-creation-expression and array-creation-expression.
-* Static flow analysis
-
- Required to warn about reachability of code and definite
- assignemt as well as missing returns on functions.
-
* Code cleanup
The information when registering a method in InternalParameters
* Make sure that we are pinning the right variable
-* Maybe track event usage? Currently I am not tracking these, although they
- are fields.
-
+* Merge tree.cs, rootcontext.cs
OPTIMIZATIONS
-------------
+* User Defined Conversions is doing way too many calls to do union sets that are not needed
+
* Add test case for destructors
* Places that use `Ldelema' are basically places where I will be
The only pending problem is that the code that implements Aliases
is on TypeContainer, and probably should go in DeclSpace.
-* Casts need to trigger a name resolution against types only.
-
- currently we use a secret hand shake, probably we should use
- a differen path, and only expressions (memberaccess, simplename)
- would participate in this protocol.
-
* 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.
-* 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.
-
-
-* Constructors
-
- Currently it calls the parent constructor before initializing fields.
- It should do it the other way around.
-
-* Use of EmitBranchable
-
- Currently I use brfalse/brtrue in the code for statements, instead of
- using the EmitBranchable function that lives in Binary
-
-* ConvertImplicit
-
- Currently ConvertImplicit will not catch things like:
-
- - IntLiteral in a float context to generate a -FloatLiteral.
- Instead it will perform an integer load followed by a conversion.
-
* 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
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
* Add a cache for the various GetArrayMethod operations.
-* Optimization:
-
- Do not use StatementCollections, use ArrayLists of Statements,
- and then "copy" it out to arrays. Then reuse the existing
- Statement structures.
-
* TypeManager.FindMembers:
Instead of having hundreds of builder_to_blah hash table, have
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.
+* Factor the lookup code for class declarations an interfaces
+ (interface.cs:GetInterfaceByName)
+
RECOMMENDATIONS
---------------
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)?
-
-************
-Potential bug:
-
- We would need to decode the shortname before we lookup members?
-
- Maybe not.
-
-interface I {
- void A ();
-}
-
-class X : I {
- void I.A ();
-}
-
-class Y : X, I {
- void I.A () {}
-}
-
-
-
-*************
-