3 * `yield' is no longer a keyword, it only has special
4 meaning before a return or break keywords.
6 * Study side effects with assign
7 * Study TemporaryStorage/LocalStorage -> Merge/rename
9 * Reset should throw not implemented now.
14 It would be nice to have things that can be "instances" to have an
15 EmitInstance method (this would default to nothing).
17 The idea is to be able to use efficiently the instance data on stack
18 manipulations, as opposed to the current scheme, where we basically have
24 Currently when we build a type cache, it contains private members,
25 internal members, and internal protected members; We should trim
26 these out, as it shows up on the profile.
28 We create too many Arraylists; When we know the size, we should create
31 During parsing we use arraylists to accumulate data, like this:
36 : thing { $$ =new ArrayList (); $$.Add ($1); }
37 | thing_list thing { ArrayList a = $1; a.Add ($2); $$ = a; }
39 We probably could start using "Pairs" there:
42 : thing { $$ = new Pair ($1, null); }
43 | thing_list thing { Pair p = $1; $$ = new Pair ($2, $1); }
51 * Resolve anonymous methods before.
52 * Each time a Local matches, if the mode is `InAnonymous', flag
53 the VariableInfo for `proxying'.
54 * During Resolve track the depth required for local variables.
55 * Before Emit, create proxy classes with proper depth.
59 Create a toplevel block for anonymous methods?
61 EmitContext.ResolveTypeTree
62 ---------------------------
64 We should investigate its usage. The problem is that by default
65 this will be set when calling FindType, that triggers a more expensive
68 I believe we should pass the current EmitContext (which has this turned off
69 by default) to ResolveType/REsolveTypeExpr and then have the routines that
70 need ResolveType to pass null as the emit context.
75 DeclareLocal is used in various statements. The audit should be done
78 * Identify all the declare locals.
82 * Find if we can make wrapper functions for all of them.
84 Then we can move DeclareLocal into a helper class.
86 This is required to fix foreach in iterators.
91 Drop FindMembers as our API and instead extract all the data
92 out of a type the first time into our own datastructures, and
93 use that to navigate and search the type instead of the
94 callback based FindMembers.
96 Martin has some some of this work with his TypeHandle code
97 that we could use for this.
99 Notes on memory allocation
100 --------------------------
104 A run of the AllocationProfile shows that the compiler allocates roughly
105 30 megabytes of strings. From those, 20 megabytes come from
108 See the notes on current_container problems below on memory usage.
110 LookupTypeReflection:
111 ---------------------
113 With something like `System.Object', LookupTypeReflection will be called
114 twice: once to find out that `System' is not a type and once
117 This is required because System.Reflection requires that the type/nested types are
118 not separated by a dot but by a plus sign.
120 A nested class would be My+Class (My being the toplevel, Class the nested one).
122 It is interesting to look at the most called lookups when bootstrapping MCS:
125 713 LTR: System.Globalization
126 822 LTR: System.Object+Expression
127 904 LTR: Mono.CSharp.ArrayList
128 976 LTR: System.Runtime.CompilerServices
130 1118 LTR: System.Runtime
131 1208 LTR: Mono.CSharp.Type
132 1373 LTR: Mono.Languages
133 1599 LTR: System.Diagnostics
134 2036 LTR: System.Text
135 2302 LTR: System.Reflection.Emit
136 2515 LTR: System.Collections
137 4527 LTR: System.Reflection
138 22273 LTR: Mono.CSharp
143 The top 9 lookups are done for things which are not types.
145 Mono.CSharp.Type happens to be a common lookup: the class Type
146 used heavily in the compiler in the default namespace.
150 Then `Type' is looked up alone a lot of the time, this happens
151 in parameter declarations and am not entirely sure that this is
152 correct (FindType will pass to LookupInterfaceOrClass a the current_type.FullName,
153 which for some reason is null!). This seems to be a problem with a lost
154 piece of context during FindType.
156 System.Object is also used a lot as a toplevel class, and we assume it will
157 have children, we should just shortcut this.
161 Adding a cache and adding a catch for `System.Object' to flag that it wont be the
162 root of a hierarchy reduced the MCS bootstrap time from 10.22 seconds to 8.90 seconds.
164 This cache is currently enabled with SIMPLE_SPEEDUP in typemanager.cs. Memory consumption
165 went down from 74 megs to 65 megs with this change.
170 Instead of the hack that *knows* about System.Object not having any children classes,
171 we should just make it simple for a probe to know that there is no need for it.
173 The use of DottedName
174 ---------------------
176 We could probably use a different system to represent names, like this:
183 So `System.ComponentModel' becomes:
186 y: (ComponentModel, x)
188 The problem is that we would still need to construct the name to pass to
191 This has been now implemented, its called "QualifiedIdentifier"
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.