/[eiffelstudio]/branches/CAT_mono/Src/Eiffel/eiffel/genericity/cl_type_i.e
ViewVC logotype

Annotation of /branches/CAT_mono/Src/Eiffel/eiffel/genericity/cl_type_i.e

Parent Directory Parent Directory | Revision Log Revision Log


Revision 39713 - (hide annotations)
Fri Oct 17 19:27:17 2003 UTC (16 years, 4 months ago) by manus
Original Path: trunk/Src/bench/Eiffel/eiffel/genericity/cl_type_i.e
File size: 13997 byte(s)
Fixed eweasel bug `freez026'. By previously fixing the way we handle
creation of generic type using anchored in their specification (e.g. A [like f])
we introduced a bug of type result caching. Indeed before when a `typarr'
had an anchor it contained either LIKE_ARG_TYPE, LIKE_CURRENT_TYPE,
LIKE_PFEATURE_TYPE or LIKE_FEATURE_TYPE. In such cases the C runtime
was preventing the caching of the information.
Now since we do not generate the LIKE_XX constants, but force a computation
of the value in the generated code the caching mechanism was not prevented
therefore in such cases it was giving the proper result the first time around
but not the second time around if the `anchors' were different.

To prevent this we tell the runtime if it can cache it by providing a non NULL
buffer, it cannot if we pass NULL.
To find out if we can pass a non-NULL or NULL, we simply find out if the
generic type is `is_explicit'. When it is `is_explicit, it is known for not
changing during the whole life of the application and we pass a non NULL buffer.
When it is not `is_explicit' then the value would have to be recomputed
each time it is queried, therefore we pass a NULL buffer.

To improve performance in non multithreaded mode we always mark the `typarr'
a static structure. As only one thread at the time can modify it if the
generic type is not explicit. In multithreaded mode, this is not the case
and therefore it is not `static'.

FIXME: we might be better off using `uint16' as on some platforms unsigned
operation are much faster than signed one. The second advantage will be to
increase the number of possible dynamic types from ~32000 to ~65000.

