/* Sun-$Revision: 23.10 $ */ /* Copyright 1992-9 Sun Microsystems, Inc. and Stanford University. See the LICENSE file for license information. */ # pragma interface extern bool NeedScavenge; // set when eden overflows extern bool GCInProgress; // GC/scavenge in progress extern bool ScavengeInProgress; // Scavenge in progress extern bool bootstrapping; // true only at the very beginning extern bool postReadSnapshot; // true after reading in a snapshot // reset after evaluation of snapshot actions extern char *WorldName; // Starting Snapshot name extern bool compressed_snapshot;// Is the starting snapshot compressed? extern bool page_aligned; // Are space boundaries page aligned? extern bool SnapshotCode; // reading=>snap contains code; writing=>write code extern bool okToUseCodeFromSnapshot; extern bool noCodeWarnings; // Suppress VM startup warnings about code extern char* vmDate; struct universe { smi major_version; smi minor_version; smi snapshot_version; smiOop programming_timestamp; newGeneration *new_gen; oldGeneration *old_gen; zone* code; stringTable* string_table; rSet* remembered_set; ageTable* age_table; oTable* object_table; // prototypes (don't forget to change APPLY_TO_VM_OOPS below) slotsOop lobbyObj; slotsOop nilObj; slotsOop trueObj; slotsOop falseObj; stringOop stringObj; assignmentOop assignmentObj; objVectorOop objVectorObj; byteVectorOop byteVectorObj; blockOop deadBlockObj; slotsOop blockTraitsObj; processOop processObj; profilerOop profilerObj; vframeOop outerActivationObj; vframeOop blockActivationObj; proxyOop proxyObj; fctProxyOop fctProxyObj; objVectorOop literalsObj; oop slotAnnotationObj; oop objectAnnotationObj; slotsOop errorObj; // objectID objVectorOop objectIDArray; // mirrors (don't forget to change APPLY_TO_VM_OOPS and FOR_ALL_MAP_TYPES // below) mirrorOop assignmentMirrorObj; mirrorOop blockMirrorObj; mirrorOop byteVectorMirrorObj; mirrorOop outerMethodMirrorObj; mirrorOop blockMethodMirrorObj; mirrorOop floatMirrorObj; mirrorOop slotsMirrorObj; mirrorOop objVectorMirrorObj; mirrorOop smiMirrorObj; mirrorOop stringMirrorObj; mirrorOop processMirrorObj; mirrorOop outerActivationMirrorObj; mirrorOop blockActivationMirrorObj; mirrorOop proxyMirrorObj; mirrorOop fctProxyMirrorObj; mirrorOop profilerMirrorObj; mirrorOop mirrorMirrorObj; // maps Map* smi_map; Map* float_map; Map* mark_map; Map* map_map; inline Map* true_map(); inline Map* false_map(); inline mapOop true_mapOop(); inline mapOop false_mapOop(); // additional variables int32 tenuring_threshold; int scavengeCount; int32 Desired_Surv_Size; // hash table holding maps mapTable* map_table; // creation universe(); // space operations bool is_heap(oop* p) { return new_gen->contains(p) || old_gen->contains(p); } bool is_obj_heap(oop* p) { return new_gen->objs_contains(p) || old_gen->objs_contains(p); } memOop relocate(memOop p); bool verify_oop(memOop p, bool expectErrorObj = false); bool really_contains(void *p); space* spaceFor(void* p); generation* generation_containing(oop p) { return new_gen->contains(p) ? (generation*)new_gen : (generation*)old_gen; } // allocators oop* alloc_objs (fint size, bool mustAllocate= true) { return new_gen->alloc_objs(size, mustAllocate); } oop* alloc_objs_and_bytes(fint size, fint bsize, char*& bytes, bool mustAllocate= true) { return new_gen->alloc_objs_and_bytes(size, bsize, bytes, mustAllocate); } // scavenging operations void swapSurvivors(); oop scavenge(oop p = NULL); oop tenure(oop p = NULL); void default_low_space_handler(oop p= NULL); void need_scavenge() { if (! NeedScavenge) { NeedScavenge = true; currentProcess->setupPreemption(); } } bool needs_scavenge() { return NeedScavenge; } bool should_scavenge(memOop p) { return new_gen->eden_space->contains(p) || new_gen->from_space->contains(p); } inline space* survivor_space(memOop p, fint size, fint bsize, bool &is_new); // garbage collecting operations oop garbage_collect(oop p = NULL); bool might_run_out_of_space_on_scavenge() { return new_gen->used() > old_gen->scavenge_space->bytes_free(); } // enumeration primitives void enumerate_matches(enumeration *e); void enumerate_maps(enumeration *e); void enumerate_families(enumeration *e); void enumerate_all_objs(enumeration *e); int32 bytes_free() { return old_gen->bytes_free(); } int32 oops_free() { return old_gen->oops_free(); } oop get_mem_current_state_prim(oop rcvrIgnored, slotsOop proto, void *FH); // snapshotting operations char *check_sizes_for_snapshot(spaceSizes &snap_sizes); bool write_snapshot(char *fileName, char *compression_filter, char *decompression_filter, spaceSizes *snap_sizes); private: void read_snapshot_header(FILE* file); void read_snapshot(FILE* file); void get_space_sizes(); void genesis(); friend void OS::FWrite(const void* , int32 , FILE* ); // calls snapshot_failed static void snapshot_failed(); #define SPACE_CHECK_DECL_TEMPLATE(s) \ char *CONC(check_,s)(spaceSizes &snap_sizes); APPLY_TO_SPACE_SIZES(SPACE_CHECK_DECL_TEMPLATE) public: spaceSizes current_sizes, default_sizes; public: // operations: we need extras because of include file orderings void store(oop* p, smiOop contents) { *(smiOop*)p = contents;} inline void store(oop* p, oop contents, bool cs= true); // inlined in oop.h void record_multistores(void* start, void* endArg) { remembered_set->record_multistores(start, endArg); } void switch_pointers(oop from, oop to); void verify(bool postScavenge = false); void increment_programming_timestamp(); // forwarders to zone if there is one void nonCombiningMode(); void setDepsMap(nmln *deps, slotsMapDeps *m); nmln* allocateSlotDeps(slotsMapDeps *m); void deallocateSlotDeps(nmln *deps, fint ndeps); // printing operations void print(); void objectSizeHistogram(fint maxSize); private: char *verify_opts; public: char* printAddr; // used for debug printing byteVectorOop verifyOpts(char *newOpts); bool is_verify_opt(char c) { return strchr(verify_opts, c) != NULL; } #ifdef DEBUG void printRegion(char *&caddr, int count= 16); #endif void printSlotDescStats(); }; extern universe* Memory; smi set_memory_tenuring_threshold_prim(oop rcvrIgnored, smi newThresh, void *FH); oop expand_heap_prim(oop rcvrIgnored, smi size); oop full_write_snapshot_prim(oop rcvrIgnored, byteVectorOop name, slotsOop compression_obj, slotsOop sizeObj, bool snapCode, void *FH); oop VMversion_prim(oop rcvrIgnored); void noCodeWarning(char *msg); void check_delim(FILE *file, char *expected); void write_delim(FILE *file, char *delim); # define APPLY_TO_VM_OOPS(template) \ template(&Memory->lobbyObj) \ template(&Memory->nilObj) \ template(&Memory->trueObj) \ template(&Memory->falseObj) \ template(&Memory->stringObj) \ template(&Memory->assignmentObj) \ template(&Memory->objVectorObj) \ template(&Memory->byteVectorObj) \ template(&Memory->blockTraitsObj) \ template(&Memory->deadBlockObj) \ template(&Memory->processObj) \ template(&Memory->profilerObj) \ template(&Memory->outerActivationObj) \ template(&Memory->blockActivationObj) \ template(&Memory->proxyObj) \ template(&Memory->fctProxyObj) \ template(&Memory->literalsObj) \ template(&Memory->slotAnnotationObj) \ template(&Memory->objectAnnotationObj) \ template(&Memory->errorObj) \ \ template(&Memory->assignmentMirrorObj) \ template(&Memory->blockMirrorObj) \ template(&Memory->byteVectorMirrorObj) \ template(&Memory->outerMethodMirrorObj) \ template(&Memory->blockMethodMirrorObj) \ template(&Memory->floatMirrorObj) \ template(&Memory->objVectorMirrorObj) \ template(&Memory->slotsMirrorObj) \ template(&Memory->smiMirrorObj) \ template(&Memory->stringMirrorObj) \ template(&Memory->processMirrorObj) \ template(&Memory->outerActivationMirrorObj) \ template(&Memory->blockActivationMirrorObj) \ template(&Memory->proxyMirrorObj) \ template(&Memory->fctProxyMirrorObj) \ template(&Memory->profilerMirrorObj) \ template(&Memory->mirrorMirrorObj) \ \ template(&Memory->objectIDArray) \ template(&BugHuntNames) \ // must be a complete list of all concrete map types (ordered by frequency) # define FOR_ALL_MAP_TYPES(template) \ template(slotsMap) \ template(slotsMapDeps) \ template(smiMap) \ template(floatMap) \ template(stringMap) \ template(blockMap) \ template(outerMethodMap) \ template(blockMethodMap) \ template(byteVectorMap) \ template(objVectorMap) \ template(mapMap) \ template(markMap) \ template(proxyMap) \ template(fctProxyMap) \ template(mirrorMap) \ template(ovframeMap) \ template(bvframeMap) \ template(processMap) \ template(profilerMap) \ template(assignmentMap) \ # define OOPS_DO_TEMPLATE(p, f) \ (*f)((oop*)p); # define SCAVENGE_TEMPLATE(p) \ *((oop*) p) = oop(*p)->scavenge(); # define MARK_TEMPLATE(p) \ *((oop*) p) = oop(*p)->gc_mark(); # define UNMARK_TEMPLATE(p) \ *((oop*) p) = oop(*p)->gc_unmark(); # define VERIFY_TEMPLATE(p) \ if (!oop(*p)->verify_oop()) lprintf("\tof object at 0x%lx\n", p); # define VERIFY_TEMPLATE_EXPECT_ERROR_OBJ(p) \ if (!oop(*p)->verify_oop(true)) lprintf("\tof object at 0x%lx\n", (unsigned long)p); # define SWITCH_POINTERS_TEMPLATE(p) \ if ((oop) *p == (oop) from) *((oop*) p) = (oop) to; # define UNDERIVE(p, offset) oop(((oop*) (p)) - (offset)) # define REDERIVE(p, offset) oop(((oop*) (p)) + (offset)) # define DERIVED_OOPS_DO_TEMPLATE(p, f) \ { int32 __o = oop(*p)->derived_offset(); \ oop __p = UNDERIVE(*p,__o); \ (*f)(&__p); \ *((oop*) p) = REDERIVE(__p,__o); } # define DERIVED_SCAVENGE_TEMPLATE(p) \ { int32 __o = oop(*p)->derived_offset(); \ oop __p = UNDERIVE(*p,__o); \ __p = __p->scavenge(); \ *((oop*) p) = REDERIVE(__p,__o); } // The stack iterators examine any location exactly once, // this code messes up if it sees an already forwarded point, thus the assert. # define DERIVED_MARK_TEMPLATE(p) \ { assert( !(*p)->is_mem() || Memory->is_obj_heap((oop*)memOop(*p)->addr()), \ "used for stack, so should only see a given place one time"); \ int32 __o = oop(*p)->derived_offset(); \ oop __p = UNDERIVE(*p,__o); \ *((oop*) p) = __p->gc_mark_derived(p,__o); } # define DERIVED_UNMARK_TEMPLATE(p) \ *((oop*) p) = oop(*p)->gc_unmark_derived(p); # define DERIVED_VERIFY_TEMPLATE(p) \ { int32 __o = oop(*p)->derived_offset(); \ if (!UNDERIVE(*p,__o)->verify_oop(true)) { \ lprintf("\tof object at 0x%lx\n", p); \ } } # define DERIVED_SWITCH_POINTERS_TEMPLATE(p) \ { int32 __o = oop(*p)->derived_offset(); \ oop __p = UNDERIVE(*p,__o); \ if (UNDERIVE(*p, __o) == (oop) from) { \ *((oop*) p) = REDERIVE((oop) to,__o); \ } } # define READ_SNAPSHOT_TEMPLATE(p) \ OS::FRead(p, oopSize, file); # define WRITE_SNAPSHOT_TEMPLATE(p) \ OS::FWrite(p, oopSize, snapFile); # define RELOCATE_TEMPLATE(p) \ *((oop*) p) = oop(*p)->relocate(); # define APPLY_TO_VM_MAPS(template) \ template(&smi_map) \ template(&float_map) \ template(&mark_map) \ template(&map_map) \ # define MAP_MARK_TEMPLATE(m) \ *m = mapOop(as_mapOop(*m)->gc_mark())->addr(); # define MAP_SCAVENGE_TEMPLATE(m) \ *m = mapOop(oop(as_mapOop(*m))->scavenge())->addr(); # define MAP_UNMARK_TEMPLATE(m) \ *m = mapOop(as_mapOop(*m)->gc_unmark())->addr(); # define MAP_SWITCH_POINTERS_TEMPLATE(m) \ if (from == as_mapOop(*m)) *m = mapOop(to)->addr(); # define MAP_READ_SNAPSHOT_TEMPLATE(m) \ OS::FRead(m, oopSize, file); # define MAP_WRITE_SNAPSHOT_TEMPLATE(m) \ OS::FWrite(m, oopSize, snapFile); # define MAP_RELOCATE_TEMPLATE(m) \ *m = mapOop(as_mapOop(*m)->relocate())->addr(); # define MAP_VERIFY_TEMPLATE(m) \ if (!as_mapOop(*m)->verify_oop()) lprintf("\tof vm map\n"); # define MAP_CANONICALIZATION_TEMPLATE(m) \ { Map *_m= *m; \ if (_m->should_canonicalize()) \ map_table->add_map_from_snapshot((slotsMapDeps*)_m); } # define APPLY_TO_YOUNG_SPACE_NAMES(template) \ template(eden) \ template(from) \ template(to) # define APPLY_TO_YOUNG_SPACES(template) \ template(new_gen->eden_space) \ template(new_gen->from_space) \ template(new_gen->to_space) #define APPLY_TO_OLD_SPACES(template) \ {FOR_EACH_OLD_SPACE(s) {template(s);}} # define APPLY_TO_SPACES(template) \ APPLY_TO_YOUNG_SPACES(template) \ APPLY_TO_OLD_SPACES(template) # define YOUNG_SPACE_COMPACT_TEMPLATE(s) \ c2= s; s->compact(unmarked_map_map, c2, d, bd); # define OLD_SPACE_COMPACT_TEMPLATE(s) \ s->compact(unmarked_map_map, c2, d, bd); # define SPACE_UNMARK_TEMPLATE(s) \ s->gc_unmark_contents(); # define SPACE_VERIFY_TEMPLATE(s) \ s->verify(); # define SPACE_RELOCATE_TEMPLATE(s) \ s->relocate(); # define SPACE_RELOCATE_BYTES_TEMPLATE(s) \ s->relocate_bytes(); # define SPACE_NEED_TO_RELOCATE_TEMPLATE(s) \ need_to_relocate |= s->need_to_relocate(); \ need_to_relocate_objs |= s->need_to_relocate_objs(); # define SPACE_FIXUP_MAPS_TEMPLATE(s) \ s->fixup_maps(); # define SPACE_CANONICALIZE_MAPS_TEMPLATE(s) \ s->canonicalize_maps(); # define SPACE_FIXUP_KILLABLES_TEMPLATE(s) \ s->fixup_killables(); # define SPACE_OOP_RELOCATE_TEMPLATE(s) \ if (s->old_objs_contains(p)) return s->relocate_objs(p); # define SPACE_VERIFY_OOP_TEMPLATE(s) \ if (s->objs_contains(p)) return true; # define SPACE_ENUMERATE_ALL_OBJS_TEMPLATE(s) \ s->enumerate_all_objs(e); # define SPACE_ENUMERATE_MATCHES_TEMPLATE(s) \ s->enumerate_matches(e); # define SPACE_ENUMERATE_MAPS_TEMPLATE(s) \ s->enumerate_maps(e); # define SPACE_ENUMERATE_FAMILIES_TEMPLATE(s) \ s->enumerate_families(e); # define SPACE_PRINT_TEMPLATE(s) \ s->print(); # define SPACE_REALLY_CONTAINS_TEMPLATE(s) \ if (s->really_contains(p)) return true;