75 lines
2.5 KiB
C
75 lines
2.5 KiB
C
/****************************************************************
|
|
* *
|
|
* Copyright 2001, 2011 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 "cache.h"
|
|
#include "rtnhdr.h"
|
|
#include "zbreak.h"
|
|
#include "inst_flush.h"
|
|
#include "private_code_copy.h"
|
|
#include "gtm_text_alloc.h"
|
|
|
|
void zr_put_free(z_records *zrecs, zbrk_struct *z_ptr)
|
|
{
|
|
mstr rtn_str;
|
|
rhdtyp *routine;
|
|
boolean_t deleted;
|
|
|
|
assert(zrecs->beg <= zrecs->free);
|
|
assert(zrecs->free < zrecs->end);
|
|
assert(z_ptr >= zrecs->beg);
|
|
assert(z_ptr <= zrecs->free);
|
|
if (NULL != z_ptr->action)
|
|
{ /* An action exists, reduce our interest in it */
|
|
assert(z_ptr->action->zb_refcnt > 0);
|
|
z_ptr->action->zb_refcnt--;
|
|
if (0 == z_ptr->action->zb_refcnt)
|
|
z_ptr->action = NULL;
|
|
}
|
|
/* In the generated code, change the offset in TRANSFER TABLE */
|
|
#ifdef COMPLEX_INSTRUCTION_UPDATE
|
|
EXTRACT_AND_UPDATE_INST(z_ptr->mpc, z_ptr->m_opcode);
|
|
#else
|
|
*z_ptr->mpc = z_ptr->m_opcode;
|
|
#endif
|
|
inst_flush(z_ptr->mpc, SIZEOF(INST_TYPE));
|
|
#ifdef USHBIN_SUPPORTED
|
|
if (((z_ptr == zrecs->beg) || !MIDENT_EQ((z_ptr - 1)->rtn, z_ptr->rtn)) &&
|
|
(((z_ptr + 1) == zrecs->free) || !MIDENT_EQ((z_ptr + 1)->rtn, z_ptr->rtn)))
|
|
{ /* No more breakpoints in the routine we just removed a break from. Note that since zrecs is sorted based
|
|
* on mpc, all breakpoints in a given routine are bunched together. Hence, it is possible to determine
|
|
* if all breakpoints are deleted from a routine by checking the preceding and succeeding entries of the
|
|
* one we are removing.
|
|
*/
|
|
assert(0 != z_ptr->rtn->len);
|
|
rtn_str.len = z_ptr->rtn->len;
|
|
rtn_str.addr = z_ptr->rtn->addr;
|
|
routine = find_rtn_hdr(&rtn_str);
|
|
if (NULL != routine->shlib_handle) /* don't need the private copy any more, revert back to shared copy */
|
|
release_private_code_copy(routine);
|
|
}
|
|
#endif
|
|
zrecs->free--;
|
|
/* potentially overlapped memory, use memmove, not memcpy */
|
|
memmove((char *)z_ptr, (char *)(z_ptr + 1), (zrecs->free - z_ptr) * SIZEOF(zbrk_struct));
|
|
if (zrecs->free == zrecs->beg)
|
|
{ /* all breaks gone, free space allocated for breakpoints */
|
|
free(zrecs->beg);
|
|
zrecs->beg = NULL;
|
|
zrecs->free = NULL;
|
|
zrecs->end = NULL;
|
|
}
|
|
return;
|
|
}
|