1 manus 26913 indexing
2     description: "Type class."
3     date: "$Date$"
4     revision: "$Revision$"
5 grator 18
6     class CL_TYPE_I
7    
8     inherit
9     TYPE_I
10     redefine
11     is_reference,
12 manus 26913 is_true_expanded,
13 xavierl 4623 is_separate,
14 grator 236 is_valid,
15 manus 11218 is_explicit,
16 manus 28380 is_external,
17 grator 18 same_as,
18     c_type,
19 grator 930 instantiation_in,
20 manus 10818 complete_instantiation_in,
21     conforms_to_array,
22     generated_id,
23 manus 11298 generate_cid,
24 manus 14013 make_gen_type_byte_code,
25     generate_cid_array,
26 manus 30169 generate_cid_init,
27 manus 35665 generate_gen_type_il,
28     generate_expanded_creation
29 grator 18 end
30 manus 30169
31     DEBUG_OUTPUT
32     export
33     {NONE} all
34     end
35 grator 18
36 manus 33952 SHARED_IL_CASING
37     export
38     {NONE} all
39     end
40    
41 manus 35665 SHARED_GENERATION
42     export
43     {NONE} all
44     end
45    
46     SHARED_DECLARATIONS
47     export
48     {NONE} all
49     end
50    
51 manus 30224 create
52     make
53    
54     feature {NONE} -- Initialization
55    
56     make (id: INTEGER) is
57 manus 30293 -- Create new instance of `Current' with `class_id'
58 manus 30224 -- assigned with `id'.
59     require
60     valid_id: id > 0
61     do
62 manus 30293 class_id := id
63 manus 30224 ensure
64 manus 30293 class_id_set: class_id = id
65 manus 30224 end
66    
67 manus 26913 feature -- Access
68 grator 18
69 manus 30293 class_id: INTEGER
70 grator 18 -- Base class id of the type class
71    
72     meta_generic: META_GENERIC is
73     -- Meta generic array describing the type class
74     do
75     -- No meta generic in non-generic type
76 manus 9655 end
77 grator 18
78 manus 10890 cr_info : CREATE_INFO
79     -- Additional information for the creation
80     -- of generic types with anchored parameters
81    
82 manus 10818 true_generics : ARRAY [TYPE_I] is
83     -- Array of generics: no mapping reference -> REFERENCE_I
84     do
85     -- Non generic types don't have them
86     end
87    
88 grator 18 base_class: CLASS_C is
89     -- Base class associated to the class type
90     do
91 manus 30293 Result := System.class_of_id (class_id)
92 manus 9655 end
93 grator 18
94 manus 26913 type_a: CL_TYPE_A is
95 grator 236 do
96 manus 30293 create Result.make (class_id)
97 manus 26913 Result.set_is_true_expanded (is_true_expanded)
98     Result.set_is_separate (is_separate)
99 manus 9655 end
100 grator 236
101 manus 33952 il_type_name (a_prefix: STRING): STRING is
102 manus 26913 -- Class name of current type.
103 manus 29681 local
104     l_class_c: like base_class
105 manus 34253 l_is_precompiled: BOOLEAN
106     l_cl_type: like associated_class_type
107 grator 18 do
108 manus 29681 l_class_c := base_class
109     if l_class_c.is_external then
110 manus 34253 Result := clone (l_class_c.external_class_name)
111 manus 29681 else
112 manus 34253 l_is_precompiled := l_class_c.is_precompiled
113     if l_is_precompiled then
114     l_cl_type := associated_class_type
115     l_is_precompiled := l_cl_type.is_precompiled
116     if l_is_precompiled then
117     Result := associated_class_type.il_type_name (a_prefix)
118     end
119     end
120     if not l_is_precompiled then
121     Result := internal_il_type_name (clone (l_class_c.name), a_prefix)
122     end
123 manus 29681 end
124 manus 11218 end
125    
126 grator 18 instantiation_in (other: GEN_TYPE_I): CL_TYPE_I is
127     -- Instantiation of Current in context of `other'
128 grator 282 require else
129     True
130 grator 18 do
131 manus 9655 Result := Current
132     end
133 grator 18
134 manus 10818 complete_instantiation_in (other: GEN_TYPE_I): CL_TYPE_I is
135     -- Instantiation of Current in context of `other'
136     require else
137     True
138     do
139     Result := Current
140     end
141    
142 grator 18 description: ATTR_DESC is
143     -- Type description for skeletons
144     local
145 michaels 7681 exp: EXPANDED_DESC
146     ref: REFERENCE_DESC
147 grator 485 do
148 manus 26913 if is_true_expanded then
149 julieng 37663 create exp
150 manus 26913 is_true_expanded := False
151 manus 32282 exp.set_class_type (base_class.types.search_item (Current))
152 manus 26913 is_true_expanded := True
153 manus 13232 exp.set_type_i (Current)
154 manus 9655 Result := exp
155 xavierl 4623 elseif is_separate then
156     -- FIXME
157     Result := c_type.description
158 grator 18 else
159 manus 9655 Result := c_type.description
160     end
161 michaels 7681
162     ref ?= Result
163     if ref /= Void then
164 manus 34621 ref.set_type_i (Current)
165 michaels 7681 end
166 manus 9655 end
167 grator 18
168     c_type: TYPE_C is
169     -- Associated C type
170     do
171 manus 9655 Result := Reference_c_type
172     end
173 manus 28618
174 grator 18 associated_class_type: CLASS_TYPE is
175     -- Associated class type
176 michaels 7681 require
177 manus 16188 -- has: has_associated_class_type
178 grator 485 do
179 manus 26913 if is_true_expanded then
180     is_true_expanded := False
181 manus 32282 Result := base_class.types.search_item (Current)
182 manus 26913 is_true_expanded := True
183 xavierl 4623 elseif is_separate then
184 manus 11065 is_separate := False
185 manus 32282 Result := base_class.types.search_item (Current)
186 manus 11065 is_separate := True
187 grator 485 else
188 manus 32282 Result := base_class.types.search_item (Current)
189 manus 9655 end
190     end
191 grator 18
192     type_id: INTEGER is
193     -- Type id of the correponding class type
194     do
195 manus 9655 Result := associated_class_type.type_id
196     end
197 grator 18
198 manus 26913 sk_value: INTEGER is
199     -- Generate SK value associated to the current type.
200 grator 18 do
201 xavierl 4623 -- FIXME????: separate
202 manus 26913 if not is_true_expanded then
203 manus 31263 Result := Sk_ref | (type_id - 1)
204 grator 18 else
205 manus 26913 is_true_expanded := False
206 manus 31263 Result := Sk_exp | (type_id - 1)
207 manus 26913 is_true_expanded := True
208 manus 9655 end
209     end
210 grator 18
211 manus 26913 cecil_value: INTEGER is
212     do
213     -- FIXME????: separate
214     if not is_true_expanded then
215     Result := Sk_dtype
216     else
217 manus 31263 Result := Sk_exp | class_id
218 manus 26913 end
219     end
220    
221 grator 18 hash_code: INTEGER is
222     -- Hash code for current type
223     do
224 manus 30293 Result := Other_code + class_id
225 manus 9655 end
226 grator 18
227 manus 26913 feature -- Status
228    
229 manus 31541 element_type: INTEGER_8 is
230     -- Void element type
231     do
232 manus 31580 if is_expanded and base_class.is_external then
233     -- We only support expanded for external class at the moment.
234 manus 31541 Result := feature {MD_SIGNATURE_CONSTANTS}.Element_type_valuetype
235     else
236 manus 37130 if class_id = System.system_string_class.compiled_class.class_id then
237 manus 31541 Result := feature {MD_SIGNATURE_CONSTANTS}.Element_type_string
238 manus 37130 elseif class_id = System.system_object_id then
239 manus 31541 Result := feature {MD_SIGNATURE_CONSTANTS}.Element_type_object
240     else
241     Result := feature {MD_SIGNATURE_CONSTANTS}.Element_type_class
242     end
243     end
244     end
245    
246 manus 26913 is_true_expanded: BOOLEAN
247     -- Is the type expanded?
248    
249     is_separate: BOOLEAN
250     -- Is the type separate?
251    
252     is_enum: BOOLEAN is
253     -- Is current type an IL enum type?
254     -- Useful to find out if some call optimization can be done
255     -- in FEATURE_B.
256     require
257     il_generation: System.il_generation
258 grator 18 do
259 manus 26913 Result := is_true_expanded and then base_class.is_enum
260     end
261    
262 manus 28380 is_external: BOOLEAN is
263     -- Is current type an IL enum type?
264     -- Useful to find out if some call optimization can be done
265     -- in FEATURE_B.
266     do
267     Result := base_class.is_external
268     end
269    
270 manus 26913 is_valid: BOOLEAN is
271 manus 35544 -- Is the base class still in the system and matches its specification?
272 manus 26913 do
273 manus 35544 Result := base_class /= Void and then (base_class.generics = Void)
274 manus 26913 end
275    
276     is_reference: BOOLEAN is
277     -- Is the type a reference type ?
278     do
279     Result := not is_true_expanded
280     end;
281    
282     is_explicit: BOOLEAN is
283 manus 39713 -- Is Current type fixed at compile time?
284 manus 26913 do
285 manus 39713 if cr_info /= Void then
286     Result := cr_info.is_explicit
287     else
288     Result := True
289     end
290 manus 26913 end
291    
292     has_associated_class_type: BOOLEAN is
293     -- Has `Current' an associated class type?
294     do
295     if is_true_expanded then
296     is_true_expanded := False
297     Result := base_class.types.has_type (Current)
298     is_true_expanded := True
299     elseif is_separate then
300     is_separate := False
301     Result := base_class.types.has_type (Current)
302     is_separate := True
303 grator 18 else
304 manus 26913 Result := base_class.types.has_type (Current)
305 manus 9655 end
306     end
307 grator 18
308 manus 26913 same_as (other: TYPE_I): BOOLEAN is
309     -- Is `other' equal to Current ?
310     local
311     other_cl_type: CL_TYPE_I
312 grator 508 do
313 manus 26913 other_cl_type ?= other
314     Result := other_cl_type /= Void -- FIXME
315 manus 30293 and then other_cl_type.class_id = class_id
316 manus 26913 and then other_cl_type.is_true_expanded = is_true_expanded
317     and then other_cl_type.is_separate = is_separate
318     and then other_cl_type.meta_generic = Void
319     and then other_cl_type.true_generics = Void
320     end
321    
322     feature -- Setting
323    
324     set_is_true_expanded (b: BOOLEAN) is
325     -- Assign `b' to `is_true_expanded'.
326     do
327     is_true_expanded := b
328 manus 35178 ensure
329     is_true_expanded_set: is_true_expanded = b
330 manus 26913 end
331    
332     set_is_separate (b: BOOLEAN) is
333     -- Assign `b' to `is_separate'.
334     do
335     is_separate := b
336 manus 35178 ensure
337     is_separate_set: is_separate = b
338 manus 26913 end
339    
340     set_cr_info (cinfo : CREATE_INFO) is
341     -- Set `cr_info' to `cinfo'.
342 manus 30224 require
343     create_info_not_void: cinfo /= Void
344 manus 26913 do
345     cr_info := cinfo
346     ensure
347     cr_info_set : cr_info = cinfo
348     end
349    
350     feature -- Formatting
351    
352     append_signature (st: STRUCTURED_TEXT) is
353     do
354     if is_true_expanded then
355     st.add_string ("expanded ")
356     elseif is_separate then
357     st.add_string ("separate ")
358     end
359     base_class.append_signature (st)
360     end
361    
362     dump (buffer: GENERATION_BUFFER) is
363     do
364 manus 30169 buffer.putstring (debug_output)
365 manus 26913 end
366    
367     feature -- C generation
368    
369 manus 35665 generate_expanded_creation (byte_code: BYTE_CODE; reg: REGISTRABLE; workbench_mode: BOOLEAN) is
370     -- Generate creation of expanded object associated to Current.
371     local
372     gen_type: GEN_TYPE_I
373     written_class: CLASS_C
374     class_type, written_type: CLASS_TYPE
375     creation_feature: FEATURE_I
376     c_name: STRING
377     buffer: GENERATION_BUFFER
378     do
379     buffer := byte_code.buffer
380    
381     gen_type ?= Current
382    
383     if gen_type /= Void then
384     byte_code.generate_block_open
385     byte_code.generate_gen_type_conversion (gen_type)
386     end
387     reg.print_register
388     if workbench_mode then
389     -- RTLX is a macro used to create
390     -- expanded types
391     if gen_type /= Void then
392     buffer.putstring (" = RTLX(typres")
393     else
394     buffer.putstring (" = RTLX(RTUD(")
395     buffer.generate_type_id (associated_class_type.static_type_id)
396     buffer.putchar (')')
397     end
398     else
399     if gen_type /= Void then
400     buffer.putstring (" = RTLN(typres")
401     else
402     buffer.putstring (" = RTLN(")
403     buffer.putint (type_id - 1)
404     end
405     class_type := associated_class_type
406     creation_feature := class_type.associated_class.creation_feature
407     if creation_feature /= Void then
408     written_class := System.class_of_id (creation_feature.written_in)
409     if written_class.generics = Void then
410     written_type := written_class.types.first
411     else
412     written_type :=
413     written_class.meta_type (class_type.type).associated_class_type
414     end
415     c_name := Encoder.feature_name (written_type.static_type_id,
416     creation_feature.body_index)
417 manus 35702 buffer.putstring (");")
418     buffer.new_line
419 manus 35665 buffer.putstring (c_name)
420     buffer.putchar ('(')
421     reg.print_register
422     Extern_declarations.add_routine_with_signature (Void_c_type,
423     c_name, <<"EIF_REFERENCE">>)
424     end
425     end
426     buffer.putchar (')')
427     buffer.putchar (';')
428    
429     if gen_type /= Void then
430     byte_code.generate_block_close
431     end
432     buffer.new_line
433     end
434    
435 manus 26913 generate_cecil_value (buffer: GENERATION_BUFFER) is
436     -- Generate cecil value
437     do
438 xavierl 4623 -- FIXME????: separate
439 manus 26913 if not is_true_expanded then
440     buffer.putstring ("SK_DTYPE")
441 grator 508 else
442 manus 26913 buffer.putstring ("SK_EXP + (uint32) ")
443 manus 34563 buffer.putint (associated_class_type.type_id - 1)
444 manus 9655 end
445     end
446 grator 508
447 grator 930 feature -- Array optimization
448    
449     conforms_to_array: BOOLEAN is
450     do
451     Result := base_class.conform_to (array_class_c)
452 manus 9655 end
453 grator 930
454     feature {NONE} -- Array optimization
455    
456     array_class_c: CLASS_C is
457     once
458     Result := System.array_class.compiled_class
459 manus 9655 end
460 grator 930
461 manus 10818 feature -- Generic conformance
462    
463     generated_id (final_mode : BOOLEAN) : INTEGER is
464 manus 11298
465 manus 10818 do
466 manus 11298 if final_mode then
467     Result := type_id - 1
468 manus 10818 else
469 manus 26913 Result := associated_class_type.static_type_id-1
470 manus 10818 end
471 manus 11298
472 manus 26913 if is_true_expanded then
473     Result := Expanded_level - Result
474 manus 11298 end
475 manus 10818 end
476    
477 manus 11599 generate_cid (buffer : GENERATION_BUFFER; final_mode, use_info : BOOLEAN) is
478 manus 11298
479 manus 10818 do
480 manus 11209 if
481     use_info and then (cr_info /= Void)
482 manus 26913 and then not is_expanded
483 manus 11209 then
484     -- It's an anchored type
485 manus 11599 cr_info.generate_cid (buffer, final_mode)
486 manus 39412 else
487     buffer.putint (generated_id (final_mode))
488     buffer.putstring (", ")
489 manus 10890 end
490 manus 10818 end
491    
492 manus 10890 make_gen_type_byte_code (ba : BYTE_ARRAY; use_info : BOOLEAN) is
493 manus 10818 do
494 manus 11209 if
495     use_info and then (cr_info /= Void)
496 manus 26913 and then not is_expanded
497 manus 11209 then
498     -- It's an anchored type
499 manus 10890 cr_info.make_gen_type_byte_code (ba)
500 manus 39412 else
501     ba.append_short_integer (generated_id (False))
502 manus 10890 end
503 manus 10818 end
504    
505 manus 14013 generate_cid_array (buffer : GENERATION_BUFFER;
506     final_mode, use_info : BOOLEAN; idx_cnt : COUNTER) is
507     local
508     dummy : INTEGER
509     do
510     if
511     use_info and then (cr_info /= Void)
512 manus 26913 and then not is_expanded
513 manus 14013 then
514 manus 39412 -- It's an anchored type
515 manus 14013 cr_info.generate_cid_array (buffer, final_mode, idx_cnt)
516 manus 39412 else
517     buffer.putint (generated_id (final_mode))
518     buffer.putstring (", ")
519    
520     -- Increment counter
521     dummy := idx_cnt.next
522 manus 14013 end
523     end
524    
525     generate_cid_init (buffer : GENERATION_BUFFER;
526     final_mode, use_info : BOOLEAN; idx_cnt : COUNTER) is
527     local
528     dummy : INTEGER
529     do
530     if
531     use_info and then (cr_info /= Void)
532 manus 26913 and then not is_expanded
533 manus 14013 then
534     -- It's an anchored type
535     cr_info.generate_cid_init (buffer, final_mode, idx_cnt)
536 manus 39412 else
537     dummy := idx_cnt.next
538 manus 14013 end
539     end
540 manus 30169
541     feature -- Generic conformance for IL
542    
543     generate_gen_type_il (il_generator: IL_CODE_GENERATOR; use_info : BOOLEAN) is
544     -- `use_info' is true iff we generate code for a
545     -- creation instruction.
546     do
547     if use_info and then cr_info /= Void then
548 manus 30582 -- It's an anchored type, we call feature
549     -- that will tell us the real type of the
550     -- anchor in the context of Current.
551     cr_info.generate_il_type
552     else
553     il_generator.generate_class_type_instance (Current)
554 manus 30169 end
555     end
556    
557     feature -- Output
558    
559     debug_output: STRING is
560     -- String that should be displayed in debugger to represent `Current'.
561     do
562     create Result.make (32)
563     if is_true_expanded then
564     Result.append ("expanded ")
565     elseif is_separate then
566     Result.append ("separate ")
567     end
568     Result.append (base_class.name_in_upper)
569     end
570 manus 33952
571     feature {NONE} -- Implementation
572    
573     internal_il_type_name (a_base_name, a_prefix: STRING): STRING is
574     -- Full type name of `a_base_name' using `a_prefix' in IL code generation
575     -- with namespace specification
576     require
577     a_base_name_not_void: a_base_name /= Void
578     local
579     l_name: STRING
580     do
581     Result := a_base_name
582     l_name := base_class.lace_class.actual_namespace
583     if a_prefix /= Void then
584     if l_name.is_empty then
585     l_name := a_prefix + "."
586     else
587 manus 34253 l_name := il_casing.namespace_casing (System.dotnet_naming_convention,
588     l_name) + "." + a_prefix + "."
589 manus 33952 end
590     else
591     if not l_name.is_empty then
592 manus 34253 l_name := il_casing.namespace_casing (System.dotnet_naming_convention,
593     l_name) + "."
594 manus 33952 end
595     end
596 manus 34253 Result := l_name + il_casing.pascal_casing (System.dotnet_naming_convention,
597     Result, feature {IL_CASING_CONVERSION}.upper_case)
598 manus 33952 ensure
599     internal_il_type_name_not_void: Result /= Void
600     internal_il_type_name_not_empty: not Result.is_empty
601     end
602    
603 grator 18 end

Properties

Name Value
svn:eol-style native
svn:keywords Author Date Id Revision

  ViewVC Help
Powered by ViewVC 1.1.23