ggc-common.c (ggc_mark_rtx_children_1): Rename from...
[gcc.git] / gcc / ggc-common.c
1 /* Simple garbage collection for the GNU compiler.
2 Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
3
4 This file is part of GCC.
5
6 GCC is free software; you can redistribute it and/or modify it under
7 the terms of the GNU General Public License as published by the Free
8 Software Foundation; either version 2, or (at your option) any later
9 version.
10
11 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING. If not, write to the Free
18 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
19 02111-1307, USA. */
20
21 /* Generic garbage collection (GC) functions and data, not specific to
22 any particular GC implementation. */
23
24 #include "config.h"
25 #include "system.h"
26 #include "rtl.h"
27 #include "tree.h"
28 #include "tm_p.h"
29 #include "hash.h"
30 #include "hashtab.h"
31 #include "varray.h"
32 #include "ggc.h"
33 #include "langhooks.h"
34
35 /* Statistics about the allocation. */
36 static ggc_statistics *ggc_stats;
37
38 /* Trees that have been marked, but whose children still need marking. */
39 varray_type ggc_pending_trees;
40
41 static void ggc_mark_rtx_children_1 PARAMS ((rtx));
42 static void ggc_mark_rtx_ptr PARAMS ((void *));
43 static void ggc_mark_tree_ptr PARAMS ((void *));
44 static void ggc_mark_rtx_varray_ptr PARAMS ((void *));
45 static void ggc_mark_tree_varray_ptr PARAMS ((void *));
46 static void ggc_mark_tree_hash_table_ptr PARAMS ((void *));
47 static int ggc_htab_delete PARAMS ((void **, void *));
48 static void ggc_mark_trees PARAMS ((void));
49 static bool ggc_mark_tree_hash_table_entry PARAMS ((struct hash_entry *,
50 hash_table_key));
51
52 /* Maintain global roots that are preserved during GC. */
53
54 /* Global roots that are preserved during calls to gc. */
55
56 struct ggc_root
57 {
58 struct ggc_root *next;
59 void *base;
60 int nelt;
61 int size;
62 void (*cb) PARAMS ((void *));
63 };
64
65 static struct ggc_root *roots;
66
67 /* Add BASE as a new garbage collection root. It is an array of
68 length NELT with each element SIZE bytes long. CB is a
69 function that will be called with a pointer to each element
70 of the array; it is the intention that CB call the appropriate
71 routine to mark gc-able memory for that element. */
72
73 void
74 ggc_add_root (base, nelt, size, cb)
75 void *base;
76 int nelt, size;
77 void (*cb) PARAMS ((void *));
78 {
79 struct ggc_root *x = (struct ggc_root *) xmalloc (sizeof (*x));
80
81 x->next = roots;
82 x->base = base;
83 x->nelt = nelt;
84 x->size = size;
85 x->cb = cb;
86
87 roots = x;
88 }
89
90 /* Register an array of rtx as a GC root. */
91
92 void
93 ggc_add_rtx_root (base, nelt)
94 rtx *base;
95 int nelt;
96 {
97 ggc_add_root (base, nelt, sizeof (rtx), ggc_mark_rtx_ptr);
98 }
99
100 /* Register an array of trees as a GC root. */
101
102 void
103 ggc_add_tree_root (base, nelt)
104 tree *base;
105 int nelt;
106 {
107 ggc_add_root (base, nelt, sizeof (tree), ggc_mark_tree_ptr);
108 }
109
110 /* Register a varray of rtxs as a GC root. */
111
112 void
113 ggc_add_rtx_varray_root (base, nelt)
114 varray_type *base;
115 int nelt;
116 {
117 ggc_add_root (base, nelt, sizeof (varray_type),
118 ggc_mark_rtx_varray_ptr);
119 }
120
121 /* Register a varray of trees as a GC root. */
122
123 void
124 ggc_add_tree_varray_root (base, nelt)
125 varray_type *base;
126 int nelt;
127 {
128 ggc_add_root (base, nelt, sizeof (varray_type),
129 ggc_mark_tree_varray_ptr);
130 }
131
132 /* Register a hash table of trees as a GC root. */
133
134 void
135 ggc_add_tree_hash_table_root (base, nelt)
136 struct hash_table **base;
137 int nelt;
138 {
139 ggc_add_root (base, nelt, sizeof (struct hash_table *),
140 ggc_mark_tree_hash_table_ptr);
141 }
142
143 /* Remove the previously registered GC root at BASE. */
144
145 void
146 ggc_del_root (base)
147 void *base;
148 {
149 struct ggc_root *x, **p;
150
151 p = &roots, x = roots;
152 while (x)
153 {
154 if (x->base == base)
155 {
156 *p = x->next;
157 free (x);
158 return;
159 }
160 p = &x->next;
161 x = x->next;
162 }
163
164 abort ();
165 }
166
167 /* Add a hash table to be scanned when all roots have been processed. We
168 delete any entry in the table that has not been marked. */
169
170 struct d_htab_root
171 {
172 struct d_htab_root *next;
173 htab_t htab;
174 ggc_htab_marked_p marked_p;
175 ggc_htab_mark mark;
176 };
177
178 static struct d_htab_root *d_htab_roots;
179
180 /* Add X, an htab, to a list of htabs that contain objects which are allocated
181 from GC memory. Once all other roots are marked, we check each object in
182 the htab to see if it has already been marked. If not, it is deleted.
183
184 MARKED_P, if specified, is a function that returns 1 if the entry is to
185 be considered as "marked". If not present, the data structure pointed to
186 by the htab slot is tested. This function should be supplied if some
187 other object (such as something pointed to by that object) should be tested
188 in which case the function tests whether that object (or objects) are
189 marked (using ggc_marked_p) and returns nonzero if it is.
190
191 MARK, if specified, is a function that is passed the contents of a slot
192 that has been determined to have been "marked" (via the above function)
193 and marks any other objects pointed to by that object. For example,
194 we might have a hash table of memory attribute blocks, which are pointed
195 to by a MEM RTL but have a pointer to a DECL. MARKED_P in that case will
196 not be specified because we want to know if the attribute block is pointed
197 to by the MEM, but MARK must be specified because if the block has been
198 marked, we need to mark the DECL. */
199
200 void
201 ggc_add_deletable_htab (x, marked_p, mark)
202 PTR x;
203 ggc_htab_marked_p marked_p;
204 ggc_htab_mark mark;
205 {
206 struct d_htab_root *r
207 = (struct d_htab_root *) xmalloc (sizeof (struct d_htab_root));
208
209 r->next = d_htab_roots;
210 r->htab = (htab_t) x;
211 r->marked_p = marked_p ? marked_p : ggc_marked_p;
212 r->mark = mark;
213 d_htab_roots = r;
214 }
215
216 /* Process a slot of an htab by deleting it if it has not been marked. */
217
218 static int
219 ggc_htab_delete (slot, info)
220 void **slot;
221 void *info;
222 {
223 struct d_htab_root *r = (struct d_htab_root *) info;
224
225 if (! (*r->marked_p) (*slot))
226 htab_clear_slot (r->htab, slot);
227 else if (r->mark)
228 (*r->mark) (*slot);
229
230 return 1;
231 }
232
233 /* Iterate through all registered roots and mark each element. */
234
235 void
236 ggc_mark_roots ()
237 {
238 struct ggc_root *x;
239 struct d_htab_root *y;
240
241 VARRAY_TREE_INIT (ggc_pending_trees, 4096, "ggc_pending_trees");
242
243 for (x = roots; x != NULL; x = x->next)
244 {
245 char *elt = x->base;
246 int s = x->size, n = x->nelt;
247 void (*cb) PARAMS ((void *)) = x->cb;
248 int i;
249
250 for (i = 0; i < n; ++i, elt += s)
251 (*cb)(elt);
252 }
253
254 /* Mark all the queued up trees, and their children. */
255 ggc_mark_trees ();
256 VARRAY_FREE (ggc_pending_trees);
257
258 /* Now scan all hash tables that have objects which are to be deleted if
259 they are not already marked. Since these may mark more trees, we need
260 to reinitialize that varray. */
261 VARRAY_TREE_INIT (ggc_pending_trees, 1024, "ggc_pending_trees");
262
263 for (y = d_htab_roots; y != NULL; y = y->next)
264 htab_traverse (y->htab, ggc_htab_delete, (PTR) y);
265 ggc_mark_trees ();
266 VARRAY_FREE (ggc_pending_trees);
267 }
268
269 /* R had not been previously marked, but has now been marked via
270 ggc_set_mark. Now recurse and process the children. */
271
272 void
273 ggc_mark_rtx_children (r)
274 rtx r;
275 {
276 rtx i, last;
277
278 /* Special case the instruction chain. This is a data structure whose
279 chain length is potentially unbounded, and which contain references
280 within the chain (e.g. label_ref and insn_list). If do nothing here,
281 we risk blowing the stack recursing through a long chain of insns.
282
283 Combat this by marking all of the instructions in the chain before
284 marking the contents of those instructions. */
285
286 switch (GET_CODE (r))
287 {
288 case INSN:
289 case JUMP_INSN:
290 case CALL_INSN:
291 case NOTE:
292 case CODE_LABEL:
293 case BARRIER:
294 for (i = NEXT_INSN (r); ; i = NEXT_INSN (i))
295 if (! ggc_test_and_set_mark (i))
296 break;
297 last = i;
298
299 for (i = NEXT_INSN (r); i != last; i = NEXT_INSN (i))
300 ggc_mark_rtx_children_1 (i);
301
302 default:
303 break;
304 }
305
306 ggc_mark_rtx_children_1 (r);
307 }
308
309 static void
310 ggc_mark_rtx_children_1 (r)
311 rtx r;
312 {
313 const char *fmt;
314 int i;
315 rtx next_rtx;
316
317 do
318 {
319 enum rtx_code code = GET_CODE (r);
320 /* This gets set to a child rtx to eliminate tail recursion. */
321 next_rtx = NULL;
322
323 /* Collect statistics, if appropriate. */
324 if (ggc_stats)
325 {
326 ++ggc_stats->num_rtxs[(int) code];
327 ggc_stats->size_rtxs[(int) code] += ggc_get_size (r);
328 }
329
330 /* ??? If (some of) these are really pass-dependent info, do we
331 have any right poking our noses in? */
332 switch (code)
333 {
334 case MEM:
335 ggc_mark (MEM_ATTRS (r));
336 break;
337 case JUMP_INSN:
338 ggc_mark_rtx (JUMP_LABEL (r));
339 break;
340 case CODE_LABEL:
341 ggc_mark_rtx (LABEL_REFS (r));
342 break;
343 case LABEL_REF:
344 ggc_mark_rtx (LABEL_NEXTREF (r));
345 ggc_mark_rtx (CONTAINING_INSN (r));
346 break;
347 case ADDRESSOF:
348 ggc_mark_tree (ADDRESSOF_DECL (r));
349 break;
350 case CONST_DOUBLE:
351 ggc_mark_rtx (CONST_DOUBLE_CHAIN (r));
352 break;
353 case NOTE:
354 switch (NOTE_LINE_NUMBER (r))
355 {
356 case NOTE_INSN_RANGE_BEG:
357 case NOTE_INSN_RANGE_END:
358 case NOTE_INSN_LIVE:
359 case NOTE_INSN_EXPECTED_VALUE:
360 ggc_mark_rtx (NOTE_RANGE_INFO (r));
361 break;
362
363 case NOTE_INSN_BLOCK_BEG:
364 case NOTE_INSN_BLOCK_END:
365 ggc_mark_tree (NOTE_BLOCK (r));
366 break;
367
368 default:
369 break;
370 }
371 break;
372
373 default:
374 break;
375 }
376
377 for (fmt = GET_RTX_FORMAT (GET_CODE (r)), i = 0; *fmt ; ++fmt, ++i)
378 {
379 rtx exp;
380 switch (*fmt)
381 {
382 case 'e': case 'u':
383 exp = XEXP (r, i);
384 if (ggc_test_and_set_mark (exp))
385 {
386 if (next_rtx == NULL)
387 next_rtx = exp;
388 else
389 ggc_mark_rtx_children (exp);
390 }
391 break;
392 case 'V': case 'E':
393 ggc_mark_rtvec (XVEC (r, i));
394 break;
395 }
396 }
397 }
398 while ((r = next_rtx) != NULL);
399 }
400
401 /* V had not been previously marked, but has now been marked via
402 ggc_set_mark. Now recurse and process the children. */
403
404 void
405 ggc_mark_rtvec_children (v)
406 rtvec v;
407 {
408 int i;
409
410 i = GET_NUM_ELEM (v);
411 while (--i >= 0)
412 ggc_mark_rtx (RTVEC_ELT (v, i));
413 }
414
415 /* Recursively set marks on all of the children of the
416 GCC_PENDING_TREES. */
417
418 static void
419 ggc_mark_trees ()
420 {
421 while (ggc_pending_trees->elements_used)
422 {
423 tree t;
424 enum tree_code code;
425
426 t = VARRAY_TOP_TREE (ggc_pending_trees);
427 VARRAY_POP (ggc_pending_trees);
428 code = TREE_CODE (t);
429
430 /* Collect statistics, if appropriate. */
431 if (ggc_stats)
432 {
433 ++ggc_stats->num_trees[(int) code];
434 ggc_stats->size_trees[(int) code] += ggc_get_size (t);
435 }
436
437 /* Bits from common. */
438 ggc_mark_tree (TREE_TYPE (t));
439 ggc_mark_tree (TREE_CHAIN (t));
440
441 /* Some nodes require special handling. */
442 switch (code)
443 {
444 case TREE_LIST:
445 ggc_mark_tree (TREE_PURPOSE (t));
446 ggc_mark_tree (TREE_VALUE (t));
447 continue;
448
449 case TREE_VEC:
450 {
451 int i = TREE_VEC_LENGTH (t);
452
453 while (--i >= 0)
454 ggc_mark_tree (TREE_VEC_ELT (t, i));
455 continue;
456 }
457
458 case COMPLEX_CST:
459 ggc_mark_tree (TREE_REALPART (t));
460 ggc_mark_tree (TREE_IMAGPART (t));
461 break;
462
463 case PARM_DECL:
464 ggc_mark_rtx (DECL_INCOMING_RTL (t));
465 break;
466
467 case FIELD_DECL:
468 ggc_mark_tree (DECL_FIELD_BIT_OFFSET (t));
469 break;
470
471 case IDENTIFIER_NODE:
472 (*lang_hooks.mark_tree) (t);
473 continue;
474
475 default:
476 break;
477 }
478
479 /* But in general we can handle them by class. */
480 switch (TREE_CODE_CLASS (code))
481 {
482 case 'd': /* A decl node. */
483 ggc_mark_tree (DECL_SIZE (t));
484 ggc_mark_tree (DECL_SIZE_UNIT (t));
485 ggc_mark_tree (DECL_NAME (t));
486 ggc_mark_tree (DECL_CONTEXT (t));
487 ggc_mark_tree (DECL_ARGUMENTS (t));
488 ggc_mark_tree (DECL_RESULT_FLD (t));
489 ggc_mark_tree (DECL_INITIAL (t));
490 ggc_mark_tree (DECL_ABSTRACT_ORIGIN (t));
491 ggc_mark_tree (DECL_SECTION_NAME (t));
492 ggc_mark_tree (DECL_ATTRIBUTES (t));
493 if (DECL_RTL_SET_P (t))
494 ggc_mark_rtx (DECL_RTL (t));
495 ggc_mark_rtx (DECL_LIVE_RANGE_RTL (t));
496 ggc_mark_tree (DECL_VINDEX (t));
497 if (DECL_ASSEMBLER_NAME_SET_P (t))
498 ggc_mark_tree (DECL_ASSEMBLER_NAME (t));
499 if (TREE_CODE (t) == FUNCTION_DECL)
500 {
501 ggc_mark_tree (DECL_SAVED_TREE (t));
502 ggc_mark_tree (DECL_INLINED_FNS (t));
503 if (DECL_SAVED_INSNS (t))
504 ggc_mark_struct_function (DECL_SAVED_INSNS (t));
505 }
506 (*lang_hooks.mark_tree) (t);
507 break;
508
509 case 't': /* A type node. */
510 ggc_mark_tree (TYPE_SIZE (t));
511 ggc_mark_tree (TYPE_SIZE_UNIT (t));
512 ggc_mark_tree (TYPE_ATTRIBUTES (t));
513 ggc_mark_tree (TYPE_VALUES (t));
514 ggc_mark_tree (TYPE_POINTER_TO (t));
515 ggc_mark_tree (TYPE_REFERENCE_TO (t));
516 ggc_mark_tree (TYPE_NAME (t));
517 ggc_mark_tree (TYPE_MIN_VALUE (t));
518 ggc_mark_tree (TYPE_MAX_VALUE (t));
519 ggc_mark_tree (TYPE_NEXT_VARIANT (t));
520 ggc_mark_tree (TYPE_MAIN_VARIANT (t));
521 ggc_mark_tree (TYPE_BINFO (t));
522 ggc_mark_tree (TYPE_CONTEXT (t));
523 (*lang_hooks.mark_tree) (t);
524 break;
525
526 case 'b': /* A lexical block. */
527 ggc_mark_tree (BLOCK_VARS (t));
528 ggc_mark_tree (BLOCK_SUBBLOCKS (t));
529 ggc_mark_tree (BLOCK_SUPERCONTEXT (t));
530 ggc_mark_tree (BLOCK_ABSTRACT_ORIGIN (t));
531 break;
532
533 case 'c': /* A constant. */
534 ggc_mark_rtx (TREE_CST_RTL (t));
535 break;
536
537 case 'r': case '<': case '1':
538 case '2': case 'e': case 's': /* Expressions. */
539 {
540 int i = TREE_CODE_LENGTH (TREE_CODE (t));
541 int first_rtl = first_rtl_op (TREE_CODE (t));
542
543 while (--i >= 0)
544 {
545 if (i >= first_rtl)
546 ggc_mark_rtx ((rtx) TREE_OPERAND (t, i));
547 else
548 ggc_mark_tree (TREE_OPERAND (t, i));
549 }
550 break;
551 }
552
553 case 'x':
554 (*lang_hooks.mark_tree) (t);
555 break;
556 }
557 }
558 }
559
560 /* Mark all the elements of the varray V, which contains rtxs. */
561
562 void
563 ggc_mark_rtx_varray (v)
564 varray_type v;
565 {
566 int i;
567
568 if (v)
569 for (i = v->num_elements - 1; i >= 0; --i)
570 ggc_mark_rtx (VARRAY_RTX (v, i));
571 }
572
573 /* Mark all the elements of the varray V, which contains trees. */
574
575 void
576 ggc_mark_tree_varray (v)
577 varray_type v;
578 {
579 int i;
580
581 if (v)
582 for (i = v->num_elements - 1; i >= 0; --i)
583 ggc_mark_tree (VARRAY_TREE (v, i));
584 }
585
586 /* Mark the hash table-entry HE. Its key field is really a tree. */
587
588 static bool
589 ggc_mark_tree_hash_table_entry (he, k)
590 struct hash_entry *he;
591 hash_table_key k ATTRIBUTE_UNUSED;
592 {
593 ggc_mark_tree ((tree) he->key);
594 return true;
595 }
596
597 /* Mark all the elements of the hash-table H, which contains trees. */
598
599 void
600 ggc_mark_tree_hash_table (ht)
601 struct hash_table *ht;
602 {
603 hash_traverse (ht, ggc_mark_tree_hash_table_entry, /*info=*/0);
604 }
605
606 /* Type-correct function to pass to ggc_add_root. It just forwards
607 *ELT (which is an rtx) to ggc_mark_rtx. */
608
609 static void
610 ggc_mark_rtx_ptr (elt)
611 void *elt;
612 {
613 ggc_mark_rtx (*(rtx *) elt);
614 }
615
616 /* Type-correct function to pass to ggc_add_root. It just forwards
617 *ELT (which is a tree) to ggc_mark_tree. */
618
619 static void
620 ggc_mark_tree_ptr (elt)
621 void *elt;
622 {
623 ggc_mark_tree (*(tree *) elt);
624 }
625
626 /* Type-correct function to pass to ggc_add_root. It just forwards
627 ELT (which is really a varray_type *) to ggc_mark_rtx_varray. */
628
629 static void
630 ggc_mark_rtx_varray_ptr (elt)
631 void *elt;
632 {
633 ggc_mark_rtx_varray (*(varray_type *) elt);
634 }
635
636 /* Type-correct function to pass to ggc_add_root. It just forwards
637 ELT (which is really a varray_type *) to ggc_mark_tree_varray. */
638
639 static void
640 ggc_mark_tree_varray_ptr (elt)
641 void *elt;
642 {
643 ggc_mark_tree_varray (*(varray_type *) elt);
644 }
645
646 /* Type-correct function to pass to ggc_add_root. It just forwards
647 ELT (which is really a struct hash_table **) to
648 ggc_mark_tree_hash_table. */
649
650 static void
651 ggc_mark_tree_hash_table_ptr (elt)
652 void *elt;
653 {
654 ggc_mark_tree_hash_table (*(struct hash_table **) elt);
655 }
656
657 /* Allocate a block of memory, then clear it. */
658 void *
659 ggc_alloc_cleared (size)
660 size_t size;
661 {
662 void *buf = ggc_alloc (size);
663 memset (buf, 0, size);
664 return buf;
665 }
666
667 /* Print statistics that are independent of the collector in use. */
668 #define SCALE(x) ((unsigned long) ((x) < 1024*10 \
669 ? (x) \
670 : ((x) < 1024*1024*10 \
671 ? (x) / 1024 \
672 : (x) / (1024*1024))))
673 #define LABEL(x) ((x) < 1024*10 ? ' ' : ((x) < 1024*1024*10 ? 'k' : 'M'))
674
675 void
676 ggc_print_common_statistics (stream, stats)
677 FILE *stream;
678 ggc_statistics *stats;
679 {
680 int code;
681
682 /* Set the pointer so that during collection we will actually gather
683 the statistics. */
684 ggc_stats = stats;
685
686 /* Then do one collection to fill in the statistics. */
687 ggc_collect ();
688
689 /* Total the statistics. */
690 for (code = 0; code < MAX_TREE_CODES; ++code)
691 {
692 stats->total_num_trees += stats->num_trees[code];
693 stats->total_size_trees += stats->size_trees[code];
694 }
695 for (code = 0; code < NUM_RTX_CODE; ++code)
696 {
697 stats->total_num_rtxs += stats->num_rtxs[code];
698 stats->total_size_rtxs += stats->size_rtxs[code];
699 }
700
701 /* Print the statistics for trees. */
702 fprintf (stream, "\n%-17s%10s %16s %10s\n", "Tree",
703 "Number", "Bytes", "% Total");
704 for (code = 0; code < MAX_TREE_CODES; ++code)
705 if (ggc_stats->num_trees[code])
706 {
707 fprintf (stream, "%-17s%10u%16ld%c %10.3f\n",
708 tree_code_name[code],
709 ggc_stats->num_trees[code],
710 SCALE (ggc_stats->size_trees[code]),
711 LABEL (ggc_stats->size_trees[code]),
712 (100 * ((double) ggc_stats->size_trees[code])
713 / ggc_stats->total_size_trees));
714 }
715 fprintf (stream,
716 "%-17s%10u%16ld%c\n", "Total",
717 ggc_stats->total_num_trees,
718 SCALE (ggc_stats->total_size_trees),
719 LABEL (ggc_stats->total_size_trees));
720
721 /* Print the statistics for RTL. */
722 fprintf (stream, "\n%-17s%10s %16s %10s\n", "RTX",
723 "Number", "Bytes", "% Total");
724 for (code = 0; code < NUM_RTX_CODE; ++code)
725 if (ggc_stats->num_rtxs[code])
726 {
727 fprintf (stream, "%-17s%10u%16ld%c %10.3f\n",
728 rtx_name[code],
729 ggc_stats->num_rtxs[code],
730 SCALE (ggc_stats->size_rtxs[code]),
731 LABEL (ggc_stats->size_rtxs[code]),
732 (100 * ((double) ggc_stats->size_rtxs[code])
733 / ggc_stats->total_size_rtxs));
734 }
735 fprintf (stream,
736 "%-17s%10u%16ld%c\n", "Total",
737 ggc_stats->total_num_rtxs,
738 SCALE (ggc_stats->total_size_rtxs),
739 LABEL (ggc_stats->total_size_rtxs));
740
741 /* Don't gather statistics any more. */
742 ggc_stats = NULL;
743 }