+Iterators
+=========
-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.
+ Ok, solved part of the problem, but not the second.
- See the notes on current_container problems below on memory usage.
+ Apparently there are 2 scopes in test-iter-05.cs that
+ are referenced, but when we call "ComputeMethodHost" in
+ iterators.cs:854 this information is not yet available.
-GetNamespaces
--------------
+* Anonymous Methods
+===================
- 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.
+In EmitAnonymousHelperClasses we set the "NeedThis" parameter of all
+the roots, but this is not necessary. We should track the
+"HaveCapturedFields" on a per-ScopeInfo basis, and only set the
+HaveCapturedFields on the proper roots, instead of all the roots.
- 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.
+* Value Parameter
- So pulling all the types takes very little time, maybe we should look into our
- Hashtable implementation to make it more optimal.
+ 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:
- 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.
+ Section 9.3 in the latest spec.
-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.
+* Review
+--------
- This is required because System.Reflection requires that the type/nested types are
- not separated by a dot but by a plus sign.
+ Reference type equality operators (15.9.6) introduced
+ operator == (C x, C y) where C is a reference type.
- A nested class would be My+Class (My being the toplevel, Class the nested one).
+ Our compiler used:
- It is interesting to look at the most called lookups when bootstrapping MCS:
+ operator == (object a, object b)
- 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
+ Review our implementation.
- Analysis:
- The top 9 lookups are done for things which are not types.
+New
+---
- Mono.CSharp.Type happens to be a common lookup: the class Type
- used heavily in the compiler in the default namespace.
+ It would be nice to optimize the case of:
- RED FLAG:
+ Method (new ValueType ())
- 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.
+ 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.
- System.Object is also used a lot as a toplevel class, and we assume it will
- have children, we should just shortcut this.
+NEW NOTES:
+----------
- A cache:
+ ImplicitStandardConversionExists and ImplicitStandardConversion
+ should always be the same, but there are a few diverging lines that
+ must be studied:
- 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.
+ if (expr_type == target_type && !(expr is NullLiteral))
+ return expr;
- This cache is currently enabled with SIMPLE_SPEEDUP in typemanager.cs. Memory consumption
- went down from 74 megs to 65 megs with this change.
+ vs:
-Ideas:
-------
+ if (expr_type == target_type)
+ return true;
- 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
----------------------
+Null Type
+---------
- We could probably use a different system to represent names, like this:
+ Need to introduce the NullType concept into the compiler, to address a
+ few small buglets and remove the hardcoded values for NullLiteral.
- class Name {
- string simplename;
- Name parent;
- }
+ NullLiteral will be the only expression that has the NullType as its type.
- So `System.ComponentModel' becomes:
+ This is what must be used to test for Null literals, instead of `is NullLiteral',
+ and this will introduce a couple of fixes to the rules.
- x: (System, null)
- y: (ComponentModel, x)
+****************************************************************************************
+*
+* The information on the rest of this file is mostly outdated, and its kept here for
+* historical reasons
+*
+****************************************************************************************
+
+Error Reporting:
+----------------
- The problem is that we would still need to construct the name to pass to
- GetType.
+ * Make yyerror show a nice syntax error, instead of the current mess.
-current_container/current_namespace and the DeclSpace
------------------------------------------------------
+Iterators
+---------
+ * Reset should throw not implemented now.
- 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'.
+Optimization ideas
+------------------
- The reason for storing the full names today is 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.
- namespace X {
- class Y {
- }
- }
+ We create too many Arraylists; When we know the size, we should create
+ an array;
- namespace A {
- class Y {
- }
- }
+ During parsing we use arraylists to accumulate data, like this:
- 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.
+ thing:
+
+ thing_list
+ : thing { $$ =new ArrayList (); $$.Add ($1); }
+ | thing_list thing { ArrayList a = $1; a.Add ($2); $$ = a; }
- To fix this problem, we have to make namespaces DeclSpaces.
+ We probably could start using "Pairs" there:
- The full size, contrasted with the size that could be stored is:
- corlib:
- Size of strings held: 368901
- Size of strings short: 147863
+ thing_list
+ : thing { $$ = new Pair ($1, null); }
+ | thing_list thing { Pair p = $1; $$ = new Pair ($2, $1); }
- 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
-
-TODO:
+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.
+
+DeclareLocal audit
+------------------
+
+ DeclareLocal is used in various statements. The audit should be done
+ in two steps:
+
+ * Identify all the declare locals.
+
+ * Identify its uses.
- 1. Create a "partial" emit context for each TypeContainer..
+ * Find if we can make wrapper functions for all of them.
- 2. EmitContext should be partially constructed. No IL Generator.
+ Then we can move DeclareLocal into a helper class.
- interface_type review.
+ This is required to fix foreach in iterators.
+
+Large project:
+--------------
+
+ 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.
+
+ Martin has some some of this work with his TypeHandle code
+ that we could use for this.
+
+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:
---------------------------
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
* 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
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
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
* 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,
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.