/* Sun-$Revision: 23.9 $ */ /* Copyright 1992-9 Sun Microsystems, Inc. and Stanford University. See the LICENSE file for license information. */ # pragma interface oop PrintDebugSize_prim(oop rcvr); oop findNMethods_prim(oop rcvr, oop map, oop sel); oop printNMethodCode_prim(oop rcvr); # if defined(FAST_COMPILER) || defined(SIC_COMPILER) // The zone is the area of memory holding compiled methods (nmethods). class ScopeDesc; class PcDesc; class addrDesc; extern int32 FrameChainNesting; enum nm_compiler {nm_nic, nm_sic, nm_last}; class zone: public CHeapObj { protected: int32* bottom; nmethod* LRUhand; // for LRU algorithm; sweeps through iZone bool needsICompaction;// need compaction of iZone bool needsSCompaction;// need compaction of dZone bool needsDCompaction;// need compaction of sZone bool _needsSweep; // need LRU sweep int32 compactDuration;// duration of last compaction timer zoneTimer; // timer for computation of above float minFreeFrac; // fraction of free space needed at compaction time IDManager* idManager; public: // for monitor Heap* iZone; // struct nmethod + insts + locs Heap* dZone; // deps Heap* sZone; // scopes + pcs Stubs* stubs; // PICs Trapdoors* trapdoors; // long calls to far-away stubs public: codeTable* table; // hash table MethodLookupKey --> nmethod codeTable* debugTable;// same for nmethods with debugging code nmln rememberLink; // list of nmethods with pointers to newspace nmln replCandidates; // list of replacement candidates nmln zombies; // list of zombie methods zone(int32& codeSize, int32& stubSize, int32& depsSize, int32& debugSize); void* operator new(size_t size) { return AllocateHeap(size, "nmethod zone header"); } void clear(); int32 capacity() { return iZone->capacity() + dZone->capacity() + sZone->capacity() + stubs->zone()->capacity(); } int32 used(); int32 numberOfNMethods() { return idManager->usedIDs; } int used_per_compiler[nm_last]; nmethod* alloc(int32 iLen, int32 sLen, int32 lLen, int32 dLen, char*& insts, nmethodScopes*& scopes, addrDesc*& locs, nmln*& deps); void free_nmethod(nmethod* m); void addToCodeTable(nmethod* nm, MethodLookupKey *k); nmethod* lookup(MethodLookupKey &k, bool needDebug = false); void compact(bool forced = false); void compactAll() { needsICompaction = needsSCompaction = needsDCompaction = true; compact(true); } bool needsCompaction() { return needsICompaction || needsSCompaction || needsDCompaction; } bool needsWork() { return needsCompaction() || _needsSweep; } bool needsSweep() { return _needsSweep; } void doWork(); void doSweep(); void flush(); void flushZombies(); void markAllUnused(); void flushUnused(); void flush_inline_cache(); int32 findReplCandidates(int32 needed); void nonCombiningMode() { iZone->combineMode = dZone->combineMode = sZone->combineMode = false; } // frame chaining: see FrameChainer below void chainFrames() { if (FrameChainNesting++ == 0) doChainFrames(); } void unchainFrames() { if (--FrameChainNesting == 0) doUnchainFrames(); } // zone creation (for PPC) must put stubs right after iZone pc_t code_start() { return Memory->code-> iZone->startAddr(); } pc_t code_end() { return Memory->code->stubs->zone()->endAddr(); } bool isSelfPC(void* p) { return code_start() <= p && p < code_end(); } bool contains(void *p) { return iZone->contains(p) || dZone->contains(p) || sZone->contains(p); } nmethod* findNMethod(void* start); nmethod* findNMethod_maybe(void* start); // slow! void findNMethodOrMap(nmln *n, nmethod* &nm, slotsMapDeps* &s); void nmethods_do(nmethodDoFn f); void oops_do(oopsDoFn f); void scavenge_contents(); void gc_mark_contents(); void gc_unmark_contents(); void switch_pointers(oop from, oop to); void verify(); void read_snapshot(FILE* f); void write_snapshot(FILE* f); #ifdef UNUSED void relocate(); #endif void relocate_nmln(nmln*); void fixup(); void print(); void print_stats(); void print_nmethod_histogram(fint size); nmethod* first_nm() { return (nmethod*)(iZone->firstUsed()); } nmethod* next_nm(nmethod* p) { return (nmethod*)(iZone->nextUsed(p)); } char* instsStart(); int32 instsSize(); int32 LRU_time(); int32 sweeper(int32 maxVisit, int32 maxReclaim, int32* nvisited = NULL, int32* nbytesReclaimed = NULL); int32 nextNMethodID(); char *allocateDeps(fint nbytes); void deallocateDeps(char *d, fint nbytes) { dZone->deallocate(d, nbytes); } void setDepsMap(nmln *deps, slotsMapDeps *m); protected: void print_helper(bool stats); void adjustPolicy(); int32 flushNextMethod(int32 needed); inline nmethod* next_circular_nm(nmethod* nm); void doChainFrames(); void doUnchainFrames(); friend void moveInsts(char* from, char* to, int32 size); friend void printAllNMethods(); friend void sweepTrigger(); }; // use this to make sure frames are unchained when returning from function class FrameChainer { zone* z; public: FrameChainer(zone* zz) { z = zz; zz->chainFrames(); } ~FrameChainer() { z->unchainFrames(); } }; // holds usage information for nmethods (or index of next free nmethod ID // if not assigned to any nmethod) class LRUcount { public: uint16 unused; // nmethod prologue clears BOTH fields to 0 uint16 lastUsed; // time of last use LRUcount() { ShouldNotCallThis(); } // shouldn't create LRUcount(LRUcount &/*l*/) { ShouldNotCallThis(); } // shouldn't create #ifdef UNUSED int32 asInt() { return *(int32*)this; } #endif void set(int32 i) { *(int32*)this = i; } }; extern LRUcount* LRUtable; // for optimized methods extern int32* LRUflag; // == LRUtable, just different type for convenience extern int32* useCount; // table with counts for unoptimized methods #define APPLY_TO_ZONES(template) \ template(Memory->code->iZone); \ template(Memory->code->dZone); \ template(Memory->code->sZone); \ template(Memory->code->stubs->zone()); \ # else // make a dummy zone class zone: public CHeapObj { public: bool contains(void *p) { Unused(p); return false;} int32 capacity() { return 0; } void compactAll() {} void flush() {} void flushUnused() {} void flushZombies() {} void flush_inline_cache() {} void markAllUnused() {} void flushInlineCache() {} void print_nmethod_histogram(fint size) { Unused(size); } void print_stats() {} zone(int32& iSize, int32& dSize, int32& sSize, int32& stSize) { iSize = dSize = sSize = stSize = 0; } void switch_pointers(oop from, oop to) { Unused(from); Unused(to); } void read_snapshot( FILE* f); void write_snapshot( FILE* f); void fixup() {} void verify() {} void clear() {} void print() {} void scavenge_contents() {} void gc_mark_contents() {} void gc_unmark_contents() {} void nonCombiningMode() {} char *allocateDeps(fint nbytes) { // no zone; no deps Unused(nbytes); ShouldNotCallThis(); return NULL; } void deallocateDeps(char *d, fint nbytes) { Unused(d); Unused(nbytes); ShouldNotCallThis(); } void setDepsMap(nmln *deps, slotsMapDeps *m) { Unused(deps); Unused(m); ShouldNotCallThis(); } void chainFrames() {} void unchainFrames() {} void findNMethodOrMap(nmln *n, nmethod* &nm, slotsMapDeps* &s); }; #define APPLY_TO_ZONES(template) # endif // defined(FAST_COMPILER) || defined(SIC_COMPILER)