File: op_clralsvars.c

package info (click to toggle)
fis-gtm 6.3-014-3
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 36,680 kB
  • sloc: ansic: 333,039; asm: 5,180; csh: 4,956; sh: 1,924; awk: 291; makefile: 66; sed: 13
file content (139 lines) | stat: -rw-r--r-- 5,221 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
/****************************************************************
 *								*
 *	Copyright 2009, 2014 Fidelity Information Services, Inc	*
 *								*
 *	This source code contains the intellectual property	*
 *	of its copyright holder(s), and is made available	*
 *	under a license.  If you do not know the terms of	*
 *	the license, please stop and do not read further.	*
 *								*
 ****************************************************************/

#include "mdef.h"

#include "gtm_string.h"
#include "gtm_stdio.h"

#include "gtmio.h"
#include <rtnhdr.h>
#include "stack_frame.h"
#include "op.h"
#include "hashtab_mname.h"
#include "lv_val.h"
#include "gdsroot.h"
#include "gtm_facility.h"
#include "fileinfo.h"
#include "gdsbt.h"
#include "gdsfhead.h"
#include "alias.h"

GBLREF symval		*curr_symval;
GBLREF stack_frame	*frame_pointer;
GBLREF unsigned char	*stackbase, *stacktop, *msp, *stackwarn;

/* Run the local var hash table looking for variables with the name "$ZWRTAC*" and performing
   "KILL *" processing on any that are found and remove them from the hash table.
*/
void op_clralsvars(lv_val *rslt)
{
	int			htcnt, delcnt, table_size_orig;
	boolean_t		done;
	hash_table_mname        *table;
	ht_ent_mname		*table_base, *table_top, **last_lsym_hte, **htep, *table_base_orig;
	ht_ent_mname    	*tabent, *tabent_top;
	stack_frame		*fp, *fpprev;
	lv_val			*lvp;
 	DEBUG_ONLY(boolean_t	first_sym;)

	delcnt = 0;
	/* Remove $ZWRTAC* vars from hash table. Hash table shrink may be triggered in the next hashtab call */
	for (tabent = curr_symval->h_symtab.base, tabent_top = curr_symval->h_symtab.top; tabent < tabent_top; tabent++)
	{
		if (HTENT_VALID_MNAME(tabent, lv_val, lvp))
		{	/* Check if this var is $ZWRTAC* */
			if ((STR_LIT_LEN(DOLLAR_ZWRTAC) <= tabent->key.var_name.len)
				&& (0 == MEMCMP_LIT(tabent->key.var_name.addr, DOLLAR_ZWRTAC)))
			{	/* Note use here of delete_hashtab_ent_mname() instead of delete_hashtab_mname() not
				 * only saves looking up the entry in the hashtab but avoids the chance of hashtable
				 * compaction which would be *really* bad since this call is not protected with the
				 * wrapper that add_hashtab_mname_symval() has to fix the l_symtab entries.
				 */
				DECR_BASE_REF_RQ(tabent, lvp, FALSE);		/* Our ref disappears like the symbol */
				delete_hashtab_ent_mname(&curr_symval->h_symtab, tabent);	/* Remove from symbol table */
				++delcnt;
			}
		}
	}
	if (delcnt)
	{	/* Vars have been removed from hash table. Now find/clear any l_symtab entries that pointed
		 * to these vars (basically looking for pointers to deleted entries). Note this loop is similar
		 * to stack frame loops in als_lsymtab_repair().
		 */
		last_lsym_hte = NULL;
		done = FALSE;
		fp = frame_pointer;
		table_base = curr_symval->h_symtab.base;
		table_top = table_base + curr_symval->h_symtab.size;
		assert(frame_pointer);
		do
		{
			if (fp->l_symtab != last_lsym_hte)
			{	/* Different l_symtab than last time (don't want to update twice) */
				last_lsym_hte = fp->l_symtab;
				if (fp->vartab_len)
				{	/* Only process non-zero length l_symtabs */
					DEBUG_ONLY(first_sym = TRUE);
					for (htep = fp->l_symtab, htcnt = fp->vartab_len; htcnt; --htcnt, ++htep)
					{
						tabent = *htep;
						if (NULL == tabent)
							continue;
						if (tabent < table_base || tabent >= table_top)
						{	/* Entry doesn't point to the current symbol table */
							assert(first_sym);
							done = TRUE;
							break;
						}
						if (HTENT_MARK_DELETED(tabent))
							*htep = NULL;		/* Clear l_symtab value for deleted hash entry */
						DEBUG_ONLY(first_sym = FALSE);
					}
				}
			}
			if (done)
				break;
			fpprev = fp;
			fp = fp->old_frame_pointer;
			if (SFF_CI & fpprev->flags)
			{	/* Callins needs to be able to crawl past apparent end of stack to earlier stack segments */
				/* We should be in the base frame now. See if an earlier frame exists */
				fp = *(stack_frame **)(fp + 1);	/* Backups up to "prev pointer" created by base_frame() */
				if (NULL == fp || fp >= (stack_frame *)stackbase || fp < (stack_frame *)stacktop)
					break;	/* Pointer not within the stack -- must be earliest occurence */
			}
		} while(fp);
		/* Now that $ZWRTAC* vars have been deleted, we should check if compaction is a suggested thing
		 * to get rid of the deleted vars which will improve the free slot search and reduce the slot scan
		 * on a gargabe collection (both types). If it is, compact in a safe way and do the necessary l_symtab
		 * fixup.
		 */
		if (COMPACT_NEEDED(&curr_symval->h_symtab))
		{	/* Step 1: Remember the current table */
			table = &curr_symval->h_symtab;
			table_base_orig = table->base;
			table_size_orig = table->size;
 			/* Step 2: compact the table */
			/* We'll do the base release once we do the reparations */
			DEFER_BASE_REL_HASHTAB(table, TRUE);
			compact_hashtab_mname(&curr_symval->h_symtab);
			/* Step 3: fix l_symtab and related entries */
			if (table_base_orig != curr_symval->h_symtab.base)
			{
				/* Only needed if expansion was successful */
				als_lsymtab_repair(table, table_base_orig, table_size_orig);
				FREE_BASE_HASHTAB(table, table_base_orig);
			}
			DEFER_BASE_REL_HASHTAB(table, FALSE);
		}
 	}
}