void deleteThreadFromHash(Thread *thread) { #undef HASH #undef COMPARE #define HASH(ptr) (int)javaThreadId(ptr) #define COMPARE(ptr1, ptr2, hash1, hash2) ptr1 == ptr2 deleteHashEntry(thread_id_map, thread, TRUE); }
void freeMethodInlinedInfo(MethodBlock *mb) { Instruction *instruction = mb->code; CodeBlockHeader **blocks = mb->code; QuickPrepareInfo *info; int i; if(!enabled) return; /* Scan handlers within the method */ for(i = mb->code_size; i--; instruction++) { char *handler = (char*)instruction->handler; CodeBlockHeader *block; if(handler >= min_entry_point || handler <= max_entry_point) { /* Handler is within the program text and so does not need freeing. However, sequences which have not been rewritten yet will have associated preparation info. */ if(handler == handler_entry_points[0][OPC_INLINE_REWRITER]) gcPendingFree(instruction->operand.pntr); continue; } /* The handler is an inlined block */ block = ((CodeBlockHeader*)handler) - 1; if(block->u.ref_count <= 0) { /* Either a duplicate block, or a hashed block and this is the only reference to it. Duplicates must be freed as this would be a leak. Hashed blocks potentially will be re-used and so we could keep them around. However, we free them because it's better to free room for a potentially more useful sequence. */ /* Add onto list to be freed */ *blocks++ = block; if(block->u.ref_count == 0) deleteHashEntry(code_hash_table, block, FALSE); } else block->u.ref_count--; } if(blocks > (CodeBlockHeader**)mb->code) addToFreeList(mb->code, blocks - (CodeBlockHeader**)mb->code); for(info = mb->quick_prepare_info; info != NULL;) { QuickPrepareInfo *temp = info; info = info->next; gcPendingFree(temp); } }