/[eiffelstudio]/branches/CAT_mono/Src/Eiffel/eiffel/byte_code/feature_b.e
ViewVC logotype

Contents of /branches/CAT_mono/Src/Eiffel/eiffel/byte_code/feature_b.e

Parent Directory Parent Directory | Revision Log Revision Log


Revision 69868 - (show annotations)
Fri Aug 3 22:28:26 2007 UTC (12 years, 4 months ago) by martins
File size: 13720 byte(s)
enabled more types to store monomorph information
1 indexing
2 description : "Byte code generation for feature call."
3 legal: "See notice at end of class."
4 status: "See notice at end of class."
5 date: "$Date$"
6 revision: "$Revision$"
7
8 class FEATURE_B
9
10 inherit
11 CALL_ACCESS_B
12 redefine
13 is_feature, set_parameters,
14 parameters, enlarged, enlarged_on, context_type,
15 is_feature_special, make_special_byte_code,
16 is_unsafe, optimized_byte_node,
17 calls_special_features, is_special_feature,
18 size, pre_inlined_code, inlined_byte_code
19 end
20
21 SHARED_TABLE
22
23 SHARED_SERVER
24
25 create
26 make
27
28 feature {NONE} -- Initialization
29
30 make (f: FEATURE_I; t: like type; p_type: like precursor_type) is
31 -- Initialization
32 require
33 good_argument: f /= Void
34 local
35 feat: FEATURE_I
36 feat_tbl: FEATURE_TABLE
37 do
38 feature_name_id := f.feature_name_id
39 body_index := f.body_index
40 routine_id := f.rout_id_set.first
41 is_once := f.is_once
42 is_process_relative := f.is_process_relative
43 precursor_type := p_type
44 type := t
45 if System.il_generation then
46 if precursor_type = Void then
47 -- Normal feature call.
48 if f.origin_class_id /= 0 then
49 feature_id := f.origin_feature_id
50 written_in := f.origin_class_id
51 else
52 -- Case of a non-external Eiffel routine
53 -- written in an external class.
54 feature_id := f.feature_id
55 written_in := f.written_in
56 end
57 else
58 -- Precursor access, we need to find where body
59 -- is defined. It is slow since we have to do a lookup
60 -- in the parent feature table but we do not have
61 -- much choice at the moment. The good thing is that
62 -- since it is done at degree 3, we are most likely
63 -- to hit the feature table cache.
64 written_in := f.written_in
65 feat_tbl := System.class_of_id (written_in).feature_table
66 feat := feat_tbl.feature_of_rout_id_set (f.rout_id_set)
67 feature_id := feat.feature_id
68 end
69 else
70 feature_id := f.feature_id
71 written_in := f.written_in
72 end
73 end
74
75 feature -- Visitor
76
77 process (v: BYTE_NODE_VISITOR) is
78 -- Process current element.
79 local
80 c: CL_TYPE_I
81 f: FEATURE_I
82 do
83 if not context.is_written_context then
84 -- Ensure the feature is not redeclared into attribute.
85 c ?= context_type
86 f := c.base_class.feature_of_rout_id (routine_id)
87 if not f.is_attribute then
88 f := Void
89 end
90 end
91 if f = Void then
92 -- Process feature as an internal routine.
93 v.process_feature_b (Current)
94 else
95 -- Create new byte node and process it instead of the current one.
96 byte_node (f).process (v)
97 end
98 end
99
100 feature -- Access
101
102 type: TYPE_I
103 -- Type of the call
104
105 body_index: INTEGER
106 -- Body Index of the feature
107
108 is_once: BOOLEAN
109 -- Is the current feature a once feature?
110 --| Used when inlining is turned on in final mode, because we are not
111 --| allowed to inline once routines
112
113 is_process_relative: BOOLEAN
114 -- Is current feature process-relative?
115
116 parameters: BYTE_LIST [PARAMETER_B]
117 -- Feature parameters: can be Void
118
119 set_parameters (p: like parameters) is
120 -- Assign `p' to `parameters'.
121 do
122 parameters := p
123 if p /= Void then
124 p.do_all (agent {PARAMETER_B}.set_parent (Current))
125 end
126 end
127
128 set_type (t: TYPE_I) is
129 -- Assign `t' to `type'.
130 do
131 type := t
132 end
133
134 special_routines: SPECIAL_FEATURES is
135 -- Array containing special routines.
136 once
137 create Result
138 end
139
140 is_any_feature: BOOLEAN is
141 -- Is Current an instance of ANY_FEATURE_B?
142 do
143 end
144
145 is_feature_special (compilation_type: BOOLEAN; target_type: BASIC_I): BOOLEAN is
146 -- Search for feature_name in special_routines.
147 -- This is used for simple types only.
148 -- If found return True (and keep reference position).
149 -- Otherwize, return false
150 do
151 Result := special_routines.has (feature_name_id, compilation_type, target_type)
152 end
153
154 is_feature: BOOLEAN is True
155 -- Is Current an access to an Eiffel feature ?
156
157 same (other: ACCESS_B): BOOLEAN is
158 -- Is `other' the same access as Current ?
159 local
160 feature_b: FEATURE_B
161 do
162 feature_b ?= other
163 if feature_b /= Void then
164 Result := feature_id = feature_b.feature_id
165 end
166 end
167
168 enlarged: CALL_ACCESS_B is
169 -- Enlarge the tree to get more attributes and return the
170 -- new enlarged tree node.
171 do
172 Result := enlarged_on (context_type)
173 end
174
175 enlarged_on (type_i: TYPE_I): CALL_ACCESS_B is
176 -- Enlarged byte node evaluated in the context of `type_i'.
177 local
178 feature_bl: FEATURE_BL
179 c: CL_TYPE_I
180 f: FEATURE_I
181 do
182 if not context.is_written_context then
183 -- Ensure the feature is not redeclared into attribute.
184 c ?= real_type (type_i)
185 if c /= Void then
186 f := c.base_class.feature_of_rout_id (routine_id)
187 if not f.is_attribute then
188 f := Void
189 end
190 end
191 end
192 if f = Void then
193 -- Process feature as an internal routine.
194 if context.final_mode then
195 create feature_bl.make
196 else
197 create {FEATURE_BW} feature_bl.make
198 end
199 feature_bl.fill_from (Current)
200 Result := feature_bl
201 else
202 -- Create new byte node and process it instead of the current one.
203 Result ?= byte_node (f).enlarged
204 end
205 end
206
207 feature -- Context type
208
209 context_type: TYPE_I is
210 -- Context type of the access (properly instantiated)
211 do
212 if precursor_type = Void then
213 Result := Precursor {CALL_ACCESS_B}
214 else
215 Result := Context.real_type (precursor_type)
216 end
217 end
218
219 feature -- Byte code generation
220
221 make_special_byte_code (ba: BYTE_ARRAY; basic_type: BASIC_I) is
222 -- Make byte code for special calls.
223 do
224 special_routines.make_byte_code (ba, basic_type)
225 end
226
227 feature -- Array optimization
228
229 is_special_feature: BOOLEAN is
230 local
231 cl_type: CL_TYPE_I
232 base_class: CLASS_C
233 f: FEATURE_I
234 dep: DEPEND_UNIT
235 do
236 cl_type ?= context_type -- Cannot fail
237 base_class := cl_type.base_class
238 f := base_class.feature_table.item_id (feature_name_id)
239 create dep.make (base_class.class_id, f)
240 Result := optimizer.special_features.has (dep)
241 end
242
243 is_unsafe: BOOLEAN is
244 local
245 cl_type: CL_TYPE_I
246 base_class: CLASS_C
247 f: FEATURE_I
248 dep: DEPEND_UNIT
249 do
250 cl_type ?= context_type -- Cannot fail
251 base_class := cl_type.base_class
252 f := base_class.feature_table.item_id (feature_name_id)
253 debug ("OPTIMIZATION")
254 io.error.put_string ("%N%N%NTESTING is_unsafe for ")
255 io.error.put_string (feature_name)
256 io.error.put_string (" from ")
257 io.error.put_string (base_class.name)
258 io.error.put_string (" is NOT safe%N")
259 end
260 optimizer.test_safety (f, base_class)
261 create dep.make (base_class.class_id, f)
262 Result := (not optimizer.is_safe (dep))
263 or else (parameters /= Void and then parameters.is_unsafe)
264 debug ("OPTIMIZATION")
265 if Result then
266 io.error.put_string (f.feature_name)
267 io.error.put_string (" from ")
268 io.error.put_string (base_class.name)
269 io.error.put_string (" is NOT safe%N")
270 end
271 end
272 end
273
274 optimized_byte_node: like Current is
275 do
276 Result := Current
277 if parameters /= Void then
278 parameters := parameters.optimized_byte_node
279 end
280 end
281
282 calls_special_features (array_desc: INTEGER): BOOLEAN is
283 do
284 if parameters /= Void then
285 Result := parameters.calls_special_features (array_desc)
286 end
287 end
288
289 feature {NONE} -- Array optimization
290
291 optimizer: ARRAY_OPTIMIZER is
292 do
293 Result := System.remover.array_optimizer
294 end
295
296 feature -- Inlining
297
298 size: INTEGER is
299 do
300 if parameters /= Void then
301 Result := 1 + parameters.size
302 else
303 Result := 1
304 end
305 end
306
307 pre_inlined_code: CALL_B is
308 local
309 inlined_current_b: INLINED_CURRENT_B
310 do
311 if parent /= Void then
312 Result := Current
313 else
314 create parent
315 create inlined_current_b
316 parent.set_target (inlined_current_b)
317 inlined_current_b.set_parent (parent)
318
319 parent.set_message (Current)
320
321 Result := parent
322 end
323 type := real_type (type)
324 if precursor_type /= Void then
325 precursor_type ?= real_type (precursor_type)
326 end
327 if parameters /= Void then
328 set_parameters (parameters.pre_inlined_code)
329 end
330 end
331
332 inlined_byte_code: ACCESS_B is
333 local
334 inlined_feat_b: INLINED_FEAT_B
335 inline: BOOLEAN
336 inliner: INLINER
337 type_i: TYPE_I
338 cl_type: CL_TYPE_I
339 bc: STD_BYTE_CODE
340 l_rout_table: ROUT_TABLE
341 l_body_index: INTEGER
342 entry: ROUT_ENTRY
343 f: FEATURE_I
344 context_class_type: CLASS_TYPE
345 written_class_type: CLASS_TYPE
346 do
347 if not is_once then
348 type_i := context_type
349 if not type_i.is_basic then
350 cl_type ?= type_i -- Cannot fail
351 -- Inline only if it is not polymorphic and if it can be inlined.
352 if Eiffel_table.is_polymorphic (routine_id, cl_type.type_id, True) = -1 then
353 l_rout_table ?= eiffel_table.poly_table (routine_id)
354 l_rout_table.goto_implemented (cl_type.type_id)
355 -- Only if it is implemented that we can inline it.
356 if l_rout_table.is_implemented then
357 inliner := System.remover.inliner
358 entry := l_rout_table.item
359 l_body_index := entry.body_index
360 inline := inliner.inline (type, l_body_index)
361 end
362 end
363 end
364 end
365
366 if inline then
367 -- Ensure the feature is not redeclared into attribute or external routine
368 f := system.class_of_id (entry.class_id).feature_of_feature_id (entry.feature_id)
369 if f.is_attribute or else f.is_external then
370 -- Create new byte node and process it instead of the current one
371 Result := byte_node (f).inlined_byte_code
372 else
373 -- Creation of a special node for the entire
374 -- feature (descendant of STD_BYTE_CODE)
375 inliner.set_current_feature_inlined
376 context_class_type := system.class_type_of_id (entry.type_id)
377 written_class_type := context_class_type.type.implemented_type (f.written_in).associated_class_type
378 context_class_type := written_class_type
379 -- Create inlined byte node.
380 if cl_type.base_class.is_special then
381 create {SPECIAL_INLINED_FEAT_B} inlined_feat_b
382 else
383 create inlined_feat_b
384 end
385 inlined_feat_b.fill_from (Current)
386
387 -- Change context type before evaluating inlined feature byte code.
388 Context.change_class_type_context (context_class_type, written_class_type)
389 inlined_feat_b.set_context_type (context_class_type, written_class_type)
390
391 bc ?= Byte_server.disk_item (l_body_index)
392 bc := bc.pre_inlined_code
393 Context.restore_class_type_context
394
395 inlined_feat_b.set_inlined_byte_code (bc)
396 Result := inlined_feat_b
397 end
398 else
399 Result := Current
400 if parameters /= Void then
401 parameters := parameters.inlined_byte_code
402 end
403 end
404 end
405
406 current_class_type: CLASS_TYPE is
407 -- Current type for the call (NOT the static type but the
408 -- type corresponding to the written in class)
409 local
410 written_class : CLASS_C
411 tuple_class : TUPLE_CLASS_B
412 original_feature: FEATURE_I
413 m : META_GENERIC
414 true_gen : ARRAY [TYPE_I]
415 real_target_type: TYPE_A
416 actual_type : TYPE_A
417 formal_a : FORMAL_A
418 nb_generics, i : INTEGER
419 l_formal_dec: FORMAL_CONSTRAINT_AS
420 do
421 original_feature := context_type.type_a.associated_class.
422 feature_table.origin_table.item (routine_id)
423 written_class := original_feature.written_class
424
425 if written_class.generics = Void then
426 Result := written_class.types.first
427 else
428 tuple_class ?= written_class
429 if tuple_class /= Void then
430 Result := tuple_class.types.first
431 else
432 real_target_type := context_type.type_a
433 -- LINKED_LIST [STRING] is recorded as LINKED_LIST [REFERENCE_I]
434 -- => LINKED_LIST [ANY] after previous call
435
436 from
437 i := 1
438 nb_generics := written_class.generics.count
439 create m.make (nb_generics)
440 create true_gen.make (1, nb_generics)
441 until
442 i > nb_generics
443 loop
444 l_formal_dec ?= written_class.generics.i_th (1)
445 check l_formal_dec_not_void: l_formal_dec /= Void end
446 create formal_a.make (l_formal_dec.is_reference, l_formal_dec.is_expanded, l_formal_dec.is_monomorph, i)
447 actual_type := formal_a.instantiation_in (real_target_type, written_class.class_id)
448
449 if actual_type.is_expanded then
450 m.put (actual_type.type_i, i)
451 else
452 m.put (reference_c_type, i)
453 end
454 true_gen.put (actual_type.type_i, i)
455 i := i + 1
456 end
457
458 Result := (create {GEN_TYPE_I}.make (written_class.class_id, m, true_gen)).associated_class_type
459 end
460 end
461 end
462
463 indexing
464 copyright: "Copyright (c) 1984-2007, Eiffel Software"
465 license: "GPL version 2 (see http://www.eiffel.com/licensing/gpl.txt)"
466 licensing_options: "http://www.eiffel.com/licensing"
467 copying: "[
468 This file is part of Eiffel Software's Eiffel Development Environment.
469
470 Eiffel Software's Eiffel Development Environment is free
471 software; you can redistribute it and/or modify it under
472 the terms of the GNU General Public License as published
473 by the Free Software Foundation, version 2 of the License
474 (available at the URL listed under "license" above).
475
476 Eiffel Software's Eiffel Development Environment is
477 distributed in the hope that it will be useful, but
478 WITHOUT ANY WARRANTY; without even the implied warranty
479 of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
480 See the GNU General Public License for more details.
481
482 You should have received a copy of the GNU General Public
483 License along with Eiffel Software's Eiffel Development
484 Environment; if not, write to the Free Software Foundation,
485 Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
486 ]"
487 source: "[
488 Eiffel Software
489 356 Storke Road, Goleta, CA 93117 USA
490 Telephone 805-685-1006, Fax 805-685-6869
491 Website http://www.eiffel.com
492 Customer support http://support.eiffel.com
493 ]"
494
495 end

Properties

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

  ViewVC Help
Powered by ViewVC 1.1.23