4 * Fix simple case (foreach)
5 * Study side effects with assign
6 * Study TemporaryStorage/LocalStorage -> Merge/rename
8 Big issues: try/finally in iterators.
13 It would be nice to have things that can be "instances" to have an
14 EmitInstance method (this would default to nothing).
16 The idea is to be able to use efficiently the instance data on stack
17 manipulations, as opposed to the current scheme, where we basically have
23 Currently when we build a type cache, it contains private members,
24 internal members, and internal protected members; We should trim
25 these out, as it shows up on the profile.
27 We create too many Arraylists; When we know the size, we should create
30 During parsing we use arraylists to accumulate data, like this:
35 : thing { $$ =new ArrayList (); $$.Add ($1); }
36 | thing_list thing { ArrayList a = $1; a.Add ($2); $$ = a; }
38 We probably could start using "Pairs" there:
41 : thing { $$ = new Pair ($1, null); }
42 | thing_list thing { Pair p = $1; $$ = new Pair ($2, $1); }
50 * Resolve anonymous methods before.
51 * Each time a Local matches, if the mode is `InAnonymous', flag
52 the VariableInfo for `proxying'.
53 * During Resolve track the depth required for local variables.
54 * Before Emit, create proxy classes with proper depth.
58 During Resolve, track all the return types.
59 Allow for ec.ReturnType to be null, indicating `Pending Return Evaluation'
63 Create a toplevel block for anonymous methods?
65 EmitContext.ResolveTypeTree
66 ---------------------------
68 We should investigate its usage. The problem is that by default
69 this will be set when calling FindType, that triggers a more expensive
72 I believe we should pass the current EmitContext (which has this turned off
73 by default) to ResolveType/REsolveTypeExpr and then have the routines that
74 need ResolveType to pass null as the emit context.
79 DeclareLocal is used in various statements. The audit should be done
82 * Identify all the declare locals.
86 * Find if we can make wrapper functions for all of them.
88 Then we can move DeclareLocal into a helper class.
90 This is required to fix foreach in iterators.
95 Drop FindMembers as our API and instead extract all the data
96 out of a type the first time into our own datastructures, and
97 use that to navigate and search the type instead of the
98 callback based FindMembers.
100 Martin has some some of this work with his TypeHandle code
101 that we could use for this.
103 Notes on memory allocation
104 --------------------------
106 A run of the AllocationProfile shows that the compiler allocates roughly
107 30 megabytes of strings. From those, 20 megabytes come from
110 See the notes on current_container problems below on memory usage.
112 LookupTypeReflection:
113 ---------------------
115 With something like `System.Object', LookupTypeReflection will be called
116 twice: once to find out that `System' is not a type and once
119 This is required because System.Reflection requires that the type/nested types are
120 not separated by a dot but by a plus sign.
122 A nested class would be My+Class (My being the toplevel, Class the nested one).
124 It is interesting to look at the most called lookups when bootstrapping MCS:
127 713 LTR: System.Globalization
128 822 LTR: System.Object+Expression
129 904 LTR: Mono.CSharp.ArrayList
130 976 LTR: System.Runtime.CompilerServices
132 1118 LTR: System.Runtime
133 1208 LTR: Mono.CSharp.Type
134 1373 LTR: Mono.Languages
135 1599 LTR: System.Diagnostics
136 2036 LTR: System.Text
137 2302 LTR: System.Reflection.Emit
138 2515 LTR: System.Collections
139 4527 LTR: System.Reflection
140 22273 LTR: Mono.CSharp
145 The top 9 lookups are done for things which are not types.
147 Mono.CSharp.Type happens to be a common lookup: the class Type
148 used heavily in the compiler in the default namespace.
152 Then `Type' is looked up alone a lot of the time, this happens
153 in parameter declarations and am not entirely sure that this is
154 correct (FindType will pass to LookupInterfaceOrClass a the current_type.FullName,
155 which for some reason is null!). This seems to be a problem with a lost
156 piece of context during FindType.
158 System.Object is also used a lot as a toplevel class, and we assume it will
159 have children, we should just shortcut this.
163 Adding a cache and adding a catch for `System.Object' to flag that it wont be the
164 root of a hierarchy reduced the MCS bootstrap time from 10.22 seconds to 8.90 seconds.
166 This cache is currently enabled with SIMPLE_SPEEDUP in typemanager.cs. Memory consumption
167 went down from 74 megs to 65 megs with this change.
172 Instead of the hack that *knows* about System.Object not having any children classes,
173 we should just make it simple for a probe to know that there is no need for it.
175 The use of DottedName
176 ---------------------
178 We could probably use a different system to represent names, like this:
185 So `System.ComponentModel' becomes:
188 y: (ComponentModel, x)
190 The problem is that we would still need to construct the name to pass to
193 current_container/current_namespace and the DeclSpace
194 -----------------------------------------------------
196 We are storing fully qualified names in the DeclSpace instead of the node,
197 this is because `current_namespace' (Namepsace) is not a DeclSpace like
200 The reason for storing the full names today is this:
212 The problem is that we only use the namespace stack to track the "prefix"
213 for typecontainers, but they are not typecontainers themselves, so we have
214 to use fully qualified names, because both A.X and A.Y would be entered
215 in the toplevel type container. If we use the short names, there would be
218 To fix this problem, we have to make namespaces DeclSpaces.
220 The full size, contrasted with the size that could be stored is:
222 Size of strings held: 368901
223 Size of strings short: 147863
226 Size of strings held: 212677
227 Size of strings short: 97521
230 Size of strings held: 128055
231 Size of strings short: 35782
234 Size of strings held: 117896
235 Size of strings short: 36153
238 Size of strings held: 194527
239 Size of strings short: 58064
241 System.Windows.Forms:
242 Size of strings held: 220495
243 Size of strings short: 64923
248 1. Create a "partial" emit context for each TypeContainer..
250 2. EmitContext should be partially constructed. No IL Generator.
252 interface_type review.
254 parameter_array, line 952: `note: must be a single dimension array type'. Validate this
256 Dead Code Elimination bugs:
257 ---------------------------
259 I should also resolve all the children expressions in Switch, Fixed, Using.
264 Pinned and volatile require type modifiers that can not be encoded
265 with Reflection.Emit.
267 Properties and 17.6.3: Finish it.
269 Implement base indexer access.
271 readonly variables and ref/out
276 * Check for Final when overriding, if the parent is Final, then we cant
281 I have not figured out why the Microsoft version puts an
282 `instance' attribute, and I am not generating this `instance' attribute.
284 Explanation: The reason for the `instance' attribute on
285 indexers is that indexers only apply to instances
287 * Break/Continue statements
289 A finally block should reset the InLoop/LoopBegin/LoopEnd, as
290 they are logically outside the scope of the loop.
292 * Break/continue part 2.
294 They should transfer control to the finally block if inside a try/catch
297 * Method Registration and error CS111
299 The way we use the method registration to signal 111 is wrong.
301 Method registration should only be used to register methodbuilders,
302 we need an alternate method of checking for duplicates.
305 > // CSC sets beforefieldinit
307 > // .cctor will be generated by compiler
308 > public static readonly object O = new System.Object ();
309 > public static void Main () {}
316 * Merge test 89 and test-34
320 Primary-expression, as it has now been split into
321 non-array-creation-expression and array-creation-expression.
325 The information when registering a method in InternalParameters
326 is duplicated, you can always get the types from the InternalParameters
328 * Emit modreq for volatiles
330 Handle modreq from public apis.
332 * Emit `pinned' for pinned local variables.
334 Both `modreq' and pinned will require special hacks in the compiler.
336 * Make sure that we are pinning the right variable
338 * Merge tree.cs, rootcontext.cs
343 * User Defined Conversions is doing way too many calls to do union sets that are not needed
345 * Add test case for destructors
347 * Places that use `Ldelema' are basically places where I will be
348 initializing a value type. I could apply an optimization to
349 disable the implicit local temporary from being created (by using
352 * Dropping TypeContainer as an argument to EmitContext
354 My theory is that I can get rid of the TypeBuilder completely from
355 the EmitContext, and have typecasts where it is used (from
356 DeclSpace to where it matters).
358 The only pending problem is that the code that implements Aliases
359 is on TypeContainer, and probably should go in DeclSpace.
361 * Use of local temporary in UnaryMutator
363 We should get rid of the Localtemporary there for some cases
365 This turns out to be very complex, at least for the post-version,
370 To produce optimal code, it is necessary for UnaryMutator to know
371 that it is being assigned to a variable (the way the stack is laid
372 out using dup requires the store to happen inside UnaryMutator).
376 Write tests for the various reference conversions. We have
377 test for all the numeric conversions.
381 In Indexers and Properties, probably support an EmitWithDup
382 That emits the code to call Get and then leaves a this pointer
383 in the stack, so that later a Store can be emitted using that
384 this pointer (consider Property++ or Indexer++)
386 * Optimizations: variable allocation.
388 When local variables of a type are required, we should request
389 the variable and later release it when we are done, so that
390 the same local variable slot can be reused later on.
392 * Add a cache for the various GetArrayMethod operations.
394 * MakeUnionSet Callers
396 If the types are the same, there is no need to compute the unionset,
397 we can just use the list from one of the types.
399 * Factor the lookup code for class declarations an interfaces
400 (interface.cs:GetInterfaceByName)
405 * Use of lexer.Location in the parser
409 TOKEN nt TERMINAL nt TERMINAL nt3 {
410 $$ = new Blah ($2, $4, $6, lexer.Location);
413 This is bad, because the lexer.Location is for the last item in `nt3'
415 We need to change that to use this pattern:
417 TOKEN { oob_stack.Push (lexer.Location) } nt TERMINAL nt TERMINAL nt3 {
418 $$ = new Blah ($3, $5, $7, (Location) oob_stack.Pop ());
421 Notice how numbering of the arguments changes as the
422 { oob_stack.Push (lexer.Location) } takes a "slot" in the productions.
424 * local_variable_declaration
426 Not sure that this grammar is correct, we might have to
427 resolve this during semantic analysis.