\
product(uintx, CMS_SweepPadding, 1, \
"The multiple of deviation from mean to use for buffering " \
"against volatility in inter-sweep duration") \
\
product(uintx, CMS_SweepTimerThresholdMillis, 10, \
"Skip block flux-rate sampling for an epoch unless inter-sweep " \
"duration exceeds this threshold in milliseconds") \
\
develop(bool, CMSTraceIncrementalMode, false, \
"Trace CMS incremental mode") \
\
develop(bool, CMSTraceIncrementalPacing, false, \
"Trace CMS incremental mode pacing computation") \
\
develop(bool, CMSTraceThreadState, false, \
"Trace the CMS thread state (enable the trace_state() method)") \
\
product(bool, CMSClassUnloadingEnabled, true, \
"Whether class unloading enabled when using CMS GC") \
\
product(uintx, CMSClassUnloadingMaxInterval, 0, \
"When CMS class unloading is enabled, the maximum CMS cycle " \
"count for which classes may not be unloaded") \
\
product(bool, CMSCompactWhenClearAllSoftRefs, true, \
"Compact when asked to collect CMS gen with " \
"clear_all_soft_refs()") \
\
product(bool, UseCMSCompactAtFullCollection, true, \
"Use Mark-Sweep-Compact algorithm at full collections") \
\
product(uintx, CMSFullGCsBeforeCompaction, 0, \
"Number of CMS full collection done before compaction if > 0") \
\
develop(intx, CMSDictionaryChoice, 0, \
"Use BinaryTreeDictionary as default in the CMS generation") \
\
product(uintx, CMSIndexedFreeListReplenish, 4, \
"Replenish an indexed free list with this number of chunks") \
\
product(bool, CMSReplenishIntermediate, true, \
"Replenish all intermediate free-list caches") \
\
product(bool, CMSSplitIndexedFreeListBlocks, true, \
"When satisfying batched demand, split blocks from the " \
"IndexedFreeList whose size is a multiple of requested size") \
\
product(bool, CMSLoopWarn, false, \
"Warn in case of excessive CMS looping") \
\
develop(bool, CMSOverflowEarlyRestoration, false, \
"Restore preserved marks early") \
\
product(uintx, MarkStackSize, NOT_LP64(32*K) LP64_ONLY(4*M), \
"Size of marking stack") \
\
product(uintx, MarkStackSizeMax, NOT_LP64(4*M) LP64_ONLY(512*M), \
"Maximum size of marking stack") \
\
notproduct(bool, CMSMarkStackOverflowALot, false, \
"Simulate frequent marking stack / work queue overflow") \
\
notproduct(uintx, CMSMarkStackOverflowInterval, 1000, \
"An \"interval\" counter that determines how frequently " \
"to simulate overflow; a smaller number increases frequency") \
\
product(uintx, CMSMaxAbortablePrecleanLoops, 0, \
"(Temporary, subject to experimentation) " \
"Maximum number of abortable preclean iterations, if > 0") \
\
product(intx, CMSMaxAbortablePrecleanTime, 5000, \
"(Temporary, subject to experimentation) " \
"Maximum time in abortable preclean (in milliseconds)") \
\
product(uintx, CMSAbortablePrecleanMinWorkPerIteration, 100, \
"(Temporary, subject to experimentation) " \
"Nominal minimum work per abortable preclean iteration") \
\
manageable(intx, CMSAbortablePrecleanWaitMillis, 100, \
"(Temporary, subject to experimentation) " \
"Time that we sleep between iterations when not given " \
"enough work per iteration") \
\
product(uintx, CMSRescanMultiple, 32, \
"Size (in cards) of CMS parallel rescan task") \
\
product(uintx, CMSConcMarkMultiple, 32, \
"Size (in cards) of CMS concurrent MT marking task") \
\
product(bool, CMSAbortSemantics, false, \
"Whether abort-on-overflow semantics is implemented") \
\
product(bool, CMSParallelInitialMarkEnabled, true, \
"Use the parallel initial mark.") \
\
product(bool, CMSParallelRemarkEnabled, true, \
"Whether parallel remark enabled (only if ParNewGC)") \
\
product(bool, CMSParallelSurvivorRemarkEnabled, true, \
"Whether parallel remark of survivor space " \
"enabled (effective only if CMSParallelRemarkEnabled)") \
\
product(bool, CMSPLABRecordAlways, true, \
"Always record survivor space PLAB boundaries (effective only " \
"if CMSParallelSurvivorRemarkEnabled)") \
\
product(bool, CMSEdenChunksRecordAlways, true, \
"Always record eden chunks used for the parallel initial mark " \
"or remark of eden") \
\
product(bool, CMSPrintEdenSurvivorChunks, false, \
"Print the eden and the survivor chunks used for the parallel " \
"initial mark or remark of the eden/survivor spaces") \
\
product(bool, CMSConcurrentMTEnabled, true, \
"Whether multi-threaded concurrent work enabled " \
"(effective only if ParNewGC)") \
\
product(bool, CMSPrecleaningEnabled, true, \
"Whether concurrent precleaning enabled") \
\
product(uintx, CMSPrecleanIter, 3, \
"Maximum number of precleaning iteration passes") \
\
product(uintx, CMSPrecleanNumerator, 2, \
"CMSPrecleanNumerator:CMSPrecleanDenominator yields convergence " \
"ratio") \
\
product(uintx, CMSPrecleanDenominator, 3, \
"CMSPrecleanNumerator:CMSPrecleanDenominator yields convergence " \
"ratio") \
\
product(bool, CMSPrecleanRefLists1, true, \
"Preclean ref lists during (initial) preclean phase") \
\
product(bool, CMSPrecleanRefLists2, false, \
"Preclean ref lists during abortable preclean phase") \
\
product(bool, CMSPrecleanSurvivors1, false, \
"Preclean survivors during (initial) preclean phase") \
\
product(bool, CMSPrecleanSurvivors2, true, \
"Preclean survivors during abortable preclean phase") \
\
product(uintx, CMSPrecleanThreshold, 1000, \
"Do not iterate again if number of dirty cards is less than this")\
\
product(bool, CMSCleanOnEnter, true, \
"Clean-on-enter optimization for reducing number of dirty cards") \
\
product(uintx, CMSRemarkVerifyVariant, 1, \
"Choose variant (1,2) of verification following remark") \
\
product(uintx, CMSScheduleRemarkEdenSizeThreshold, 2*M, \
"If Eden size is below this, do not try to schedule remark") \
\
product(uintx, CMSScheduleRemarkEdenPenetration, 50, \
"The Eden occupancy percentage (0-100) at which " \
"to try and schedule remark pause") \
\
product(uintx, CMSScheduleRemarkSamplingRatio, 5, \
"Start sampling eden top at least before young gen " \
"occupancy reaches 1/<ratio> of the size at which " \
"we plan to schedule remark") \
\
product(uintx, CMSSamplingGrain, 16*K, \
"The minimum distance between eden samples for CMS (see above)") \
\
product(bool, CMSScavengeBeforeRemark, false, \
"Attempt scavenge before the CMS remark step") \
\
develop(bool, CMSTraceSweeper, false, \
"Trace some actions of the CMS sweeper") \
\
product(uintx, CMSWorkQueueDrainThreshold, 10, \
"Don't drain below this size per parallel worker/thief") \
\
manageable(intx, CMSWaitDuration, 2000, \
"Time in milliseconds that CMS thread waits for young GC") \
\
develop(uintx, CMSCheckInterval, 1000, \
"Interval in milliseconds that CMS thread checks if it " \
"should start a collection cycle") \
\
product(bool, CMSYield, true, \
"Yield between steps of CMS") \
\
product(uintx, CMSBitMapYieldQuantum, 10*M, \
"Bitmap operations should process at most this many bits " \
"between yields") \
\
product(bool, CMSDumpAtPromotionFailure, false, \
"Dump useful information about the state of the CMS old " \
"generation upon a promotion failure") \
\
product(bool, CMSPrintChunksInDump, false, \
"In a dump enabled by CMSDumpAtPromotionFailure, include " \
"more detailed information about the free chunks") \
\
product(bool, CMSPrintObjectsInDump, false, \
"In a dump enabled by CMSDumpAtPromotionFailure, include " \
"more detailed information about the allocated objects") \
\
diagnostic(bool, FLSVerifyAllHeapReferences, false, \
"Verify that all references across the FLS boundary " \
"are to valid objects") \
\
diagnostic(bool, FLSVerifyLists, false, \
"Do lots of (expensive) FreeListSpace verification") \
\
diagnostic(bool, FLSVerifyIndexTable, false, \
"Do lots of (expensive) FLS index table verification") \
\
develop(bool, FLSVerifyDictionary, false, \
"Do lots of (expensive) FLS dictionary verification") \
\
develop(bool, VerifyBlockOffsetArray, false, \
"Do (expensive) block offset array verification") \
\
diagnostic(bool, BlockOffsetArrayUseUnallocatedBlock, false, \
"Maintain _unallocated_block in BlockOffsetArray " \
"(currently applicable only to CMS collector)") \
\
develop(bool, TraceCMSState, false, \
"Trace the state of the CMS collection") \
\
product(intx, RefDiscoveryPolicy, 0, \
"Select type of reference discovery policy: " \
"reference-based(0) or referent-based(1)") \
\
product(bool, ParallelRefProcEnabled, false, \
"Enable parallel reference processing whenever possible") \
\
product(bool, ParallelRefProcBalancingEnabled, true, \
"Enable balancing of reference processing queues") \
\
product(uintx, CMSTriggerRatio, 80, \
"Percentage of MinHeapFreeRatio in CMS generation that is " \
"allocated before a CMS collection cycle commences") \
\
product(uintx, CMSBootstrapOccupancy, 50, \
"Percentage CMS generation occupancy at which to " \
"initiate CMS collection for bootstrapping collection stats") \
\
product(intx, CMSInitiatingOccupancyFraction, -1, \
"Percentage CMS generation occupancy to start a CMS collection " \
"cycle. A negative value means that CMSTriggerRatio is used") \
\
product(uintx, InitiatingHeapOccupancyPercent, 45, \
"Percentage of the (entire) heap occupancy to start a " \
"concurrent GC cycle. It is used by GCs that trigger a " \
"concurrent GC cycle based on the occupancy of the entire heap, " \
"not just one of the generations (e.g., G1). A value of 0 " \
"denotes 'do constant GC cycles'.") \
\
manageable(intx, CMSTriggerInterval, -1, \
"Commence a CMS collection cycle (at least) every so many " \
"milliseconds (0 permanently, -1 disabled)") \
\
product(bool, UseCMSInitiatingOccupancyOnly, false, \
"Only use occupancy as a criterion for starting a CMS collection")\
\
product(uintx, CMSIsTooFullPercentage, 98, \
"An absolute ceiling above which CMS will always consider the " \
"unloading of classes when class unloading is enabled") \
\
develop(bool, CMSTestInFreeList, false, \
"Check if the coalesced range is already in the " \
"free lists as claimed") \
\
notproduct(bool, CMSVerifyReturnedBytes, false, \
"Check that all the garbage collected was returned to the " \
"free lists") \
\
notproduct(bool, ScavengeALot, false, \
"Force scavenge at every Nth exit from the runtime system " \
"(N=ScavengeALotInterval)") \
\
develop(bool, FullGCALot, false, \
"Force full gc at every Nth exit from the runtime system " \
"(N=FullGCALotInterval)") \
\
notproduct(bool, GCALotAtAllSafepoints, false, \
"Enforce ScavengeALot/GCALot at all potential safepoints") \
\
product(bool, PrintPromotionFailure, false, \
"Print additional diagnostic information following " \
"promotion failure") \
\
notproduct(bool, PromotionFailureALot, false, \
"Use promotion failure handling on every youngest generation " \
"collection") \
\
develop(uintx, PromotionFailureALotCount, 1000, \
"Number of promotion failures occurring at ParGCAllocBuffer " \
"refill attempts (ParNew) or promotion attempts " \
"(other young collectors)") \
\
develop(uintx, PromotionFailureALotInterval, 5, \
"Total collections between promotion failures alot") \
\
experimental(uintx, WorkStealingSleepMillis, 1, \
"Sleep time when sleep is used for yields") \
\
experimental(uintx, WorkStealingYieldsBeforeSleep, 5000, \
"Number of yields before a sleep is done during workstealing") \
\
experimental(uintx, WorkStealingHardSpins, 4096, \
"Number of iterations in a spin loop between checks on " \
"time out of hard spin") \
\
experimental(uintx, WorkStealingSpinToYieldRatio, 10, \
"Ratio of hard spins to calls to yield") \
\
develop(uintx, ObjArrayMarkingStride, 2048, \
"Number of object array elements to push onto the marking stack " \
"before pushing a continuation entry") \
\
develop(bool, MetadataAllocationFailALot, false, \
"Fail metadata allocations at intervals controlled by " \
"MetadataAllocationFailALotInterval") \
\
develop(uintx, MetadataAllocationFailALotInterval, 1000, \
"Metadata allocation failure a lot interval") \
\
develop(bool, TraceMetadataChunkAllocation, false, \
"Trace chunk metadata allocations") \
\
product(bool, TraceMetadataHumongousAllocation, false, \
"Trace humongous metadata allocations") \
\
develop(bool, TraceMetavirtualspaceAllocation, false, \
"Trace virtual space metadata allocations") \
\
notproduct(bool, ExecuteInternalVMTests, false, \
"Enable execution of internal VM tests") \
\
notproduct(bool, VerboseInternalVMTests, false, \
"Turn on logging for internal VM tests.") \
\
product_pd(bool, UseTLAB, "Use thread-local object allocation") \
\
product_pd(bool, ResizeTLAB, \
"Dynamically resize TLAB size for threads") \
\
product(bool, ZeroTLAB, false, \
"Zero out the newly created TLAB") \
\
product(bool, FastTLABRefill, true, \
"Use fast TLAB refill code") \
\
product(bool, PrintTLAB, false, \
"Print various TLAB related information") \
\
product(bool, TLABStats, true, \
"Provide more detailed and expensive TLAB statistics " \
"(with PrintTLAB)") \
\
product_pd(bool, NeverActAsServerClassMachine, \
"Never act like a server-class machine") \
\
product(bool, AlwaysActAsServerClassMachine, false, \
"Always act like a server-class machine") \
\
product_pd(uint64_t, MaxRAM, \
"Real memory size (in bytes) used to set maximum heap size") \
\
product(bool, AggressiveHeap, false, \
"Optimize heap options for long-running memory intensive apps") \
\
product(uintx, ErgoHeapSizeLimit, 0, \
"Maximum ergonomically set heap size (in bytes); zero means use " \
"MaxRAM * MaxRAMPercentage / 100") \
\
experimental(bool, UseCGroupMemoryLimitForHeap, false, \
"Use CGroup memory limit as physical memory limit for heap " \
"sizing" \
"Deprecated, replaced by container support") \
\
diagnostic(bool, PrintContainerInfo, false, \
"Print container related information") \
\
diagnostic(bool, PrintActiveCpus, false, \
"Print the number of CPUs detected in os::active_processor_count") \
\
product(uintx, MaxRAMFraction, 4, \
"Maximum fraction (1/n) of real memory used for maximum heap " \
"size") \
\
product(uintx, DefaultMaxRAMFraction, 4, \
"Maximum fraction (1/n) of real memory used for maximum heap " \
"size; deprecated: to be renamed to MaxRAMFraction") \
\
product(uintx, MinRAMFraction, 2, \
"Minimum fraction (1/n) of real memory used for maxmimum heap " \
"size on systems with small physical memory size") \
\
product(uintx, InitialRAMFraction, 64, \
"Fraction (1/n) of real memory used for initial heap size") \
\
product(double, MaxRAMPercentage, 25.0, \
"Maximum percentage of real memory used for maximum heap size") \
\
product(double, MinRAMPercentage, 50.0, \
"Minimum percentage of real memory used for maximum heap" \
"size on systems with small physical memory size") \
\
product(double, InitialRAMPercentage, 1.5625, \
"Percentage of real memory used for initial heap size") \
\
product(intx, ActiveProcessorCount, -1, \
"Specify the CPU count the VM should use and report as active") \
\
develop(uintx, MaxVirtMemFraction, 2, \
"Maximum fraction (1/n) of virtual memory used for ergonomically "\
"determining maximum heap size") \
\
product(bool, UseAutoGCSelectPolicy, false, \
"Use automatic collection selection policy") \
\
product(uintx, AutoGCSelectPauseMillis, 5000, \
"Automatic GC selection pause threshold in milliseconds") \
\
product(bool, UseAdaptiveSizePolicy, true, \
"Use adaptive generation sizing policies") \
\
product(bool, UsePSAdaptiveSurvivorSizePolicy, true, \
"Use adaptive survivor sizing policies") \
\
product(bool, UseAdaptiveGenerationSizePolicyAtMinorCollection, true, \
"Use adaptive young-old sizing policies at minor collections") \
\
product(bool, UseAdaptiveGenerationSizePolicyAtMajorCollection, true, \
"Use adaptive young-old sizing policies at major collections") \
\
product(bool, UseAdaptiveSizePolicyWithSystemGC, false, \
"Include statistics from System.gc() for adaptive size policy") \
\
product(bool, UseAdaptiveGCBoundary, false, \
"Allow young-old boundary to move") \
\
develop(bool, TraceAdaptiveGCBoundary, false, \
"Trace young-old boundary moves") \
\
develop(intx, PSAdaptiveSizePolicyResizeVirtualSpaceAlot, -1, \
"Resize the virtual spaces of the young or old generations") \
\
product(uintx, AdaptiveSizeThroughPutPolicy, 0, \
"Policy for changing generation size for throughput goals") \
\
product(uintx, AdaptiveSizePausePolicy, 0, \
"Policy for changing generation size for pause goals") \
\
develop(bool, PSAdjustTenuredGenForMinorPause, false, \
"Adjust tenured generation to achieve a minor pause goal") \
\
develop(bool, PSAdjustYoungGenForMajorPause, false, \
"Adjust young generation to achieve a major pause goal") \
\
product(uintx, AdaptiveSizePolicyInitializingSteps, 20, \
"Number of steps where heuristics is used before data is used") \
\
develop(uintx, AdaptiveSizePolicyReadyThreshold, 5, \
"Number of collections before the adaptive sizing is started") \
\
product(uintx, AdaptiveSizePolicyOutputInterval, 0, \
"Collection interval for printing information; zero means never") \
\
product(bool, UseAdaptiveSizePolicyFootprintGoal, true, \
"Use adaptive minimum footprint as a goal") \
\
product(uintx, AdaptiveSizePolicyWeight, 10, \
"Weight given to exponential resizing, between 0 and 100") \
\
product(uintx, AdaptiveTimeWeight, 25, \
"Weight given to time in adaptive policy, between 0 and 100") \
\
product(uintx, PausePadding, 1, \
"How much buffer to keep for pause time") \
\
product(uintx, PromotedPadding, 3, \
"How much buffer to keep for promotion failure") \
\
product(uintx, SurvivorPadding, 3, \
"How much buffer to keep for survivor overflow") \
\
product(uintx, ThresholdTolerance, 10, \
"Allowed collection cost difference between generations") \
\
product(uintx, AdaptiveSizePolicyCollectionCostMargin, 50, \
"If collection costs are within margin, reduce both by full " \
"delta") \
\
product(uintx, YoungGenerationSizeIncrement, 20, \
"Adaptive size percentage change in young generation") \
\
product(uintx, YoungGenerationSizeSupplement, 80, \
"Supplement to YoungedGenerationSizeIncrement used at startup") \
\
product(uintx, YoungGenerationSizeSupplementDecay, 8, \
"Decay factor to YoungedGenerationSizeSupplement") \
\
product(uintx, TenuredGenerationSizeIncrement, 20, \
"Adaptive size percentage change in tenured generation") \
\
product(uintx, TenuredGenerationSizeSupplement, 80, \
"Supplement to TenuredGenerationSizeIncrement used at startup") \
\
product(uintx, TenuredGenerationSizeSupplementDecay, 2, \
"Decay factor to TenuredGenerationSizeIncrement") \
\
product(uintx, MaxGCPauseMillis, max_uintx, \
"Adaptive size policy maximum GC pause time goal in millisecond, "\
"or (G1 Only) the maximum GC time per MMU time slice") \
\
product(uintx, GCPauseIntervalMillis, 0, \
"Time slice for MMU specification") \
\
product(uintx, MaxGCMinorPauseMillis, max_uintx, \
"Adaptive size policy maximum GC minor pause time goal " \
"in millisecond") \
\
product(uintx, GCTimeRatio, 99, \
"Adaptive size policy application time to GC time ratio") \
\
product(uintx, AdaptiveSizeDecrementScaleFactor, 4, \
"Adaptive size scale down factor for shrinking") \
\
product(bool, UseAdaptiveSizeDecayMajorGCCost, true, \
"Adaptive size decays the major cost for long major intervals") \
\
product(uintx, AdaptiveSizeMajorGCDecayTimeScale, 10, \
"Time scale over which major costs decay") \
\
product(uintx, MinSurvivorRatio, 3, \
"Minimum ratio of young generation/survivor space size") \
\
product(uintx, InitialSurvivorRatio, 8, \
"Initial ratio of young generation/survivor space size") \
\
product(uintx, BaseFootPrintEstimate, 256*M, \
"Estimate of footprint other than Java Heap") \
\
product(bool, UseGCOverheadLimit, true, \
"Use policy to limit of proportion of time spent in GC " \
"before an OutOfMemory error is thrown") \
\
product(uintx, GCTimeLimit, 98, \
"Limit of the proportion of time spent in GC before " \
"an OutOfMemoryError is thrown (used with GCHeapFreeLimit)") \
\
product(uintx, GCHeapFreeLimit, 2, \
"Minimum percentage of free space after a full GC before an " \
"OutOfMemoryError is thrown (used with GCTimeLimit)") \
\
develop(uintx, AdaptiveSizePolicyGCTimeLimitThreshold, 5, \
"Number of consecutive collections before gc time limit fires") \
\
product(bool, PrintAdaptiveSizePolicy, false, \
"Print information about AdaptiveSizePolicy") \
\
product(intx, PrefetchCopyIntervalInBytes, -1, \
"How far ahead to prefetch destination area (<= 0 means off)") \
\
product(intx, PrefetchScanIntervalInBytes, -1, \
"How far ahead to prefetch scan area (<= 0 means off)") \
\
product(intx, PrefetchFieldsAhead, -1, \
"How many fields ahead to prefetch in oop scan (<= 0 means off)") \
\
diagnostic(bool, VerifySilently, false, \
"Do not print the verification progress") \
\
diagnostic(bool, VerifyDuringStartup, false, \
"Verify memory system before executing any Java code " \
"during VM initialization") \
\
diagnostic(bool, VerifyBeforeExit, trueInDebug, \
"Verify system before exiting") \
\
diagnostic(bool, VerifyBeforeGC, false, \
"Verify memory system before GC") \
\
diagnostic(bool, VerifyAfterGC, false, \
"Verify memory system after GC") \
\
diagnostic(bool, VerifyDuringGC, false, \
"Verify memory system during GC (between phases)") \
\
diagnostic(ccstrlist, VerifySubSet, "", \
"Memory sub-systems to verify when Verify*GC flag(s) " \
"are enabled. One or more sub-systems can be specified " \
"in a comma separated string. Sub-systems are: " \
"threads, heap, symbol_table, string_table, codecache, " \
"dictionary, classloader_data_graph, metaspace, jni_handles, " \
"c-heap, codecache_oops") \
\
diagnostic(bool, GCParallelVerificationEnabled, true, \
"Enable parallel memory system verification") \
\
diagnostic(bool, DeferInitialCardMark, false, \
"When +ReduceInitialCardMarks, explicitly defer any that " \
"may arise from new_pre_store_barrier") \
\
diagnostic(bool, VerifyRememberedSets, false, \
"Verify GC remembered sets") \
\
diagnostic(bool, VerifyObjectStartArray, true, \
"Verify GC object start array if verify before/after") \
\
product(bool, DisableExplicitGC, false, \
"Ignore calls to System.gc()") \
\
notproduct(bool, CheckMemoryInitialization, false, \
"Check memory initialization") \
\
product(bool, CollectGen0First, false, \
"Collect youngest generation before each full GC") \
\
diagnostic(bool, BindCMSThreadToCPU, false, \
"Bind CMS Thread to CPU if possible") \
\
diagnostic(uintx, CPUForCMSThread, 0, \
"When BindCMSThreadToCPU is true, the CPU to bind CMS thread to") \
\
product(bool, BindGCTaskThreadsToCPUs, false, \
"Bind GCTaskThreads to CPUs if possible") \
\
product(bool, UseGCTaskAffinity, false, \
"Use worker affinity when asking for GCTasks") \
\
product(uintx, ProcessDistributionStride, 4, \
"Stride through processors when distributing processes") \
\
product(uintx, CMSCoordinatorYieldSleepCount, 10, \
"Number of times the coordinator GC thread will sleep while " \
"yielding before giving up and resuming GC") \
\
product(uintx, CMSYieldSleepCount, 0, \
"Number of times a GC thread (minus the coordinator) " \
"will sleep while yielding before giving up and resuming GC") \
\
manageable(bool, PrintGC, false, \
"Print message at garbage collection") \
\
manageable(bool, PrintGCDetails, false, \
"Print more details at garbage collection") \
\
manageable(bool, PrintGCDateStamps, false, \
"Print date stamps at garbage collection") \
\
manageable(bool, PrintGCTimeStamps, false, \
"Print timestamps at garbage collection") \
\
manageable(bool, PrintGCID, false, \
"Print an identifier for each garbage collection") \
\
product(bool, PrintGCTaskTimeStamps, false, \
"Print timestamps for individual gc worker thread tasks") \
\
develop(intx, ConcGCYieldTimeout, 0, \
"If non-zero, assert that GC threads yield within this " \
"number of milliseconds") \
\
notproduct(bool, TraceMarkSweep, false, \
"Trace mark sweep") \
\
product(bool, PrintReferenceGC, false, \
"Print times spent handling reference objects during GC " \
"(enabled only when PrintGCDetails)") \
\
develop(bool, TraceReferenceGC, false, \
"Trace handling of soft/weak/final/phantom references") \
\
develop(bool, TraceFinalizerRegistration, false, \
"Trace registration of final references") \
\
notproduct(bool, TraceScavenge, false, \
"Trace scavenge") \
\
product(bool, IgnoreEmptyClassPaths, false, \
"Ignore empty path elements in -classpath") \
\
product(bool, TraceClassPaths, false, \
"Trace processing of class paths") \
\
product_rw(bool, TraceClassLoading, false, \
"Trace all classes loaded") \
\
product(bool, TraceClassLoadingPreorder, false, \
"Trace all classes loaded in order referenced (not loaded)") \
\
product_rw(bool, TraceClassUnloading, false, \
"Trace unloading of classes") \
\
product_rw(bool, TraceLoaderConstraints, false, \
"Trace loader constraints") \
\
develop(bool, TraceClassLoaderData, false, \
"Trace class loader loader_data lifetime") \
\
product(uintx, InitialBootClassLoaderMetaspaceSize, \
NOT_LP64(2200*K) LP64_ONLY(4*M), \
"Initial size of the boot class loader data metaspace") \
\
product(bool, TraceGen0Time, false, \
"Trace accumulated time for Gen 0 collection") \
\
product(bool, TraceGen1Time, false, \
"Trace accumulated time for Gen 1 collection") \
\
product(bool, PrintTenuringDistribution, false, \
"Print tenuring age information") \
\
product_rw(bool, PrintHeapAtGC, false, \
"Print heap layout before and after each GC") \
\
product_rw(bool, PrintHeapAtGCExtended, false, \
"Print extended information about the layout of the heap " \
"when -XX:+PrintHeapAtGC is set") \
\
product(bool, PrintHeapAtSIGBREAK, true, \
"Print heap layout in response to SIGBREAK") \
\
manageable(bool, PrintClassHistogramBeforeFullGC, false, \
"Print a class histogram before any major stop-world GC") \
\
manageable(bool, PrintClassHistogramAfterFullGC, false, \
"Print a class histogram after any major stop-world GC") \
\
manageable(bool, PrintClassHistogram, false, \
"Print a histogram of class instances") \
\
develop(bool, TraceWorkGang, false, \
"Trace activities of work gangs") \
\
product(bool, TraceParallelOldGCTasks, false, \
"Trace multithreaded GC activity") \
\
develop(bool, TraceBlockOffsetTable, false, \
"Print BlockOffsetTable maps") \
\
develop(bool, TraceCardTableModRefBS, false, \
"Print CardTableModRefBS maps") \
\
develop(bool, TraceGCTaskManager, false, \
"Trace actions of the GC task manager") \
\
develop(bool, TraceGCTaskQueue, false, \
"Trace actions of the GC task queues") \
\
diagnostic(bool, TraceGCTaskThread, false, \
"Trace actions of the GC task threads") \
\
product(bool, PrintParallelOldGCPhaseTimes, false, \
"Print the time taken by each phase in ParallelOldGC " \
"(PrintGCDetails must also be enabled)") \
\
develop(bool, TraceParallelOldGCMarkingPhase, false, \
"Trace marking phase in ParallelOldGC") \
\
develop(bool, TraceParallelOldGCSummaryPhase, false, \
"Trace summary phase in ParallelOldGC") \
\
develop(bool, TraceParallelOldGCCompactionPhase, false, \
"Trace compaction phase in ParallelOldGC") \
\
develop(bool, TraceParallelOldGCDensePrefix, false, \
"Trace dense prefix computation for ParallelOldGC") \
\
develop(bool, IgnoreLibthreadGPFault, false, \
"Suppress workaround for libthread GP fault") \
\
product(bool, PrintJNIGCStalls, false, \
"Print diagnostic message when GC is stalled " \
"by JNI critical section") \
\
experimental(double, ObjectCountCutOffPercent, 0.5, \
"The percentage of the used heap that the instances of a class " \
"must occupy for the class to generate a trace event") \
\
\
product(bool, UseGCLogFileRotation, false, \
"Rotate gclog files (for long running applications). It requires "\
"-Xloggc:<filename>") \
\
product(uintx, NumberOfGCLogFiles, 0, \
"Number of gclog files in rotation " \
"(default: 0, no rotation)") \
\
product(uintx, GCLogFileSize, 8*K, \
"GC log file size, requires UseGCLogFileRotation. " \
"Set to 0 to only trigger rotation via jcmd") \
\
\
diagnostic(bool, TraceJVMTIObjectTagging, false, \
"Trace JVMTI object tagging calls") \
\
diagnostic(bool, VerifyBeforeIteration, false, \
"Verify memory system before JVMTI iteration") \
\
\
develop(bool, CIPrintCompilerName, false, \
"when CIPrint is active, print the name of the active compiler") \
\
develop(bool, CIPrintCompileQueue, false, \
"display the contents of the compile queue whenever a " \
"compilation is enqueued") \
\
develop(bool, CIPrintRequests, false, \
"display every request for compilation") \
\
product(bool, CITime, false, \
"collect timing information for compilation") \
\
develop(bool, CITimeEach, false, \
"display timing information after each successful compilation") \
\
develop(bool, CICountOSR, false, \
"use a separate counter when assigning ids to osr compilations") \
\
develop(bool, CICompileNatives, true, \
"compile native methods if supported by the compiler") \
\
develop_pd(bool, CICompileOSR, \
"compile on stack replacement methods if supported by the " \
"compiler") \
\
develop(bool, CIPrintMethodCodes, false, \
"print method bytecodes of the compiled code") \
\
develop(bool, CIPrintTypeFlow, false, \
"print the results of ciTypeFlow analysis") \
\
develop(bool, CITraceTypeFlow, false, \
"detailed per-bytecode tracing of ciTypeFlow analysis") \
\
develop(intx, OSROnlyBCI, -1, \
"OSR only at this bci. Negative values mean exclude that bci") \
\
\
product(intx, CICompilerCount, CI_COMPILER_COUNT, \
"Number of compiler threads to run") \
\
product(intx, CompilationPolicyChoice, 0, \
"which compilation policy (0/1)") \
\
develop(bool, UseStackBanging, true, \
"use stack banging for stack overflow checks (required for " \
"proper StackOverflow handling; disable only to measure cost " \
"of stackbanging)") \
\
develop(bool, UseStrictFP, true, \
"use strict fp if modifier strictfp is set") \
\
develop(bool, GenerateSynchronizationCode, true, \
"generate locking/unlocking code for synchronized methods and " \
"monitors") \
\
develop(bool, GenerateCompilerNullChecks, true, \
"Generate explicit null checks for loads/stores/calls") \
\
develop(bool, GenerateRangeChecks, true, \
"Generate range checks for array accesses") \
\
develop_pd(bool, ImplicitNullChecks, \
"Generate code for implicit null checks") \
\
product_pd(bool, TrapBasedNullChecks, \
"Generate code for null checks that uses a cmp and trap " \
"instruction raising SIGTRAP. This is only used if an access to" \
"null (+offset) will not raise a SIGSEGV, i.e.," \
"ImplicitNullChecks don't work (PPC64).") \
\
product(bool, PrintSafepointStatistics, false, \
"Print statistics about safepoint synchronization") \
\
product(intx, PrintSafepointStatisticsCount, 300, \
"Total number of safepoint statistics collected " \
"before printing them out") \
\
product(intx, PrintSafepointStatisticsTimeout, -1, \
"Print safepoint statistics only when safepoint takes " \
"more than PrintSafepointSatisticsTimeout in millis") \
\
product(bool, TraceSafepointCleanupTime, false, \
"Print the break down of clean up tasks performed during " \
"safepoint") \
\
product(bool, Inline, true, \
"Enable inlining") \
\
product(bool, ClipInlining, true, \
"Clip inlining if aggregate method exceeds DesiredMethodLimit") \
\
develop(bool, UseCHA, true, \
"Enable CHA") \
\
product(bool, UseTypeProfile, true, \
"Check interpreter profile for historically monomorphic calls") \
\
notproduct(bool, TimeCompiler, false, \
"Time the compiler") \
\
diagnostic(bool, PrintInlining, false, \
"Print inlining optimizations") \
\
product(bool, UsePopCountInstruction, false, \
"Use population count instruction") \
\
develop(bool, EagerInitialization, false, \
"Eagerly initialize classes if possible") \
\
develop(bool, TraceMethodReplacement, false, \
"Print when methods are replaced do to recompilation") \
\
develop(bool, PrintMethodFlushing, false, \
"Print the nmethods being flushed") \
\
diagnostic(bool, PrintMethodFlushingStatistics, false, \
"print statistics about method flushing") \
\
develop(bool, UseRelocIndex, false, \
"Use an index to speed random access to relocations") \
\
develop(bool, StressCodeBuffers, false, \
"Exercise code buffer expansion and other rare state changes") \
\
diagnostic(bool, DebugNonSafepoints, trueInDebug, \
"Generate extra debugging information for non-safepoints in " \
"nmethods") \
\
product(bool, PrintVMOptions, false, \
"Print flags that appeared on the command line") \
\
product(bool, IgnoreUnrecognizedVMOptions, false, \
"Ignore unrecognized VM options") \
\
product(bool, PrintCommandLineFlags, false, \
"Print flags specified on command line or set by ergonomics") \
\
product(bool, PrintFlagsInitial, false, \
"Print all VM flags before argument processing and exit VM") \
\
product(bool, PrintFlagsFinal, false, \
"Print all VM flags after argument and ergonomic processing") \
\
notproduct(bool, PrintFlagsWithComments, false, \
"Print all VM flags with default values and descriptions and " \
"exit") \
\
diagnostic(bool, SerializeVMOutput, true, \
"Use a mutex to serialize output to tty and LogFile") \
\
diagnostic(bool, DisplayVMOutput, true, \
"Display all VM output on the tty, independently of LogVMOutput") \
\
diagnostic(bool, LogVMOutput, false, \
"Save VM output to LogFile") \
\
diagnostic(ccstr, LogFile, NULL, \
"If LogVMOutput or LogCompilation is on, save VM output to " \
"this file [default: ./hotspot_pid%p.log] (%p replaced with pid)")\
\
product(ccstr, ErrorFile, NULL, \
"If an error occurs, save the error data to this file " \
"[default: ./hs_err_pid%p.log] (%p replaced with pid)") \
\
product(bool, DisplayVMOutputToStderr, false, \
"If DisplayVMOutput is true, display all VM output to stderr") \
\
product(bool, DisplayVMOutputToStdout, false, \
"If DisplayVMOutput is true, display all VM output to stdout") \
\
product(bool, ErrorFileToStderr, false, \
"If true, error data is printed to stderr instead of a file") \
\
product(bool, ErrorFileToStdout, false, \
"If true, error data is printed to stdout instead of a file") \
\
product(bool, UseHeavyMonitors, false, \
"use heavyweight instead of lightweight Java monitors") \
\
product(bool, PrintStringTableStatistics, false, \
"print statistics about the StringTable and SymbolTable") \
\
diagnostic(bool, VerifyStringTableAtExit, false, \
"verify StringTable contents at exit") \
\
notproduct(bool, PrintSymbolTableSizeHistogram, false, \
"print histogram of the symbol table") \
\
notproduct(bool, ExitVMOnVerifyError, false, \
"standard exit from VM if bytecode verify error " \
"(only in debug mode)") \
\
notproduct(ccstr, AbortVMOnException, NULL, \
"Call fatal if this exception is thrown. Example: " \
"java -XX:AbortVMOnException=java.lang.NullPointerException Foo") \
\
notproduct(ccstr, AbortVMOnExceptionMessage, NULL, \
"Call fatal if the exception pointed by AbortVMOnException " \
"has this message") \
\
develop(bool, DebugVtables, false, \
"add debugging code to vtable dispatch") \
\
develop(bool, PrintVtables, false, \
"print vtables when printing klass") \
\
notproduct(bool, PrintVtableStats, false, \
"print vtables stats at end of run") \
\
develop(bool, TraceCreateZombies, false, \
"trace creation of zombie nmethods") \
\
notproduct(bool, IgnoreLockingAssertions, false, \
"disable locking assertions (for speed)") \
\
product(bool, RangeCheckElimination, true, \
"Eliminate range checks") \
\
develop_pd(bool, UncommonNullCast, \
"track occurrences of null in casts; adjust compiler tactics") \
\
develop(bool, TypeProfileCasts, true, \
"treat casts like calls for purposes of type profiling") \
\
develop(bool, DelayCompilationDuringStartup, true, \
"Delay invoking the compiler until main application class is " \
"loaded") \
\
develop(bool, CompileTheWorld, false, \
"Compile all methods in all classes in bootstrap class path " \
"(stress test)") \
\
develop(bool, CompileTheWorldPreloadClasses, true, \
"Preload all classes used by a class before start loading") \
\
notproduct(intx, CompileTheWorldSafepointInterval, 100, \
"Force a safepoint every n compiles so sweeper can keep up") \
\
develop(bool, FillDelaySlots, true, \
"Fill delay slots (on SPARC only)") \
\
develop(bool, TimeLivenessAnalysis, false, \
"Time computation of bytecode liveness analysis") \
\
develop(bool, TraceLivenessGen, false, \
"Trace the generation of liveness analysis information") \
\
notproduct(bool, TraceLivenessQuery, false, \
"Trace queries of liveness analysis information") \
\
notproduct(bool, CollectIndexSetStatistics, false, \
"Collect information about IndexSets") \
\
develop(bool, UseLoopSafepoints, true, \
"Generate Safepoint nodes in every loop") \
\
develop(intx, FastAllocateSizeLimit, 128*K, \
"Inline allocations larger than this in doublewords must go slow")\
\
product(bool, AggressiveOpts, false, \
"Enable aggressive optimizations - see arguments.cpp") \
\
product_pd(uintx, TypeProfileLevel, \
"=XYZ, with Z: Type profiling of arguments at call; " \
"Y: Type profiling of return value at call; " \
"X: Type profiling of parameters to methods; " \
"X, Y and Z in 0=off ; 1=jsr292 only; 2=all methods") \
\
product(intx, TypeProfileArgsLimit, 2, \
"max number of call arguments to consider for type profiling") \
\
product(intx, TypeProfileParmsLimit, 2, \
"max number of incoming parameters to consider for type profiling"\
", -1 for all") \
\
develop(bool, CountCompiledCalls, false, \
"Count method invocations") \
\
notproduct(bool, CountRuntimeCalls, false, \
"Count VM runtime calls") \
\
develop(bool, CountJNICalls, false, \
"Count jni method invocations") \
\
notproduct(bool, CountJVMCalls, false, \
"Count jvm method invocations") \
\
notproduct(bool, CountRemovableExceptions, false, \
"Count exceptions that could be replaced by branches due to " \
"inlining") \
\
notproduct(bool, ICMissHistogram, false, \
"Produce histogram of IC misses") \
\
notproduct(bool, PrintClassStatistics, false, \
"Print class statistics at end of run") \
\
notproduct(bool, PrintMethodStatistics, false, \
"Print method statistics at end of run") \
\
develop(bool, ClearInterpreterLocals, false, \
"Always clear local variables of interpreter activations upon " \
"entry") \
\
product_pd(bool, RewriteBytecodes, \
"Allow rewriting of bytecodes (bytecodes are not immutable)") \
\
product_pd(bool, RewriteFrequentPairs, \
"Rewrite frequently used bytecode pairs into a single bytecode") \
\
diagnostic(bool, PrintInterpreter, false, \
"Print the generated interpreter code") \
\
product(bool, UseInterpreter, true, \
"Use interpreter for non-compiled methods") \
\
develop(bool, UseFastSignatureHandlers, true, \
"Use fast signature handlers for native calls") \
\
product(bool, UseLoopCounter, true, \
"Increment invocation counter on backward branch") \
\
product(bool, UseFastEmptyMethods, true, \
"Use fast method entry code for empty methods") \
\
product(bool, UseFastAccessorMethods, true, \
"Use fast method entry code for accessor methods") \
\
product_pd(bool, UseOnStackReplacement, \
"Use on stack replacement, calls runtime if invoc. counter " \
"overflows in loop") \
\
notproduct(bool, TraceOnStackReplacement, false, \
"Trace on stack replacement") \
\
product_pd(bool, PreferInterpreterNativeStubs, \
"Use always interpreter stubs for native methods invoked via " \
"interpreter") \
\
develop(bool, CountBytecodes, false, \
"Count number of bytecodes executed") \
\
develop(bool, PrintBytecodeHistogram, false, \
"Print histogram of the executed bytecodes") \
\
develop(bool, PrintBytecodePairHistogram, false, \
"Print histogram of the executed bytecode pairs") \
\
diagnostic(bool, PrintSignatureHandlers, false, \
"Print code generated for native method signature handlers") \
\
develop(bool, VerifyOops, false, \
"Do plausibility checks for oops") \
\
develop(bool, CheckUnhandledOops, false, \
"Check for unhandled oops in VM code") \
\
develop(bool, VerifyJNIFields, trueInDebug, \
"Verify jfieldIDs for instance fields") \
\
notproduct(bool, VerifyJNIEnvThread, false, \
"Verify JNIEnv.thread == Thread::current() when entering VM " \
"from JNI") \
\
develop(bool, VerifyFPU, false, \
"Verify FPU state (check for NaN's, etc.)") \
\
develop(bool, VerifyThread, false, \
"Watch the thread register for corruption (SPARC only)") \
\
develop(bool, VerifyActivationFrameSize, false, \
"Verify that activation frame didn't become smaller than its " \
"minimal size") \
\
develop(bool, TraceFrequencyInlining, false, \
"Trace frequency based inlining") \
\
develop_pd(bool, InlineIntrinsics, \
"Inline intrinsics that can be statically resolved") \
\
product_pd(bool, ProfileInterpreter, \
"Profile at the bytecode level during interpretation") \
\
develop(bool, TraceProfileInterpreter, false, \
"Trace profiling at the bytecode level during interpretation. " \
"This outputs the profiling information collected to improve " \
"jit compilation.") \
\
develop_pd(bool, ProfileTraps, \
"Profile deoptimization traps at the bytecode level") \
\
product(intx, ProfileMaturityPercentage, 20, \
"number of method invocations/branches (expressed as % of " \
"CompileThreshold) before using the method's profile") \
\
develop(bool, PrintMethodData, false, \
"Print the results of +ProfileInterpreter at end of run") \
\
develop(bool, VerifyDataPointer, trueInDebug, \
"Verify the method data pointer during interpreter profiling") \
\
develop(bool, VerifyCompiledCode, false, \
"Include miscellaneous runtime verifications in nmethod code; " \
"default off because it disturbs nmethod size heuristics") \
\
notproduct(bool, CrashGCForDumpingJavaThread, false, \
"Manually make GC thread crash then dump java stack trace; " \
"Test only") \
\
product(bool, UseCompiler, true, \
"Use Just-In-Time compilation") \
\
develop(bool, TraceCompilationPolicy, false, \
"Trace compilation policy") \
\
develop(bool, TimeCompilationPolicy, false, \
"Time the compilation policy") \
\
product(bool, UseCounterDecay, true, \
"Adjust recompilation counters") \
\
develop(intx, CounterHalfLifeTime, 30, \
"Half-life time of invocation counters (in seconds)") \
\
develop(intx, CounterDecayMinIntervalLength, 500, \
"The minimum interval (in milliseconds) between invocation of " \
"CounterDecay") \
\
product(bool, AlwaysCompileLoopMethods, false, \
"When using recompilation, never interpret methods " \
"containing loops") \
\
product(bool, DontCompileHugeMethods, true, \
"Do not compile methods > HugeMethodLimit") \
\
product(bool, EstimateArgEscape, true, \
"Analyze bytecodes to estimate escape state of arguments") \
\
product(intx, BCEATraceLevel, 0, \
"How much tracing to do of bytecode escape analysis estimates") \
\
product(intx, MaxBCEAEstimateLevel, 5, \
"Maximum number of nested calls that are analyzed by BC EA") \
\
product(intx, MaxBCEAEstimateSize, 150, \
"Maximum bytecode size of a method to be analyzed by BC EA") \
\
product(intx, AllocatePrefetchStyle, 1, \
"0 = no prefetch, " \
"1 = prefetch instructions for each allocation, " \
"2 = use TLAB watermark to gate allocation prefetch, " \
"3 = use BIS instruction on Sparc for allocation prefetch") \
\
product(intx, AllocatePrefetchDistance, -1, \
"Distance to prefetch ahead of allocation pointer") \
\
product(intx, AllocatePrefetchLines, 3, \
"Number of lines to prefetch ahead of array allocation pointer") \
\
product(intx, AllocateInstancePrefetchLines, 1, \
"Number of lines to prefetch ahead of instance allocation " \
"pointer") \
\
product(intx, AllocatePrefetchStepSize, 16, \
"Step size in bytes of sequential prefetch instructions") \
\
product(intx, AllocatePrefetchInstr, 0, \
"Prefetch instruction to prefetch ahead of allocation pointer") \
\
develop(bool, TraceDeoptimization, false, \
"Trace deoptimization") \
\
develop(bool, DebugDeoptimization, false, \
"Tracing various information while debugging deoptimization") \
\
product(intx, SelfDestructTimer, 0, \
"Will cause VM to terminate after a given time (in minutes) " \
"(0 means off)") \
\
product(intx, MaxJavaStackTraceDepth, 1024, \
"The maximum number of lines in the stack trace for Java " \
"exceptions (0 means all)") \
\
NOT_EMBEDDED(diagnostic(intx, GuaranteedSafepointInterval, 1000, \
"Guarantee a safepoint (at least) every so many milliseconds " \
"(0 means none)")) \
\
EMBEDDED_ONLY(product(intx, GuaranteedSafepointInterval, 0, \
"Guarantee a safepoint (at least) every so many milliseconds " \
"(0 means none)")) \
\
product(intx, SafepointTimeoutDelay, 10000, \
"Delay in milliseconds for option SafepointTimeout") \
\
product(intx, NmethodSweepFraction, 16, \
"Number of invocations of sweeper to cover all nmethods") \
\
product(intx, NmethodSweepCheckInterval, 5, \
"Compilers wake up every n seconds to possibly sweep nmethods") \
\
product(intx, NmethodSweepActivity, 10, \
"Removes cold nmethods from code cache if > 0. Higher values " \
"result in more aggressive sweeping") \
\
notproduct(bool, LogSweeper, false, \
"Keep a ring buffer of sweeper activity") \
\
notproduct(intx, SweeperLogEntries, 1024, \
"Number of records in the ring buffer of sweeper activity") \
\
notproduct(intx, MemProfilingInterval, 500, \
"Time between each invocation of the MemProfiler") \
\
develop(intx, MallocCatchPtr, -1, \
"Hit breakpoint when mallocing/freeing this pointer") \
\
notproduct(intx, AssertRepeat, 1, \
"number of times to evaluate expression in assert " \
"(to estimate overhead); only works with -DUSE_REPEATED_ASSERTS") \
\
notproduct(ccstrlist, SuppressErrorAt, "", \
"List of assertions (file:line) to muzzle") \
\
notproduct(uintx, HandleAllocationLimit, 1024, \
"Threshold for HandleMark allocation when +TraceHandleAllocation "\
"is used") \
\
develop(uintx, TotalHandleAllocationLimit, 1024, \
"Threshold for total handle allocation when " \
"+TraceHandleAllocation is used") \
\
develop(intx, StackPrintLimit, 100, \
"number of stack frames to print in VM-level stack dump") \
\
notproduct(intx, MaxElementPrintSize, 256, \
"maximum number of elements to print") \
\
notproduct(intx, MaxSubklassPrintSize, 4, \
"maximum number of subklasses to print when printing klass") \
\
product(intx, MaxInlineLevel, 9, \
"maximum number of nested calls that are inlined") \
\
product(intx, MaxRecursiveInlineLevel, 1, \
"maximum number of nested recursive calls that are inlined") \
\
develop(intx, MaxForceInlineLevel, 100, \
"maximum number of nested calls that are forced for inlining " \
"(using CompilerOracle or marked w/ @ForceInline)") \
\
product_pd(intx, InlineSmallCode, \
"Only inline already compiled methods if their code size is " \
"less than this") \
\
product(intx, MaxInlineSize, 35, \
"The maximum bytecode size of a method to be inlined") \
\
product_pd(intx, FreqInlineSize, \
"The maximum bytecode size of a frequent method to be inlined") \
\
product(intx, MaxTrivialSize, 6, \
"The maximum bytecode size of a trivial method to be inlined") \
\
product(intx, MinInliningThreshold, 250, \
"The minimum invocation count a method needs to have to be " \
"inlined") \
\
develop(intx, MethodHistogramCutoff, 100, \
"The cutoff value for method invocation histogram (+CountCalls)") \
\
develop(intx, ProfilerNumberOfInterpretedMethods, 25, \
"Number of interpreted methods to show in profile") \
\
develop(intx, ProfilerNumberOfCompiledMethods, 25, \
"Number of compiled methods to show in profile") \
\
develop(intx, ProfilerNumberOfStubMethods, 25, \
"Number of stub methods to show in profile") \
\
develop(intx, ProfilerNumberOfRuntimeStubNodes, 25, \
"Number of runtime stub nodes to show in profile") \
\
product(intx, ProfileIntervalsTicks, 100, \
"Number of ticks between printing of interval profile " \
"(+ProfileIntervals)") \
\
notproduct(intx, ScavengeALotInterval, 1, \
"Interval between which scavenge will occur with +ScavengeALot") \
\
notproduct(intx, FullGCALotInterval, 1, \
"Interval between which full gc will occur with +FullGCALot") \
\
notproduct(intx, FullGCALotStart, 0, \
"For which invocation to start FullGCAlot") \
\
notproduct(intx, FullGCALotDummies, 32*K, \
"Dummy object allocated with +FullGCALot, forcing all objects " \
"to move") \
\
develop(intx, DontYieldALotInterval, 10, \
"Interval between which yields will be dropped (milliseconds)") \
\
develop(intx, MinSleepInterval, 1, \
"Minimum sleep() interval (milliseconds) when " \
"ConvertSleepToYield is off (used for Solaris)") \
\
develop(intx, ProfilerPCTickThreshold, 15, \
"Number of ticks in a PC buckets to be a hotspot") \
\
notproduct(intx, DeoptimizeALotInterval, 5, \
"Number of exits until DeoptimizeALot kicks in") \
\
notproduct(intx, ZombieALotInterval, 5, \
"Number of exits until ZombieALot kicks in") \
\
diagnostic(intx, MallocVerifyInterval, 0, \
"If non-zero, verify C heap after every N calls to " \
"malloc/realloc/free") \
\
diagnostic(intx, MallocVerifyStart, 0, \
"If non-zero, start verifying C heap after Nth call to " \
"malloc/realloc/free") \
\
diagnostic(uintx, MallocMaxTestWords, 0, \
"If non-zero, maximum number of words that malloc/realloc can " \
"allocate (for testing only)") \
\
product(intx, TypeProfileWidth, 2, \
"Number of receiver types to record in call/cast profile") \
\
develop(intx, BciProfileWidth, 2, \
"Number of return bci's to record in ret profile") \
\
product(intx, PerMethodRecompilationCutoff, 400, \
"After recompiling N times, stay in the interpreter (-1=>'Inf')") \
\
product(intx, PerBytecodeRecompilationCutoff, 200, \
"Per-BCI limit on repeated recompilation (-1=>'Inf')") \
\
product(intx, PerMethodTrapLimit, 100, \
"Limit on traps (of one kind) in a method (includes inlines)") \
\
experimental(intx, PerMethodSpecTrapLimit, 5000, \
"Limit on speculative traps (of one kind) in a method (includes inlines)") \
\
product(intx, PerBytecodeTrapLimit, 4, \
"Limit on traps (of one kind) at a particular BCI") \
\
experimental(intx, SpecTrapLimitExtraEntries, 3, \
"Extra method data trap entries for speculation") \
\
develop(intx, InlineFrequencyRatio, 20, \
"Ratio of call site execution to caller method invocation") \
\
develop_pd(intx, InlineFrequencyCount, \
"Count of call site execution necessary to trigger frequent " \
"inlining") \
\
develop(intx, InlineThrowCount, 50, \
"Force inlining of interpreted methods that throw this often") \
\
develop(intx, InlineThrowMaxSize, 200, \
"Force inlining of throwing methods smaller than this") \
\
develop(intx, ProfilerNodeSize, 1024, \
"Size in K to allocate for the Profile Nodes of each thread") \
\
product_pd(intx, PreInflateSpin, \
"Number of times to spin wait before inflation") \
\
product(uintx, InitialHeapSize, 0, \
"Initial heap size (in bytes); zero means use ergonomics") \
\
product(uintx, MaxHeapSize, ScaleForWordSize(96*M), \
"Maximum heap size (in bytes)") \
\
product(uintx, OldSize, ScaleForWordSize(4*M), \
"Initial tenured generation size (in bytes)") \
\
product(uintx, NewSize, ScaleForWordSize(1*M), \
"Initial new generation size (in bytes)") \
\
product(uintx, MaxNewSize, max_uintx, \
"Maximum new generation size (in bytes), max_uintx means set " \
"ergonomically") \
\
product(uintx, PretenureSizeThreshold, 0, \
"Maximum size in bytes of objects allocated in DefNew " \
"generation; zero means no maximum") \
\
product(uintx, TLABSize, 0, \
"Starting TLAB size (in bytes); zero means set ergonomically") \
\
product(uintx, MinTLABSize, 2*K, \
"Minimum allowed TLAB size (in bytes)") \
\
product(uintx, TLABAllocationWeight, 35, \
"Allocation averaging weight") \
\
product(uintx, TLABWasteTargetPercent, 1, \
"Percentage of Eden that can be wasted") \
\
product(uintx, TLABRefillWasteFraction, 64, \
"Maximum TLAB waste at a refill (internal fragmentation)") \
\
product(uintx, TLABWasteIncrement, 4, \
"Increment allowed waste at slow allocation") \
\
product(uintx, SurvivorRatio, 8, \
"Ratio of eden/survivor space size") \
\
product(uintx, NewRatio, 2, \
"Ratio of old/new generation sizes") \
\
product_pd(uintx, NewSizeThreadIncrease, \
"Additional size added to desired new generation size per " \
"non-daemon thread (in bytes)") \
\
product_pd(uintx, MetaspaceSize, \
"Initial size of Metaspaces (in bytes)") \
\
product(uintx, MaxMetaspaceSize, max_uintx, \
"Maximum size of Metaspaces (in bytes)") \
\
product(uintx, CompressedClassSpaceSize, 1*G, \
"Maximum size of class area in Metaspace when compressed " \
"class pointers are used") \
\
manageable(uintx, MinHeapFreeRatio, 40, \
"The minimum percentage of heap free after GC to avoid expansion."\
" For most GCs this applies to the old generation. In G1 and" \
" ParallelGC it applies to the whole heap.") \
\
manageable(uintx, MaxHeapFreeRatio, 70, \
"The maximum percentage of heap free after GC to avoid shrinking."\
" For most GCs this applies to the old generation. In G1 and" \
" ParallelGC it applies to the whole heap.") \
\
product(intx, SoftRefLRUPolicyMSPerMB, 1000, \
"Number of milliseconds per MB of free space in the heap") \
\
product(uintx, MinHeapDeltaBytes, ScaleForWordSize(128*K), \
"The minimum change in heap space due to GC (in bytes)") \
\
product(uintx, MinMetaspaceExpansion, ScaleForWordSize(256*K), \
"The minimum expansion of Metaspace (in bytes)") \
\
product(uintx, MinMetaspaceFreeRatio, 40, \
"The minimum percentage of Metaspace free after GC to avoid " \
"expansion") \
\
product(uintx, MaxMetaspaceFreeRatio, 70, \
"The maximum percentage of Metaspace free after GC to avoid " \
"shrinking") \
\
product(uintx, MaxMetaspaceExpansion, ScaleForWordSize(4*M), \
"The maximum expansion of Metaspace without full GC (in bytes)") \
\
product(uintx, QueuedAllocationWarningCount, 0, \
"Number of times an allocation that queues behind a GC " \
"will retry before printing a warning") \
\
diagnostic(uintx, VerifyGCStartAt, 0, \
"GC invoke count where +VerifyBefore/AfterGC kicks in") \
\
diagnostic(intx, VerifyGCLevel, 0, \
"Generation level at which to start +VerifyBefore/AfterGC") \
\
product(uintx, MaxTenuringThreshold, 15, \
"Maximum value for tenuring threshold") \
\
product(uintx, InitialTenuringThreshold, 7, \
"Initial value for tenuring threshold") \
\
product(uintx, TargetSurvivorRatio, 50, \
"Desired percentage of survivor space used after scavenge") \
\
product(uintx, MarkSweepDeadRatio, 5, \
"Percentage (0-100) of the old gen allowed as dead wood. " \
"Serial mark sweep treats this as both the minimum and maximum " \
"value. " \
"CMS uses this value only if it falls back to mark sweep. " \
"Par compact uses a variable scale based on the density of the " \
"generation and treats this as the maximum value when the heap " \
"is either completely full or completely empty. Par compact " \
"also has a smaller default value; see arguments.cpp.") \
\
product(uintx, MarkSweepAlwaysCompactCount, 4, \
"How often should we fully compact the heap (ignoring the dead " \
"space parameters)") \
\
product(intx, PrintCMSStatistics, 0, \
"Statistics for CMS") \
\
product(bool, PrintCMSInitiationStatistics, false, \
"Statistics for initiating a CMS collection") \
\
product(intx, PrintFLSStatistics, 0, \
"Statistics for CMS' FreeListSpace") \
\
product(intx, PrintFLSCensus, 0, \
"Census for CMS' FreeListSpace") \
\
develop(uintx, GCExpandToAllocateDelayMillis, 0, \
"Delay between expansion and allocation (in milliseconds)") \
\
develop(uintx, GCWorkerDelayMillis, 0, \
"Delay in scheduling GC workers (in milliseconds)") \
\
product(intx, DeferThrSuspendLoopCount, 4000, \
"(Unstable) Number of times to iterate in safepoint loop " \
"before blocking VM threads ") \
\
product(intx, DeferPollingPageLoopCount, -1, \
"(Unsafe,Unstable) Number of iterations in safepoint loop " \
"before changing safepoint polling page to RO ") \
\
product(intx, SafepointSpinBeforeYield, 2000, "(Unstable)") \
\
product(bool, PSChunkLargeArrays, true, \
"Process large arrays in chunks") \
\
product(uintx, GCDrainStackTargetSize, 64, \
"Number of entries we will try to leave on the stack " \
"during parallel gc") \
\
product_pd(intx, StackYellowPages, \
"Number of yellow zone (recoverable overflows) pages") \
\
product_pd(intx, StackRedPages, \
"Number of red zone (unrecoverable overflows) pages") \
\
product_pd(intx, StackShadowPages, \
"Number of shadow zone (for overflow checking) pages " \
"this should exceed the depth of the VM and native call stack") \
\
product_pd(intx, ThreadStackSize, \
"Thread Stack Size (in Kbytes)") \
\
product_pd(intx, VMThreadStackSize, \
"Non-Java Thread Stack Size (in Kbytes)") \
\
product_pd(intx, CompilerThreadStackSize, \
"Compiler Thread Stack Size (in Kbytes)") \
\
develop_pd(uintx, JVMInvokeMethodSlack, \
"Stack space (bytes) required for JVM_InvokeMethod to complete") \
\
product(uintx, ThreadSafetyMargin, 50*M, \
"Thread safety margin is used on fixed-stack LinuxThreads (on " \
"Linux/x86 only) to prevent heap-stack collision. Set to 0 to " \
"disable this feature") \
\
develop(uintx, CodeCacheSegmentSize, 64 PPC64_ONLY(+64), \
"Code cache segment size (in bytes) - smallest unit of " \
"allocation") \
\
develop_pd(intx, CodeEntryAlignment, \
"Code entry alignment for generated code (in bytes)") \
\
product_pd(intx, OptoLoopAlignment, \
"Align inner loops to zero relative to this modulus") \
\
product_pd(uintx, InitialCodeCacheSize, \
"Initial code cache size (in bytes)") \
\
develop_pd(uintx, CodeCacheMinimumUseSpace, \
"Minimum code cache size (in bytes) required to start VM.") \
\
product_pd(uintx, ReservedCodeCacheSize, \
"Reserved code cache size (in bytes) - maximum code cache size") \
\
product(uintx, CodeCacheMinimumFreeSpace, 500*K, \
"When less than X space left, we stop compiling") \
\
product_pd(uintx, CodeCacheExpansionSize, \
"Code cache expansion size (in bytes)") \
\
develop_pd(uintx, CodeCacheMinBlockLength, \
"Minimum number of segments in a code cache block") \
\
notproduct(bool, ExitOnFullCodeCache, false, \
"Exit the VM if we fill the code cache") \
\
product(bool, UseCodeCacheFlushing, true, \
"Remove cold/old nmethods from the code cache") \
\
develop(intx, BinarySwitchThreshold, 5, \
"Minimal number of lookupswitch entries for rewriting to binary " \
"switch") \
\
develop(intx, StopInterpreterAt, 0, \
"Stop interpreter execution at specified bytecode number") \
\
develop(intx, TraceBytecodesAt, 0, \
"Trace bytecodes starting with specified bytecode number") \
\
develop(intx, CIStart, 0, \
"The id of the first compilation to permit") \
\
develop(intx, CIStop, max_jint, \
"The id of the last compilation to permit") \
\
develop(intx, CIStartOSR, 0, \
"The id of the first osr compilation to permit " \
"(CICountOSR must be on)") \
\
develop(intx, CIStopOSR, max_jint, \
"The id of the last osr compilation to permit " \
"(CICountOSR must be on)") \
\
develop(intx, CIBreakAtOSR, -1, \
"The id of osr compilation to break at") \
\
develop(intx, CIBreakAt, -1, \
"The id of compilation to break at") \
\
product(ccstrlist, CompileOnly, "", \
"List of methods (pkg/class.name) to restrict compilation to") \
\
product(ccstr, CompileCommandFile, NULL, \
"Read compiler commands from this file [.hotspot_compiler]") \
\
product(ccstrlist, CompileCommand, "", \
"Prepend to .hotspot_compiler; e.g. log,java/lang/String.<init>") \
\
develop(bool, ReplayCompiles, false, \
"Enable replay of compilations from ReplayDataFile") \
\
product(ccstr, ReplayDataFile, NULL, \
"File containing compilation replay information" \
"[default: ./replay_pid%p.log] (%p replaced with pid)") \
\
product(ccstr, InlineDataFile, NULL, \
"File containing inlining replay information" \
"[default: ./inline_pid%p.log] (%p replaced with pid)") \
\
develop(intx, ReplaySuppressInitializers, 2, \
"Control handling of class initialization during replay: " \
"0 - don't do anything special; " \
"1 - treat all class initializers as empty; " \
"2 - treat class initializers for application classes as empty; " \
"3 - allow all class initializers to run during bootstrap but " \
" pretend they are empty after starting replay") \
\
develop(bool, ReplayIgnoreInitErrors, false, \
"Ignore exceptions thrown during initialization for replay") \
\
product(bool, DumpReplayDataOnError, true, \
"Record replay data for crashing compiler threads") \
\
product(bool, CICompilerCountPerCPU, false, \
"1 compiler thread for log(N CPUs)") \
\
develop(intx, CIFireOOMAt, -1, \
"Fire OutOfMemoryErrors throughout CI for testing the compiler " \
"(non-negative value throws OOM after this many CI accesses " \
"in each compile)") \
notproduct(intx, CICrashAt, -1, \
"id of compilation to trigger assert in compiler thread for " \
"the purpose of testing, e.g. generation of replay data") \
notproduct(bool, CIObjectFactoryVerify, false, \
"enable potentially expensive verification in ciObjectFactory") \
\
diagnostic(bool, AbortVMOnCompilationFailure, false, \
"Abort VM when method had failed to compile.") \
\
product_pd(bool, UseThreadPriorities, "Use native thread priorities") \
\
product(intx, ThreadPriorityPolicy, 0, \
"0 : Normal. "\
" VM chooses priorities that are appropriate for normal "\
" applications. On Solaris NORM_PRIORITY and above are mapped "\
" to normal native priority. Java priorities below " \
" NORM_PRIORITY map to lower native priority values. On "\
" Windows applications are allowed to use higher native "\
" priorities. However, with ThreadPriorityPolicy=0, VM will "\
" not use the highest possible native priority, "\
" THREAD_PRIORITY_TIME_CRITICAL, as it may interfere with "\
" system threads. On Linux thread priorities are ignored "\
" because the OS does not support static priority in "\
" SCHED_OTHER scheduling class which is the only choice for "\
" non-root, non-realtime applications. "\
"1 : Aggressive. "\
" Java thread priorities map over to the entire range of "\
" native thread priorities. Higher Java thread priorities map "\
" to higher native thread priorities. This policy should be "\
" used with care, as sometimes it can cause performance "\
" degradation in the application and/or the entire system. On "\
" Linux this policy requires root privilege.") \
\
product(bool, ThreadPriorityVerbose, false, \
"Print priority changes") \
\
product(intx, DefaultThreadPriority, -1, \
"The native priority at which threads run if not elsewhere " \
"specified (-1 means no change)") \
\
product(intx, CompilerThreadPriority, -1, \
"The native priority at which compiler threads should run " \
"(-1 means no change)") \
\
product(intx, VMThreadPriority, -1, \
"The native priority at which the VM thread should run " \
"(-1 means no change)") \
\
product(bool, CompilerThreadHintNoPreempt, true, \
"(Solaris only) Give compiler threads an extra quanta") \
\
product(bool, VMThreadHintNoPreempt, false, \
"(Solaris only) Give VM thread an extra quanta") \
\
product(intx, JavaPriority1_To_OSPriority, -1, \
"Map Java priorities to OS priorities") \
\
product(intx, JavaPriority2_To_OSPriority, -1, \
"Map Java priorities to OS priorities") \
\
product(intx, JavaPriority3_To_OSPriority, -1, \
"Map Java priorities to OS priorities") \
\
product(intx, JavaPriority4_To_OSPriority, -1, \
"Map Java priorities to OS priorities") \
\
product(intx, JavaPriority5_To_OSPriority, -1, \
"Map Java priorities to OS priorities") \
\
product(intx, JavaPriority6_To_OSPriority, -1, \
"Map Java priorities to OS priorities") \
\
product(intx, JavaPriority7_To_OSPriority, -1, \
"Map Java priorities to OS priorities") \
\
product(intx, JavaPriority8_To_OSPriority, -1, \
"Map Java priorities to OS priorities") \
\
product(intx, JavaPriority9_To_OSPriority, -1, \
"Map Java priorities to OS priorities") \
\
product(intx, JavaPriority10_To_OSPriority,-1, \
"Map Java priorities to OS priorities") \
\
experimental(bool, UseCriticalJavaThreadPriority, false, \
"Java thread priority 10 maps to critical scheduling priority") \
\
experimental(bool, UseCriticalCompilerThreadPriority, false, \
"Compiler thread(s) run at critical scheduling priority") \
\
experimental(bool, UseCriticalCMSThreadPriority, false, \
"ConcurrentMarkSweep thread runs at critical scheduling priority")\
\
notproduct(intx, CompileTheWorldStartAt, 1, \
"First class to consider when using +CompileTheWorld") \
\
notproduct(intx, CompileTheWorldStopAt, max_jint, \
"Last class to consider when using +CompileTheWorld") \
\
develop(intx, NewCodeParameter, 0, \
"Testing Only: Create a dedicated integer parameter before " \
"putback") \
\
develop(intx, MinOopMapAllocation, 8, \
"Minimum number of OopMap entries in an OopMapSet") \
\
develop(intx, LongCompileThreshold, 50, \
"Used with +TraceLongCompiles") \
\
product(intx, StarvationMonitorInterval, 200, \
"Pause between each check (in milliseconds)") \
\
product_pd(intx, CompileThreshold, \
"number of interpreted method invocations before (re-)compiling") \
\
product_pd(intx, BackEdgeThreshold, \
"Interpreter Back edge threshold at which an OSR compilation is " \
"invoked") \
\
product(intx, Tier0InvokeNotifyFreqLog, 7, \
"Interpreter (tier 0) invocation notification frequency") \
\
product(intx, Tier2InvokeNotifyFreqLog, 11, \
"C1 without MDO (tier 2) invocation notification frequency") \
\
product(intx, Tier3InvokeNotifyFreqLog, 10, \
"C1 with MDO profiling (tier 3) invocation notification " \
"frequency") \
\
product(intx, Tier23InlineeNotifyFreqLog, 20, \
"Inlinee invocation (tiers 2 and 3) notification frequency") \
\
product(intx, Tier0BackedgeNotifyFreqLog, 10, \
"Interpreter (tier 0) invocation notification frequency") \
\
product(intx, Tier2BackedgeNotifyFreqLog, 14, \
"C1 without MDO (tier 2) invocation notification frequency") \
\
product(intx, Tier3BackedgeNotifyFreqLog, 13, \
"C1 with MDO profiling (tier 3) invocation notification " \
"frequency") \
\
product(intx, Tier2CompileThreshold, 0, \
"threshold at which tier 2 compilation is invoked") \
\
product(intx, Tier2BackEdgeThreshold, 0, \
"Back edge threshold at which tier 2 compilation is invoked") \
\
product(intx, Tier3InvocationThreshold, 200, \
"Compile if number of method invocations crosses this " \
"threshold") \
\
product(intx, Tier3MinInvocationThreshold, 100, \
"Minimum invocation to compile at tier 3") \
\
product(intx, Tier3CompileThreshold, 2000, \
"Threshold at which tier 3 compilation is invoked (invocation " \
"minimum must be satisfied") \
\
product(intx, Tier3BackEdgeThreshold, 60000, \
"Back edge threshold at which tier 3 OSR compilation is invoked") \
\
product(intx, Tier4InvocationThreshold, 5000, \
"Compile if number of method invocations crosses this " \
"threshold") \
\
product(intx, Tier4MinInvocationThreshold, 600, \
"Minimum invocation to compile at tier 4") \
\
product(intx, Tier4CompileThreshold, 15000, \
"Threshold at which tier 4 compilation is invoked (invocation " \
"minimum must be satisfied") \
\
product(intx, Tier4BackEdgeThreshold, 40000, \
"Back edge threshold at which tier 4 OSR compilation is invoked") \
\
product(intx, Tier3DelayOn, 5, \
"If C2 queue size grows over this amount per compiler thread " \
"stop compiling at tier 3 and start compiling at tier 2") \
\
product(intx, Tier3DelayOff, 2, \
"If C2 queue size is less than this amount per compiler thread " \
"allow methods compiled at tier 2 transition to tier 3") \
\
product(intx, Tier3LoadFeedback, 5, \
"Tier 3 thresholds will increase twofold when C1 queue size " \
"reaches this amount per compiler thread") \
\
product(intx, Tier4LoadFeedback, 3, \
"Tier 4 thresholds will increase twofold when C2 queue size " \
"reaches this amount per compiler thread") \
\
product(intx, TieredCompileTaskTimeout, 50, \
"Kill compile task if method was not used within " \
"given timeout in milliseconds") \
\
product(intx, TieredStopAtLevel, 4, \
"Stop at given compilation level") \
\
product(intx, Tier0ProfilingStartPercentage, 200, \
"Start profiling in interpreter if the counters exceed tier 3 " \
"thresholds by the specified percentage") \
\
product(uintx, IncreaseFirstTierCompileThresholdAt, 50, \
"Increase the compile threshold for C1 compilation if the code " \
"cache is filled by the specified percentage") \
\
product(intx, TieredRateUpdateMinTime, 1, \
"Minimum rate sampling interval (in milliseconds)") \
\
product(intx, TieredRateUpdateMaxTime, 25, \
"Maximum rate sampling interval (in milliseconds)") \
\
product_pd(bool, TieredCompilation, \
"Enable tiered compilation") \
\
product(bool, PrintTieredEvents, false, \
"Print tiered events notifications") \
\
product_pd(intx, OnStackReplacePercentage, \
"NON_TIERED number of method invocations/branches (expressed as " \
"% of CompileThreshold) before (re-)compiling OSR code") \
\
product(intx, InterpreterProfilePercentage, 33, \
"NON_TIERED number of method invocations/branches (expressed as " \
"% of CompileThreshold) before profiling in the interpreter") \
\
develop(intx, MaxRecompilationSearchLength, 10, \
"The maximum number of frames to inspect when searching for " \
"recompilee") \
\
develop(intx, MaxInterpretedSearchLength, 3, \
"The maximum number of interpreted frames to skip when searching "\
"for recompilee") \
\
develop(intx, DesiredMethodLimit, 8000, \
"The desired maximum method size (in bytecodes) after inlining") \
\
develop(intx, HugeMethodLimit, 8000, \
"Don't compile methods larger than this if " \
"+DontCompileHugeMethods") \
\
\
develop(bool, UseNewReflection, true, \
"Temporary flag for transition to reflection based on dynamic " \
"bytecode generation in 1.4; can no longer be turned off in 1.4 " \
"JDK, and is unneeded in 1.3 JDK, but marks most places VM " \
"changes were needed") \
\
develop(bool, VerifyReflectionBytecodes, false, \
"Force verification of 1.4 reflection bytecodes. Does not work " \
"in situations like that described in 4486457 or for " \
"constructors generated for serialization, so can not be enabled "\
"in product.") \
\
product(bool, ReflectionWrapResolutionErrors, true, \
"Temporary flag for transition to AbstractMethodError wrapped " \
"in InvocationTargetException. See 6531596") \
\
develop(intx, FastSuperclassLimit, 8, \
"Depth of hardwired instanceof accelerator array") \
\
\
product(uintx, MaxDirectMemorySize, 0, \
"Maximum total size of NIO direct-buffer allocations") \
\
\
diagnostic(bool, UseNewCode, false, \
"Testing Only: Use the new version while testing") \
\
diagnostic(bool, UseNewCode2, false, \
"Testing Only: Use the new version while testing") \
\
diagnostic(bool, UseNewCode3, false, \
"Testing Only: Use the new version while testing") \
\
\
product(bool, UsePerfData, falseInEmbedded, \
"Flag to disable jvmstat instrumentation for performance testing "\
"and problem isolation purposes") \
\
product(bool, PerfDataSaveToFile, false, \
"Save PerfData memory to hsperfdata_<pid> file on exit") \
\
product(ccstr, PerfDataSaveFile, NULL, \
"Save PerfData memory to the specified absolute pathname. " \
"The string %p in the file name (if present) " \
"will be replaced by pid") \
\
product(intx, PerfDataSamplingInterval, 50, \
"Data sampling interval (in milliseconds)") \
\
develop(bool, PerfTraceDataCreation, false, \
"Trace creation of Performance Data Entries") \
\
develop(bool, PerfTraceMemOps, false, \
"Trace PerfMemory create/attach/detach calls") \
\
product(bool, PerfDisableSharedMem, false, \
"Store performance data in standard memory") \
\
product(intx, PerfDataMemorySize, 32*K, \
"Size of performance data memory region. Will be rounded " \
"up to a multiple of the native os page size.") \
\
product(intx, PerfMaxStringConstLength, 1024, \
"Maximum PerfStringConstant string length before truncation") \
\
product(bool, PerfAllowAtExitRegistration, false, \
"Allow registration of atexit() methods") \
\
product(bool, PerfBypassFileSystemCheck, false, \
"Bypass Win32 file system criteria checks (Windows Only)") \
\
product(intx, UnguardOnExecutionViolation, 0, \
"Unguard page and retry on no-execute fault (Win32 only) " \
"0=off, 1=conservative, 2=aggressive") \
\
\
product(bool, ManagementServer, false, \
"Create JMX Management Server") \
\
product(bool, DisableAttachMechanism, false, \
"Disable mechanism that allows tools to attach to this VM") \
\
product(bool, StartAttachListener, false, \
"Always start Attach Listener at VM startup") \
\
manageable(bool, PrintConcurrentLocks, false, \
"Print java.util.concurrent locks in thread dump") \
\
product(bool, TransmitErrorReport, false, \
"Enable error report transmission on erroneous termination") \
\
product(ccstr, ErrorReportServer, NULL, \
"Override built-in error report server address") \
\
\
product(bool, UseSharedSpaces, true, \
"Use shared spaces for metadata") \
\
product(bool, VerifySharedSpaces, false, \
"Verify shared spaces (false for default archive, true for " \
"archive specified by -XX:SharedArchiveFile)") \
\
product(bool, RequireSharedSpaces, false, \
"Require shared spaces for metadata") \
\
product(bool, DumpSharedSpaces, false, \
"Special mode: JVM reads a class list, loads classes, builds " \
"shared spaces, and dumps the shared spaces to a file to be " \
"used in future JVM runs") \
\
product(bool, PrintSharedSpaces, false, \
"Print usage of shared spaces") \
\
product(bool, PrintSharedArchiveAndExit, false, \
"Print shared archive file contents") \
\
product(bool, PrintSharedDictionary, false, \
"If PrintSharedArchiveAndExit is true, also print the shared " \
"dictionary") \
\
product(uintx, SharedReadWriteSize, NOT_LP64(12*M) LP64_ONLY(16*M), \
"Size of read-write space for metadata (in bytes)") \
\
product(uintx, SharedReadOnlySize, NOT_LP64(12*M) LP64_ONLY(16*M), \
"Size of read-only space for metadata (in bytes)") \
\
product(uintx, SharedMiscDataSize, NOT_LP64(2*M) LP64_ONLY(4*M), \
"Size of the shared miscellaneous data area (in bytes)") \
\
product(uintx, SharedMiscCodeSize, AARCH64_ONLY(192*K) NOT_AARCH64(120*K), \
"Size of the shared miscellaneous code area (in bytes)") \
\
product(uintx, SharedBaseAddress, LP64_ONLY(32*G) \
NOT_LP64(LINUX_ONLY(2*G) NOT_LINUX(0)), \
"Address to allocate shared memory region for class data") \
\
diagnostic(bool, EnableInvokeDynamic, true, \
"support JSR 292 (method handles, invokedynamic, " \
"anonymous classes") \
\
diagnostic(bool, IgnoreUnverifiableClassesDuringDump, false, \
"Do not quit -Xshare:dump even if we encounter unverifiable " \
"classes. Just exclude them from the shared dictionary.") \
\
diagnostic(bool, PrintMethodHandleStubs, false, \
"Print generated stub code for method handles") \
\
develop(bool, TraceMethodHandles, false, \
"trace internal method handle operations") \
\
diagnostic(bool, VerifyMethodHandles, trueInDebug, \
"perform extra checks when constructing method handles") \
\
diagnostic(bool, ShowHiddenFrames, false, \
"show method handle implementation frames (usually hidden)") \
\
experimental(bool, TrustFinalNonStaticFields, false, \
"trust final non-static declarations for constant folding") \
\
diagnostic(bool, FoldStableValues, true, \
"Optimize loads from stable fields (marked w/ @Stable)") \
\
develop(bool, TraceInvokeDynamic, false, \
"trace internal invoke dynamic operations") \
\
diagnostic(bool, PauseAtStartup, false, \
"Causes the VM to pause at startup time and wait for the pause " \
"file to be removed (default: ./vm.paused.<pid>)") \
\
diagnostic(ccstr, PauseAtStartupFile, NULL, \
"The file to create and for whose removal to await when pausing " \
"at startup. (default: ./vm.paused.<pid>)") \
\
diagnostic(bool, PauseAtExit, false, \
"Pause and wait for keypress on exit if a debugger is attached") \
\
product(bool, ExtendedDTraceProbes, false, \
"Enable performance-impacting dtrace probes") \
\
product(bool, DTraceMethodProbes, false, \
"Enable dtrace probes for method-entry and method-exit") \
\
product(bool, DTraceAllocProbes, false, \
"Enable dtrace probes for object allocation") \
\
product(bool, DTraceMonitorProbes, false, \
"Enable dtrace probes for monitor events") \
\
product(bool, RelaxAccessControlCheck, false, \
"Relax the access control checks in the verifier") \
\
diagnostic(bool, PrintDTraceDOF, false, \
"Print the DTrace DOF passed to the system for JSDT probes") \
\
product(uintx, StringTableSize, defaultStringTableSize, \
"Number of buckets in the interned String table") \
\
experimental(uintx, SymbolTableSize, defaultSymbolTableSize, \
"Number of buckets in the JVM internal Symbol table") \
\
product(bool, UseStringDeduplication, false, \
"Use string deduplication") \
\
product(bool, PrintStringDeduplicationStatistics, false, \
"Print string deduplication statistics") \
\
product(uintx, StringDeduplicationAgeThreshold, 3, \
"A string must reach this age (or be promoted to an old region) " \
"to be considered for deduplication") \
\
diagnostic(bool, StringDeduplicationResizeALot, false, \
"Force table resize every time the table is scanned") \
\
diagnostic(bool, StringDeduplicationRehashALot, false, \
"Force table rehash every time the table is scanned") \
\
develop(bool, TraceDefaultMethods, false, \
"Trace the default method processing steps") \
\
develop(bool, VerifyGenericSignatures, false, \
"Abort VM on erroneous or inconsistent generic signatures") \
\
product(bool, UseVMInterruptibleIO, false, \
"(Unstable, Solaris-specific) Thread interrupt before or with " \
"EINTR for I/O operations results in OS_INTRPT. The default " \
"value of this flag is true for JDK 6 and earlier") \
\
diagnostic(bool, WhiteBoxAPI, false, \
"Enable internal testing APIs") \
\
product(bool, PrintGCCause, true, \
"Include GC cause in GC logging") \
\
experimental(intx, SurvivorAlignmentInBytes, 0, \
"Default survivor space alignment in bytes") \
\
product(bool , AllowNonVirtualCalls, false, \
"Obey the ACC_SUPER flag and allow invokenonvirtual calls") \
\
product(ccstr, DumpLoadedClassList, NULL, \
"Dump the names all loaded classes, that could be stored into " \
"the CDS archive, in the specified file") \
\
product(ccstr, SharedClassListFile, NULL, \
"Override the default CDS class list") \
\
diagnostic(ccstr, SharedArchiveFile, NULL, \
"Override the default location of the CDS archive file") \
\
product(ccstr, ExtraSharedClassListFile, NULL, \
"Extra classlist for building the CDS archive file") \
\
experimental(uintx, ArrayAllocatorMallocLimit, \
SOLARIS_ONLY(64*K) NOT_SOLARIS(max_uintx), \
"Allocation less than this value will be allocated " \
"using malloc. Larger allocations will use mmap.") \
\
product_pd(bool, PreserveFramePointer, \
"Use the FP register for holding the frame pointer " \
"and not as a general purpose register.") \
\
product(bool, EnableTracing, false, \
"Enable event-based tracing" \
"Deprecated: use FlightRecorder instead") \
\
product(bool, UseLockedTracing, false, \
"Use locked-tracing when doing event-based tracing" \
"Deprecated: use FlightRecorder instead") \
\
JFR_ONLY(product(bool, FlightRecorder, false, \
"Enable Flight Recorder")) \
\
JFR_ONLY(product(ccstr, FlightRecorderOptions, NULL, \
"Flight Recorder options")) \
\
JFR_ONLY(product(ccstr, StartFlightRecording, NULL, \
"Start flight recording with options")) \
\
JFR_ONLY(product(bool, UnlockCommercialFeatures, false, \
"This flag is ignored. Left for compatibility")) \
\
experimental(bool, UseFastUnorderedTimeStamps, false, \
"Use platform unstable time where supported for timestamps only") \
\
JFR_ONLY(product(bool, LogJFR, false, \
"Enable JFR logging (consider +Verbose)")) \
#define DECLARE_PRODUCT_FLAG(type, name, value, doc) extern "C" type name;
#define DECLARE_PD_PRODUCT_FLAG(type, name, doc) extern "C" type name;
#define DECLARE_DIAGNOSTIC_FLAG(type, name, value, doc) extern "C" type name;
#define DECLARE_EXPERIMENTAL_FLAG(type, name, value, doc) extern "C" type name;
#define DECLARE_MANAGEABLE_FLAG(type, name, value, doc) extern "C" type name;
#define DECLARE_PRODUCT_RW_FLAG(type, name, value, doc) extern "C" type name;
#ifdef PRODUCT
#define DECLARE_DEVELOPER_FLAG(type, name, value, doc) extern "C" type CONST_##name; const type name = value;
#define DECLARE_PD_DEVELOPER_FLAG(type, name, doc) extern "C" type CONST_##name; const type name = pd_##name;
#define DECLARE_NOTPRODUCT_FLAG(type, name, value, doc) extern "C" type CONST_##name;
#else
#define DECLARE_DEVELOPER_FLAG(type, name, value, doc) extern "C" type name;
#define DECLARE_PD_DEVELOPER_FLAG(type, name, doc) extern "C" type name;
#define DECLARE_NOTPRODUCT_FLAG(type, name, value, doc) extern "C" type name;
#endif
#ifdef _LP64
#define DECLARE_LP64_PRODUCT_FLAG(type, name, value, doc) extern "C" type name;
#else
#define DECLARE_LP64_PRODUCT_FLAG(type, name, value, doc) const type name = value;
#endif // _LP64
#define MATERIALIZE_PRODUCT_FLAG(type, name, value, doc) type name = value;
#define MATERIALIZE_PD_PRODUCT_FLAG(type, name, doc) type name = pd_##name;
#define MATERIALIZE_DIAGNOSTIC_FLAG(type, name, value, doc) type name = value;
#define MATERIALIZE_EXPERIMENTAL_FLAG(type, name, value, doc) type name = value;
#define MATERIALIZE_MANAGEABLE_FLAG(type, name, value, doc) type name = value;
#define MATERIALIZE_PRODUCT_RW_FLAG(type, name, value, doc) type name = value;
#ifdef PRODUCT
#define MATERIALIZE_DEVELOPER_FLAG(type, name, value, doc) type CONST_##name = value;
#define MATERIALIZE_PD_DEVELOPER_FLAG(type, name, doc) type CONST_##name = pd_##name;
#define MATERIALIZE_NOTPRODUCT_FLAG(type, name, value, doc) type CONST_##name = value;
#else
#define MATERIALIZE_DEVELOPER_FLAG(type, name, value, doc) type name = value;
#define MATERIALIZE_PD_DEVELOPER_FLAG(type, name, doc) type name = pd_##name;
#define MATERIALIZE_NOTPRODUCT_FLAG(type, name, value, doc) type name = value;
#endif
#ifdef _LP64
#define MATERIALIZE_LP64_PRODUCT_FLAG(type, name, value, doc) type name = value;
#else
#define MATERIALIZE_LP64_PRODUCT_FLAG(type, name, value, doc) /* flag is constant */
#endif // _LP64
RUNTIME_FLAGS(DECLARE_DEVELOPER_FLAG, DECLARE_PD_DEVELOPER_FLAG, DECLARE_PRODUCT_FLAG, DECLARE_PD_PRODUCT_FLAG, DECLARE_DIAGNOSTIC_FLAG, DECLARE_EXPERIMENTAL_FLAG, DECLARE_NOTPRODUCT_FLAG, DECLARE_MANAGEABLE_FLAG, DECLARE_PRODUCT_RW_FLAG, DECLARE_LP64_PRODUCT_FLAG)
RUNTIME_OS_FLAGS(DECLARE_DEVELOPER_FLAG, DECLARE_PD_DEVELOPER_FLAG, DECLARE_PRODUCT_FLAG, DECLARE_PD_PRODUCT_FLAG, DECLARE_DIAGNOSTIC_FLAG, DECLARE_NOTPRODUCT_FLAG)
ARCH_FLAGS(DECLARE_DEVELOPER_FLAG, DECLARE_PRODUCT_FLAG, DECLARE_DIAGNOSTIC_FLAG, DECLARE_EXPERIMENTAL_FLAG, DECLARE_NOTPRODUCT_FLAG)
#include "runtime/globals_ext.hpp"
#endif // SHARE_VM_RUNTIME_GLOBALS_HPP
C:\hotspot-69087d08d473\src\share\vm/runtime/globals_ext.hpp
#ifndef SHARE_VM_RUNTIME_GLOBALS_EXT_HPP
#define SHARE_VM_RUNTIME_GLOBALS_EXT_HPP
#define COMMANDLINEFLAG_EXT
#define COMMANDLINEFLAGWITHTYPE_EXT
#define MATERIALIZE_FLAGS_EXT
#define FLAGTABLE_EXT
inline bool Flag::is_unlocker_ext() const {
return false;
}
inline bool Flag::is_unlocked_ext() const {
return true;
}
inline bool Flag::is_writeable_ext() const {
return false;
}
inline bool Flag::is_external_ext() const {
return false;
}
inline void Flag::get_locked_message_ext(char* buf, int buflen) const {
assert(buf != NULL, "Buffer cannot be NULL");
buf[0] = '\0';
}
#endif // SHARE_VM_RUNTIME_GLOBALS_EXT_HPP
C:\hotspot-69087d08d473\src\share\vm/runtime/globals_extension.hpp
#ifndef SHARE_VM_RUNTIME_GLOBALS_EXTENSION_HPP
#define SHARE_VM_RUNTIME_GLOBALS_EXTENSION_HPP
#include "runtime/globals.hpp"
#include "utilities/macros.hpp"
#include "utilities/top.hpp"
#define FLAG_MEMBER(flag) Flag_##flag
#define RUNTIME_PRODUCT_FLAG_MEMBER(type, name, value, doc) FLAG_MEMBER(name),
#define RUNTIME_PD_PRODUCT_FLAG_MEMBER(type, name, doc) FLAG_MEMBER(name),
#define RUNTIME_DIAGNOSTIC_FLAG_MEMBER(type, name, value, doc) FLAG_MEMBER(name),
#define RUNTIME_EXPERIMENTAL_FLAG_MEMBER(type, name, value, doc) FLAG_MEMBER(name),
#define RUNTIME_MANAGEABLE_FLAG_MEMBER(type, name, value, doc) FLAG_MEMBER(name),
#define RUNTIME_PRODUCT_RW_FLAG_MEMBER(type, name, value, doc) FLAG_MEMBER(name),
#define RUNTIME_DEVELOP_FLAG_MEMBER(type, name, value, doc) FLAG_MEMBER(name),
#define RUNTIME_PD_DEVELOP_FLAG_MEMBER(type, name, doc) FLAG_MEMBER(name),
#define RUNTIME_NOTPRODUCT_FLAG_MEMBER(type, name, value, doc) FLAG_MEMBER(name),
#ifdef _LP64
#define RUNTIME_LP64_PRODUCT_FLAG_MEMBER(type, name, value, doc) FLAG_MEMBER(name),
#else
#define RUNTIME_LP64_PRODUCT_FLAG_MEMBER(type, name, value, doc) /* flag is constant */
#endif // _LP64
#define C1_PRODUCT_FLAG_MEMBER(type, name, value, doc) FLAG_MEMBER(name),
#define C1_PD_PRODUCT_FLAG_MEMBER(type, name, doc) FLAG_MEMBER(name),
#define C1_DIAGNOSTIC_FLAG_MEMBER(type, name, value, doc) FLAG_MEMBER(name),
#define C1_DEVELOP_FLAG_MEMBER(type, name, value, doc) FLAG_MEMBER(name),
#define C1_PD_DEVELOP_FLAG_MEMBER(type, name, doc) FLAG_MEMBER(name),
#define C1_NOTPRODUCT_FLAG_MEMBER(type, name, value, doc) FLAG_MEMBER(name),
#define C2_PRODUCT_FLAG_MEMBER(type, name, value, doc) FLAG_MEMBER(name),
#define C2_PD_PRODUCT_FLAG_MEMBER(type, name, doc) FLAG_MEMBER(name),
#define C2_DIAGNOSTIC_FLAG_MEMBER(type, name, value, doc) FLAG_MEMBER(name),
#define C2_EXPERIMENTAL_FLAG_MEMBER(type, name, value, doc) FLAG_MEMBER(name),
#define C2_DEVELOP_FLAG_MEMBER(type, name, value, doc) FLAG_MEMBER(name),
#define C2_PD_DEVELOP_FLAG_MEMBER(type, name, doc) FLAG_MEMBER(name),
#define C2_NOTPRODUCT_FLAG_MEMBER(type, name, value, doc) FLAG_MEMBER(name),
#define ARCH_PRODUCT_FLAG_MEMBER(type, name, value, doc) FLAG_MEMBER(name),
#define ARCH_DIAGNOSTIC_FLAG_MEMBER(type, name, value, doc) FLAG_MEMBER(name),
#define ARCH_EXPERIMENTAL_FLAG_MEMBER(type, name, value, doc) FLAG_MEMBER(name),
#define ARCH_DEVELOP_FLAG_MEMBER(type, name, value, doc) FLAG_MEMBER(name),
#define ARCH_NOTPRODUCT_FLAG_MEMBER(type, name, value, doc) FLAG_MEMBER(name),
typedef enum {
RUNTIME_FLAGS(RUNTIME_DEVELOP_FLAG_MEMBER, RUNTIME_PD_DEVELOP_FLAG_MEMBER, RUNTIME_PRODUCT_FLAG_MEMBER, RUNTIME_PD_PRODUCT_FLAG_MEMBER, RUNTIME_DIAGNOSTIC_FLAG_MEMBER, RUNTIME_EXPERIMENTAL_FLAG_MEMBER, RUNTIME_NOTPRODUCT_FLAG_MEMBER, RUNTIME_MANAGEABLE_FLAG_MEMBER, RUNTIME_PRODUCT_RW_FLAG_MEMBER, RUNTIME_LP64_PRODUCT_FLAG_MEMBER)
RUNTIME_OS_FLAGS(RUNTIME_DEVELOP_FLAG_MEMBER, RUNTIME_PD_DEVELOP_FLAG_MEMBER, RUNTIME_PRODUCT_FLAG_MEMBER, RUNTIME_PD_PRODUCT_FLAG_MEMBER, RUNTIME_DIAGNOSTIC_FLAG_MEMBER, RUNTIME_NOTPRODUCT_FLAG_MEMBER)
#if INCLUDE_ALL_GCS
G1_FLAGS(RUNTIME_DEVELOP_FLAG_MEMBER, RUNTIME_PD_DEVELOP_FLAG_MEMBER, RUNTIME_PRODUCT_FLAG_MEMBER, RUNTIME_PD_PRODUCT_FLAG_MEMBER, RUNTIME_DIAGNOSTIC_FLAG_MEMBER, RUNTIME_EXPERIMENTAL_FLAG_MEMBER, RUNTIME_NOTPRODUCT_FLAG_MEMBER, RUNTIME_MANAGEABLE_FLAG_MEMBER, RUNTIME_PRODUCT_RW_FLAG_MEMBER)
#endif // INCLUDE_ALL_GCS
#ifdef COMPILER1
C1_FLAGS(C1_DEVELOP_FLAG_MEMBER, C1_PD_DEVELOP_FLAG_MEMBER, C1_PRODUCT_FLAG_MEMBER, C1_PD_PRODUCT_FLAG_MEMBER, C1_DIAGNOSTIC_FLAG_MEMBER, C1_NOTPRODUCT_FLAG_MEMBER)
#endif
#ifdef COMPILER2
C2_FLAGS(C2_DEVELOP_FLAG_MEMBER, C2_PD_DEVELOP_FLAG_MEMBER, C2_PRODUCT_FLAG_MEMBER, C2_PD_PRODUCT_FLAG_MEMBER, C2_DIAGNOSTIC_FLAG_MEMBER, C2_EXPERIMENTAL_FLAG_MEMBER, C2_NOTPRODUCT_FLAG_MEMBER)
#endif
ARCH_FLAGS(ARCH_DEVELOP_FLAG_MEMBER, ARCH_PRODUCT_FLAG_MEMBER, ARCH_DIAGNOSTIC_FLAG_MEMBER, ARCH_EXPERIMENTAL_FLAG_MEMBER, ARCH_NOTPRODUCT_FLAG_MEMBER)
COMMANDLINEFLAG_EXT
NUM_CommandLineFlag
} CommandLineFlag;
#define FLAG_MEMBER_WITH_TYPE(flag,type) Flag_##flag##_##type
#define RUNTIME_PRODUCT_FLAG_MEMBER_WITH_TYPE(type, name, value, doc) FLAG_MEMBER_WITH_TYPE(name,type),
#define RUNTIME_PD_PRODUCT_FLAG_MEMBER_WITH_TYPE(type, name, doc) FLAG_MEMBER_WITH_TYPE(name,type),
#define RUNTIME_DIAGNOSTIC_FLAG_MEMBER_WITH_TYPE(type, name, value, doc) FLAG_MEMBER_WITH_TYPE(name,type),
#define RUNTIME_EXPERIMENTAL_FLAG_MEMBER_WITH_TYPE(type, name, value, doc) FLAG_MEMBER_WITH_TYPE(name,type),
#define RUNTIME_MANAGEABLE_FLAG_MEMBER_WITH_TYPE(type, name, value, doc) FLAG_MEMBER_WITH_TYPE(name,type),
#define RUNTIME_PRODUCT_RW_FLAG_MEMBER_WITH_TYPE(type, name, value, doc) FLAG_MEMBER_WITH_TYPE(name,type),
#define RUNTIME_DEVELOP_FLAG_MEMBER_WITH_TYPE(type, name, value, doc) FLAG_MEMBER_WITH_TYPE(name,type),
#define RUNTIME_PD_DEVELOP_FLAG_MEMBER_WITH_TYPE(type, name, doc) FLAG_MEMBER_WITH_TYPE(name,type),
#define RUNTIME_NOTPRODUCT_FLAG_MEMBER_WITH_TYPE(type, name, value, doc) FLAG_MEMBER_WITH_TYPE(name,type),
#define C1_PRODUCT_FLAG_MEMBER_WITH_TYPE(type, name, value, doc) FLAG_MEMBER_WITH_TYPE(name,type),
#define C1_PD_PRODUCT_FLAG_MEMBER_WITH_TYPE(type, name, doc) FLAG_MEMBER_WITH_TYPE(name,type),
#define C1_DIAGNOSTIC_FLAG_MEMBER_WITH_TYPE(type, name, value, doc) FLAG_MEMBER_WITH_TYPE(name,type),
#define C1_DEVELOP_FLAG_MEMBER_WITH_TYPE(type, name, value, doc) FLAG_MEMBER_WITH_TYPE(name,type),
#define C1_PD_DEVELOP_FLAG_MEMBER_WITH_TYPE(type, name, doc) FLAG_MEMBER_WITH_TYPE(name,type),
#define C1_NOTPRODUCT_FLAG_MEMBER_WITH_TYPE(type, name, value, doc) FLAG_MEMBER_WITH_TYPE(name,type),
#ifdef _LP64
#define RUNTIME_LP64_PRODUCT_FLAG_MEMBER_WITH_TYPE(type, name, value, doc) FLAG_MEMBER_WITH_TYPE(name,type),
#else
#define RUNTIME_LP64_PRODUCT_FLAG_MEMBER_WITH_TYPE(type, name, value, doc) /* flag is constant */
#endif // _LP64
#define C2_PRODUCT_FLAG_MEMBER_WITH_TYPE(type, name, value, doc) FLAG_MEMBER_WITH_TYPE(name,type),
#define C2_PD_PRODUCT_FLAG_MEMBER_WITH_TYPE(type, name, doc) FLAG_MEMBER_WITH_TYPE(name,type),
#define C2_DIAGNOSTIC_FLAG_MEMBER_WITH_TYPE(type, name, value, doc) FLAG_MEMBER_WITH_TYPE(name,type),
#define C2_EXPERIMENTAL_FLAG_MEMBER_WITH_TYPE(type, name, value, doc) FLAG_MEMBER_WITH_TYPE(name,type),
#define C2_DEVELOP_FLAG_MEMBER_WITH_TYPE(type, name, value, doc) FLAG_MEMBER_WITH_TYPE(name,type),
#define C2_PD_DEVELOP_FLAG_MEMBER_WITH_TYPE(type, name, doc) FLAG_MEMBER_WITH_TYPE(name,type),
#define C2_NOTPRODUCT_FLAG_MEMBER_WITH_TYPE(type, name, value, doc) FLAG_MEMBER_WITH_TYPE(name,type),
#define ARCH_PRODUCT_FLAG_MEMBER_WITH_TYPE(type, name, value, doc) FLAG_MEMBER_WITH_TYPE(name,type),
#define ARCH_DIAGNOSTIC_FLAG_MEMBER_WITH_TYPE(type, name, value, doc) FLAG_MEMBER_WITH_TYPE(name,type),
#define ARCH_EXPERIMENTAL_FLAG_MEMBER_WITH_TYPE(type, name, value, doc) FLAG_MEMBER_WITH_TYPE(name,type),
#define ARCH_DEVELOP_FLAG_MEMBER_WITH_TYPE(type, name, value, doc) FLAG_MEMBER_WITH_TYPE(name,type),
#define ARCH_NOTPRODUCT_FLAG_MEMBER_WITH_TYPE(type, name, value, doc) FLAG_MEMBER_WITH_TYPE(name,type),
typedef enum {
RUNTIME_FLAGS(RUNTIME_DEVELOP_FLAG_MEMBER_WITH_TYPE,
RUNTIME_PD_DEVELOP_FLAG_MEMBER_WITH_TYPE,
RUNTIME_PRODUCT_FLAG_MEMBER_WITH_TYPE,
RUNTIME_PD_PRODUCT_FLAG_MEMBER_WITH_TYPE,
RUNTIME_DIAGNOSTIC_FLAG_MEMBER_WITH_TYPE,
RUNTIME_EXPERIMENTAL_FLAG_MEMBER_WITH_TYPE,
RUNTIME_NOTPRODUCT_FLAG_MEMBER_WITH_TYPE,
RUNTIME_MANAGEABLE_FLAG_MEMBER_WITH_TYPE,
RUNTIME_PRODUCT_RW_FLAG_MEMBER_WITH_TYPE,
RUNTIME_LP64_PRODUCT_FLAG_MEMBER_WITH_TYPE)
RUNTIME_OS_FLAGS(RUNTIME_DEVELOP_FLAG_MEMBER_WITH_TYPE,
RUNTIME_PD_DEVELOP_FLAG_MEMBER_WITH_TYPE,
RUNTIME_PRODUCT_FLAG_MEMBER_WITH_TYPE,
RUNTIME_PD_PRODUCT_FLAG_MEMBER_WITH_TYPE,
RUNTIME_DIAGNOSTIC_FLAG_MEMBER_WITH_TYPE,
RUNTIME_NOTPRODUCT_FLAG_MEMBER_WITH_TYPE)
#if INCLUDE_ALL_GCS
G1_FLAGS(RUNTIME_DEVELOP_FLAG_MEMBER_WITH_TYPE,
RUNTIME_PD_DEVELOP_FLAG_MEMBER_WITH_TYPE,
RUNTIME_PRODUCT_FLAG_MEMBER_WITH_TYPE,
RUNTIME_PD_PRODUCT_FLAG_MEMBER_WITH_TYPE,
RUNTIME_DIAGNOSTIC_FLAG_MEMBER_WITH_TYPE,
RUNTIME_EXPERIMENTAL_FLAG_MEMBER_WITH_TYPE,
RUNTIME_NOTPRODUCT_FLAG_MEMBER_WITH_TYPE,
RUNTIME_MANAGEABLE_FLAG_MEMBER_WITH_TYPE,
RUNTIME_PRODUCT_RW_FLAG_MEMBER_WITH_TYPE)
#endif // INCLUDE_ALL_GCS
#ifdef COMPILER1
C1_FLAGS(C1_DEVELOP_FLAG_MEMBER_WITH_TYPE,
C1_PD_DEVELOP_FLAG_MEMBER_WITH_TYPE,
C1_PRODUCT_FLAG_MEMBER_WITH_TYPE,
C1_PD_PRODUCT_FLAG_MEMBER_WITH_TYPE,
C1_DIAGNOSTIC_FLAG_MEMBER_WITH_TYPE,
C1_NOTPRODUCT_FLAG_MEMBER_WITH_TYPE)
#endif
#ifdef COMPILER2
C2_FLAGS(C2_DEVELOP_FLAG_MEMBER_WITH_TYPE,
C2_PD_DEVELOP_FLAG_MEMBER_WITH_TYPE,
C2_PRODUCT_FLAG_MEMBER_WITH_TYPE,
C2_PD_PRODUCT_FLAG_MEMBER_WITH_TYPE,
C2_DIAGNOSTIC_FLAG_MEMBER_WITH_TYPE,
C2_EXPERIMENTAL_FLAG_MEMBER_WITH_TYPE,
C2_NOTPRODUCT_FLAG_MEMBER_WITH_TYPE)
#endif
ARCH_FLAGS(ARCH_DEVELOP_FLAG_MEMBER_WITH_TYPE,
ARCH_PRODUCT_FLAG_MEMBER_WITH_TYPE,
ARCH_DIAGNOSTIC_FLAG_MEMBER_WITH_TYPE,
ARCH_EXPERIMENTAL_FLAG_MEMBER_WITH_TYPE,
ARCH_NOTPRODUCT_FLAG_MEMBER_WITH_TYPE)
COMMANDLINEFLAGWITHTYPE_EXT
NUM_CommandLineFlagWithType
} CommandLineFlagWithType;
#define FLAG_IS_DEFAULT(name) (CommandLineFlagsEx::is_default(FLAG_MEMBER(name)))
#define FLAG_IS_ERGO(name) (CommandLineFlagsEx::is_ergo(FLAG_MEMBER(name)))
#define FLAG_IS_CMDLINE(name) (CommandLineFlagsEx::is_cmdline(FLAG_MEMBER(name)))
#define FLAG_SET_DEFAULT(name, value) ((name) = (value))
#define FLAG_SET_CMDLINE(type, name, value) (CommandLineFlagsEx::type##AtPut(FLAG_MEMBER_WITH_TYPE(name,type), (type)(value), Flag::COMMAND_LINE))
#define FLAG_SET_ERGO(type, name, value) (CommandLineFlagsEx::type##AtPut(FLAG_MEMBER_WITH_TYPE(name,type), (type)(value), Flag::ERGONOMIC))
#define FLAG_SET_MGMT(type, name, value) (CommandLineFlagsEx::type##AtPut(FLAG_MEMBER_WITH_TYPE(name, type), (type)(value), Flag::MANAGEMENT))
class CommandLineFlagsEx : CommandLineFlags {
public:
static void boolAtPut(CommandLineFlagWithType flag, bool value, Flag::Flags origin);
static void intxAtPut(CommandLineFlagWithType flag, intx value, Flag::Flags origin);
static void uintxAtPut(CommandLineFlagWithType flag, uintx value, Flag::Flags origin);
static void uint64_tAtPut(CommandLineFlagWithType flag, uint64_t value, Flag::Flags origin);
static void doubleAtPut(CommandLineFlagWithType flag, double value, Flag::Flags origin);
static void ccstrAtPut(CommandLineFlagWithType flag, ccstr value, Flag::Flags origin);
static bool is_default(CommandLineFlag flag);
static bool is_ergo(CommandLineFlag flag);
static bool is_cmdline(CommandLineFlag flag);
};
#endif // SHARE_VM_RUNTIME_GLOBALS_EXTENSION_HPP
C:\hotspot-69087d08d473\src\share\vm/runtime/handles.cpp
#include "precompiled.hpp"
#include "memory/allocation.inline.hpp"
#include "oops/constantPool.hpp"
#include "oops/oop.inline.hpp"
#include "runtime/handles.inline.hpp"
#include "runtime/thread.inline.hpp"
#ifdef TARGET_OS_FAMILY_linux
# include "os_linux.inline.hpp"
#endif
#ifdef TARGET_OS_FAMILY_solaris
# include "os_solaris.inline.hpp"
#endif
#ifdef TARGET_OS_FAMILY_windows
# include "os_windows.inline.hpp"
#endif
#ifdef TARGET_OS_FAMILY_bsd
# include "os_bsd.inline.hpp"
#endif
PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
#ifdef ASSERT
oop* HandleArea::allocate_handle(oop obj) {
assert(_handle_mark_nesting > 1, "memory leak: allocating handle outside HandleMark");
assert(_no_handle_mark_nesting == 0, "allocating handle inside NoHandleMark");
assert(obj->is_oop(), err_msg("not an oop: " INTPTR_FORMAT, (intptr_t*) obj));
return real_allocate_handle(obj);
}
Handle::Handle(Thread* thread, oop obj) {
assert(thread == Thread::current(), "sanity check");
if (obj == NULL) {
_handle = NULL;
} else {
_handle = thread->handle_area()->allocate_handle(obj);
}
}
#endif
static uintx chunk_oops_do(OopClosure* f, Chunk* chunk, char* chunk_top) {
oop* bottom = (oop*) chunk->bottom();
oop* top = (oop*) chunk_top;
uintx handles_visited = top - bottom;
assert(top >= bottom && top <= (oop*) chunk->top(), "just checking");
while (bottom < top) {
assert((*bottom)->is_oop(INCLUDE_JFR), "handle should point to oop");
f->do_oop(bottom++);
}
return handles_visited;
}
NOT_PRODUCT(jint _nof_handlemarks = 0;)
void HandleArea::oops_do(OopClosure* f) {
uintx handles_visited = 0;
handles_visited += chunk_oops_do(f, _chunk, _hwm);
Chunk* k = _first;
while(k != _chunk) {
handles_visited += chunk_oops_do(f, k, k->top());
k = k->next();
}
if (TraceHandleAllocation && handles_visited > TotalHandleAllocationLimit) {
#ifdef ASSERT
warning("%d: Visited in HandleMark : %d",
_nof_handlemarks, handles_visited);
#else
warning("Visited in HandleMark : %d", handles_visited);
#endif
}
if (_prev != NULL) _prev->oops_do(f);
}
void HandleMark::initialize(Thread* thread) {
_thread = thread;
_area = thread->handle_area();
_chunk = _area->_chunk;
_hwm = _area->_hwm;
_max = _area->_max;
_size_in_bytes = _area->_size_in_bytes;
debug_only(_area->_handle_mark_nesting++);
assert(_area->_handle_mark_nesting > 0, "must stack allocate HandleMarks");
debug_only(Atomic::inc(&_nof_handlemarks);)
set_previous_handle_mark(thread->last_handle_mark());
thread->set_last_handle_mark(this);
}
HandleMark::~HandleMark() {
HandleArea* area = _area; // help compilers with poor alias analysis
assert(area == _thread->handle_area(), "sanity check");
assert(area->_handle_mark_nesting > 0, "must stack allocate HandleMarks" );
debug_only(area->_handle_mark_nesting--);
#ifdef ASSERT
if (TraceHandleAllocation) {
size_t handles = 0;
Chunk *c = _chunk->next();
if (c == NULL) {
handles = area->_hwm - _hwm; // no new chunk allocated
} else {
handles = _max - _hwm; // add rest in first chunk
while(c != NULL) {
handles += c->length();
c = c->next();
}
handles -= area->_max - area->_hwm; // adjust for last trunk not full
}
handles /= sizeof(void *); // Adjust for size of a handle
if (handles > HandleAllocationLimit) {
warning("%d: Allocated in HandleMark : %d", _nof_handlemarks, handles);
}
tty->print_cr("Handles %d", handles);
}
#endif
if( _chunk->next() ) {
assert(area->size_in_bytes() > size_in_bytes(), "Sanity check");
area->set_size_in_bytes(size_in_bytes());
_chunk->next_chop();
} else {
assert(area->size_in_bytes() == size_in_bytes(), "Sanity check");
}
area->_chunk = _chunk;
area->_hwm = _hwm;
area->_max = _max;
#ifdef ASSERT
if (ZapVMHandleArea) {
memset(_hwm, badHandleValue, _max - _hwm);
}
Atomic::dec(&_nof_handlemarks);
#endif
_thread->set_last_handle_mark(previous_handle_mark());
}
void* HandleMark::operator new(size_t size) throw() {
return AllocateHeap(size, mtThread);
}
void* HandleMark::operator new [] (size_t size) throw() {
return AllocateHeap(size, mtThread);
}
void HandleMark::operator delete(void* p) {
FreeHeap(p, mtThread);
}
void HandleMark::operator delete[](void* p) {
FreeHeap(p, mtThread);
}
#ifdef ASSERT
NoHandleMark::NoHandleMark() {
HandleArea* area = Thread::current()->handle_area();
area->_no_handle_mark_nesting++;
assert(area->_no_handle_mark_nesting > 0, "must stack allocate NoHandleMark" );
}
NoHandleMark::~NoHandleMark() {
HandleArea* area = Thread::current()->handle_area();
assert(area->_no_handle_mark_nesting > 0, "must stack allocate NoHandleMark" );
area->_no_handle_mark_nesting--;
}
ResetNoHandleMark::ResetNoHandleMark() {
HandleArea* area = Thread::current()->handle_area();
_no_handle_mark_nesting = area->_no_handle_mark_nesting;
area->_no_handle_mark_nesting = 0;
}
ResetNoHandleMark::~ResetNoHandleMark() {
HandleArea* area = Thread::current()->handle_area();
area->_no_handle_mark_nesting = _no_handle_mark_nesting;
}
#endif
C:\hotspot-69087d08d473\src\share\vm/runtime/handles.hpp
#ifndef SHARE_VM_RUNTIME_HANDLES_HPP
#define SHARE_VM_RUNTIME_HANDLES_HPP
#include "oops/klass.hpp"
class Handle VALUE_OBJ_CLASS_SPEC {
private:
oop* _handle;
protected:
oop obj() const { return _handle == NULL ? (oop)NULL : *_handle; }
oop non_null_obj() const { assert(_handle != NULL, "resolving NULL handle"); return *_handle; }
public:
Handle() { _handle = NULL; }
Handle(oop obj);
Handle(Thread* thread, oop obj);
oop operator () () const { return obj(); }
oop operator -> () const { return non_null_obj(); }
bool operator == (oop o) const { return obj() == o; }
bool operator == (const Handle& h) const { return obj() == h.obj(); }
bool is_null() const { return _handle == NULL; }
bool not_null() const { return _handle != NULL; }
void print() { obj()->print(); }
Handle(oop *handle, bool dummy) { _handle = handle; }
oop* raw_value() { return _handle; }
static oop raw_resolve(oop *handle) { return handle == NULL ? (oop)NULL : *handle; }
};
#define DEF_HANDLE(type, is_a) \
class type##Handle: public Handle { \
protected: \
type##Oop obj() const { return (type##Oop)Handle::obj(); } \
type##Oop non_null_obj() const { return (type##Oop)Handle::non_null_obj(); } \
\
public: \
type##Handle () : Handle() {} \
type##Handle (type##Oop obj) : Handle((oop)obj) { \
assert(is_null() || ((oop)obj)->is_a(), \
"illegal type"); \
} \
type##Handle (Thread* thread, type##Oop obj) : Handle(thread, (oop)obj) { \
assert(is_null() || ((oop)obj)->is_a(), "illegal type"); \
} \
\
type##Oop operator () () const { return obj(); } \
type##Oop operator -> () const { return non_null_obj(); } \
};
DEF_HANDLE(instance , is_instance )
DEF_HANDLE(array , is_array )
DEF_HANDLE(objArray , is_objArray )
DEF_HANDLE(typeArray , is_typeArray )
#define DEF_METADATA_HANDLE(name, type) \
class name##Handle; \
class name##Handle : public StackObj { \
type* _value; \
Thread* _thread; \
protected: \
type* obj() const { return _value; } \
type* non_null_obj() const { assert(_value != NULL, "resolving NULL _value"); return _value; } \
\
public: \
name##Handle () : _value(NULL), _thread(NULL) {} \
name##Handle (type* obj); \
name##Handle (Thread* thread, type* obj); \
\
name##Handle (const name##Handle &h); \
name##Handle& operator=(const name##Handle &s); \
\
~name##Handle (); \
void remove(); \
\
type* operator () () const { return obj(); } \
type* operator -> () const { return non_null_obj(); } \
\
bool operator == (type* o) const { return obj() == o; } \
bool operator == (const name##Handle& h) const { return obj() == h.obj(); } \
\
bool is_null() const { return _value == NULL; } \
bool not_null() const { return _value != NULL; } \
};
DEF_METADATA_HANDLE(method, Method)
DEF_METADATA_HANDLE(constantPool, ConstantPool)
class KlassHandle : public StackObj {
Klass* _value;
protected:
Klass* obj() const { return _value; }
Klass* non_null_obj() const { assert(_value != NULL, "resolving NULL _value"); return _value; }
public:
KlassHandle() : _value(NULL) {}
KlassHandle(const Klass* obj) : _value(const_cast<Klass *>(obj)) {};
KlassHandle(Thread* thread, const Klass* obj) : _value(const_cast<Klass *>(obj)) {};
Klass* operator () () const { return obj(); }
Klass* operator -> () const { return non_null_obj(); }
bool operator == (Klass* o) const { return obj() == o; }
bool operator == (const KlassHandle& h) const { return obj() == h.obj(); }
bool is_null() const { return _value == NULL; }
bool not_null() const { return _value != NULL; }
};
class instanceKlassHandle : public KlassHandle {
public:
instanceKlassHandle () : KlassHandle() {}
instanceKlassHandle (const Klass* k) : KlassHandle(k) {
assert(k == NULL || k->oop_is_instance(),
"illegal type");
}
instanceKlassHandle (Thread* thread, const Klass* k) : KlassHandle(thread, k) {
assert(k == NULL || k->oop_is_instance(),
"illegal type");
}
InstanceKlass* operator () () const { return (InstanceKlass*)obj(); }
InstanceKlass* operator -> () const { return (InstanceKlass*)obj(); }
};
class HandleArea: public Arena {
friend class HandleMark;
friend class NoHandleMark;
friend class ResetNoHandleMark;
#ifdef ASSERT
int _handle_mark_nesting;
int _no_handle_mark_nesting;
#endif
HandleArea* _prev; // link to outer (older) area
public:
HandleArea(HandleArea* prev) : Arena(mtThread, Chunk::tiny_size) {
debug_only(_handle_mark_nesting = 0);
debug_only(_no_handle_mark_nesting = 0);
_prev = prev;
}
private:
oop* real_allocate_handle(oop obj) {
#ifdef ASSERT
oop* handle = (oop*) (UseMallocOnly ? internal_malloc_4(oopSize) : Amalloc_4(oopSize));
#else
oop* handle = (oop*) Amalloc_4(oopSize);
#endif
return handle;
}
public:
#ifdef ASSERT
oop* allocate_handle(oop obj);
#else
oop* allocate_handle(oop obj) { return real_allocate_handle(obj); }
#endif
void oops_do(OopClosure* f);
size_t used() const { return Arena::used() / oopSize; }
debug_only(bool no_handle_mark_active() { return _no_handle_mark_nesting > 0; })
};
class HandleMark {
private:
Thread *_thread; // thread that owns this mark
HandleArea *_area; // saved handle area
Chunk *_chunk; // saved arena chunk
char *_hwm, *_max; // saved arena info
size_t _size_in_bytes; // size of handle area
HandleMark* _previous_handle_mark;
void initialize(Thread* thread); // common code for constructors
void set_previous_handle_mark(HandleMark* mark) { _previous_handle_mark = mark; }
HandleMark* previous_handle_mark() const { return _previous_handle_mark; }
size_t size_in_bytes() const { return _size_in_bytes; }
public:
HandleMark(); // see handles_inline.hpp
HandleMark(Thread* thread) { initialize(thread); }
~HandleMark();
void push();
void pop_and_restore();
void* operator new(size_t size) throw();
void* operator new [](size_t size) throw();
void operator delete(void* p);
void operator delete[](void* p);
};
class NoHandleMark: public StackObj {
public:
#ifdef ASSERT
NoHandleMark();
~NoHandleMark();
#else
NoHandleMark() {}
~NoHandleMark() {}
#endif
};
class ResetNoHandleMark: public StackObj {
int _no_handle_mark_nesting;
public:
#ifdef ASSERT
ResetNoHandleMark();
~ResetNoHandleMark();
#else
ResetNoHandleMark() {}
~ResetNoHandleMark() {}
#endif
};
#endif // SHARE_VM_RUNTIME_HANDLES_HPP
C:\hotspot-69087d08d473\src\share\vm/runtime/handles.inline.hpp
#ifndef SHARE_VM_RUNTIME_HANDLES_INLINE_HPP
#define SHARE_VM_RUNTIME_HANDLES_INLINE_HPP
#include "runtime/handles.hpp"
#include "runtime/thread.inline.hpp"
inline Handle::Handle(oop obj) {
if (obj == NULL) {
_handle = NULL;
} else {
_handle = Thread::current()->handle_area()->allocate_handle(obj);
}
}
#ifndef ASSERT
inline Handle::Handle(Thread* thread, oop obj) {
assert(thread == Thread::current(), "sanity check");
if (obj == NULL) {
_handle = NULL;
} else {
_handle = thread->handle_area()->allocate_handle(obj);
}
}
#endif // ASSERT
#define DEF_METADATA_HANDLE_FN(name, type) \
inline name##Handle::name##Handle(type* obj) : _value(obj), _thread(NULL) { \
if (obj != NULL) { \
assert(((Metadata*)obj)->is_valid(), "obj is valid"); \
_thread = Thread::current(); \
assert (_thread->is_in_stack((address)this), "not on stack?"); \
_thread->metadata_handles()->push((Metadata*)obj); \
} \
} \
inline name##Handle::name##Handle(Thread* thread, type* obj) : _value(obj), _thread(thread) { \
if (obj != NULL) { \
assert(((Metadata*)obj)->is_valid(), "obj is valid"); \
assert(_thread == Thread::current(), "thread must be current"); \
assert (_thread->is_in_stack((address)this), "not on stack?"); \
_thread->metadata_handles()->push((Metadata*)obj); \
} \
} \
inline name##Handle::name##Handle(const name##Handle &h) { \
_value = h._value; \
if (_value != NULL) { \
assert(_value->is_valid(), "obj is valid"); \
if (h._thread != NULL) { \
assert(h._thread == Thread::current(), "thread must be current");\
_thread = h._thread; \
} else { \
_thread = Thread::current(); \
} \
assert (_thread->is_in_stack((address)this), "not on stack?"); \
_thread->metadata_handles()->push((Metadata*)_value); \
} else { \
_thread = NULL; \
} \
} \
inline name##Handle& name##Handle::operator=(const name##Handle &s) { \
remove(); \
_value = s._value; \
if (_value != NULL) { \
assert(_value->is_valid(), "obj is valid"); \
if (s._thread != NULL) { \
assert(s._thread == Thread::current(), "thread must be current");\
_thread = s._thread; \
} else { \
_thread = Thread::current(); \
} \
assert (_thread->is_in_stack((address)this), "not on stack?"); \
_thread->metadata_handles()->push((Metadata*)_value); \
} else { \
_thread = NULL; \
} \
return *this; \
} \
inline void name##Handle::remove() { \
if (_value != NULL) { \
int i = _thread->metadata_handles()->find_from_end((Metadata*)_value); \
assert(i!=-1, "not in metadata_handles list"); \
_thread->metadata_handles()->remove_at(i); \
} \
} \
inline name##Handle::~name##Handle () { remove(); } \
DEF_METADATA_HANDLE_FN(method, Method)
DEF_METADATA_HANDLE_FN(constantPool, ConstantPool)
inline HandleMark::HandleMark() {
initialize(Thread::current());
}
inline void HandleMark::push() {
debug_only(_area->_handle_mark_nesting++);
}
inline void HandleMark::pop_and_restore() {
HandleArea* area = _area; // help compilers with poor alias analysis
if( _chunk->next() ) {
assert(area->size_in_bytes() > size_in_bytes(), "Sanity check");
area->set_size_in_bytes(size_in_bytes());
_chunk->next_chop();
} else {
assert(area->size_in_bytes() == size_in_bytes(), "Sanity check");
}
area->_chunk = _chunk;
area->_hwm = _hwm;
area->_max = _max;
debug_only(area->_handle_mark_nesting--);
}
#endif // SHARE_VM_RUNTIME_HANDLES_INLINE_HPP
C:\hotspot-69087d08d473\src\share\vm/runtime/icache.cpp
#include "precompiled.hpp"
#include "memory/resourceArea.hpp"
#include "runtime/icache.hpp"
AbstractICache::flush_icache_stub_t AbstractICache::_flush_icache_stub = NULL;
void AbstractICache::initialize() {
ResourceMark rm;
BufferBlob* b = BufferBlob::create("flush_icache_stub", ICache::stub_size);
CodeBuffer c(b);
ICacheStubGenerator g(&c);
g.generate_icache_flush(&_flush_icache_stub);
}
void AbstractICache::call_flush_stub(address start, int lines) {
static int magic = 0xbaadbabe;
int auto_magic = magic; // Make a local copy to avoid race condition
int r = (*_flush_icache_stub)(start, lines, auto_magic);
guarantee(r == auto_magic, "flush stub routine did not execute");
++magic;
}
void AbstractICache::invalidate_word(address addr) {
const int word_size_in_bytes = 4; // Always, regardless of platform
intptr_t start_line = ((intptr_t)addr + 0) & ~(ICache::line_size - 1);
intptr_t end_line = ((intptr_t)addr + word_size_in_bytes - 1)
& ~(ICache::line_size - 1);
(*_flush_icache_stub)((address)start_line, start_line == end_line ? 1 : 2, 0);
}
void AbstractICache::invalidate_range(address start, int nbytes) {
static bool firstTime = true;
if (firstTime) {
guarantee(start == CAST_FROM_FN_PTR(address, _flush_icache_stub),
"first flush should be for flush stub");
firstTime = false;
return;
}
if (nbytes == 0) {
return;
}
const uint line_offset = mask_address_bits(start, ICache::line_size-1);
if (line_offset != 0) {
start -= line_offset;
nbytes += line_offset;
}
call_flush_stub(start, round_to(nbytes, ICache::line_size) >>
ICache::log2_line_size);
}
void icache_init() {
ICache::initialize();
}
C:\hotspot-69087d08d473\src\share\vm/runtime/icache.hpp
#ifndef SHARE_VM_RUNTIME_ICACHE_HPP
#define SHARE_VM_RUNTIME_ICACHE_HPP
#include "memory/allocation.hpp"
#include "runtime/stubCodeGenerator.hpp"
class AbstractICache : AllStatic {
public:
typedef int (*flush_icache_stub_t)(address addr, int lines, int magic);
protected:
static flush_icache_stub_t _flush_icache_stub;
static void call_flush_stub(address start, int lines);
public:
enum {
stub_size = 0, // Size of the icache flush stub in bytes
line_size = 0, // Icache line size in bytes
log2_line_size = 0 // log2(line_size)
};
static void initialize();
static void invalidate_word(address addr);
static void invalidate_range(address start, int nbytes);
};
#ifdef TARGET_ARCH_x86
# include "icache_x86.hpp"
#endif
#ifdef TARGET_ARCH_aarch64
# include "icache_aarch64.hpp"
#endif
#ifdef TARGET_ARCH_sparc
# include "icache_sparc.hpp"
#endif
#ifdef TARGET_ARCH_zero
# include "icache_zero.hpp"
#endif
#ifdef TARGET_ARCH_arm
# include "icache_arm.hpp"
#endif
#ifdef TARGET_ARCH_ppc
# include "icache_ppc.hpp"
#endif
class ICacheStubGenerator : public StubCodeGenerator {
public:
ICacheStubGenerator(CodeBuffer *c) : StubCodeGenerator(c) {}
void generate_icache_flush(ICache::flush_icache_stub_t* flush_icache_stub);
};
#endif // SHARE_VM_RUNTIME_ICACHE_HPP
C:\hotspot-69087d08d473\src\share\vm/runtime/init.cpp
#include "precompiled.hpp"
#include "classfile/symbolTable.hpp"
#include "code/icBuffer.hpp"
#include "gc_interface/collectedHeap.hpp"
#include "interpreter/bytecodes.hpp"
#include "memory/universe.hpp"
#include "prims/methodHandles.hpp"
#include "runtime/handles.inline.hpp"
#include "runtime/icache.hpp"
#include "runtime/init.hpp"
#include "runtime/safepoint.hpp"
#include "runtime/sharedRuntime.hpp"
#include "services/memTracker.hpp"
#include "utilities/macros.hpp"
void check_ThreadShadow();
void eventlog_init();
void mutex_init();
void chunkpool_init();
void perfMemory_init();
void management_init();
void bytecodes_init();
void classLoader_init();
void codeCache_init();
void VM_Version_init();
void os_init_globals(); // depends on VM_Version_init, before universe_init
void stubRoutines_init1();
jint universe_init(); // depends on codeCache_init and stubRoutines_init
void interpreter_init(); // before any methods loaded
void invocationCounter_init(); // before any methods loaded
void marksweep_init();
void accessFlags_init();
void templateTable_init();
void InterfaceSupport_init();
void universe2_init(); // dependent on codeCache_init and stubRoutines_init, loads primordial classes
void referenceProcessor_init();
void jni_handles_init();
void vmStructs_init();
void vtableStubs_init();
void InlineCacheBuffer_init();
void compilerOracle_init();
void compilationPolicy_init();
void compileBroker_init();
bool universe_post_init(); // must happen after compiler_init
void javaClasses_init(); // must happen after vtable initialization
void stubRoutines_init2(); // note: StubRoutines need 2-phase init
void perfMemory_exit();
void ostream_exit();
void vm_init_globals() {
check_ThreadShadow();
basic_types_init();
eventlog_init();
mutex_init();
chunkpool_init();
perfMemory_init();
}
jint init_globals() {
HandleMark hm;
management_init();
bytecodes_init();
classLoader_init();
codeCache_init();
VM_Version_init();
os_init_globals();
stubRoutines_init1();
jint status = universe_init(); // dependent on codeCache_init and
if (status != JNI_OK)
return status;
interpreter_init(); // before any methods loaded
invocationCounter_init(); // before any methods loaded
marksweep_init();
accessFlags_init();
templateTable_init();
InterfaceSupport_init();
SharedRuntime::generate_stubs();
universe2_init(); // dependent on codeCache_init and stubRoutines_init1
referenceProcessor_init();
jni_handles_init();
#if INCLUDE_VM_STRUCTS
vmStructs_init();
#endif // INCLUDE_VM_STRUCTS
vtableStubs_init();
InlineCacheBuffer_init();
compilerOracle_init();
compilationPolicy_init();
compileBroker_init();
VMRegImpl::set_regName();
if (!universe_post_init()) {
return JNI_ERR;
}
javaClasses_init(); // must happen after vtable initialization
stubRoutines_init2(); // note: StubRoutines need 2-phase init
#if INCLUDE_NMT
NMT_stack_walkable = true;
#endif // INCLUDE_NMT
if (PrintFlagsFinal) {
CommandLineFlags::printFlags(tty, false);
}
return JNI_OK;
}
void exit_globals() {
static bool destructorsCalled = false;
if (!destructorsCalled) {
destructorsCalled = true;
perfMemory_exit();
if (PrintSafepointStatistics) {
SafepointSynchronize::print_stat_on_exit();
}
if (PrintStringTableStatistics) {
SymbolTable::dump(tty);
StringTable::dump(tty);
}
ostream_exit();
}
}
static bool _init_completed = false;
bool is_init_completed() {
return _init_completed;
}
void set_init_completed() {
assert(Universe::is_fully_initialized(), "Should have completed initialization");
_init_completed = true;
}
C:\hotspot-69087d08d473\src\share\vm/runtime/init.hpp
#ifndef SHARE_VM_RUNTIME_INIT_HPP
#define SHARE_VM_RUNTIME_INIT_HPP
#include "utilities/top.hpp"
jint init_globals(); // call constructors at startup (main Java thread)
void vm_init_globals(); // call constructors at startup (VM thread)
void exit_globals(); // call destructors before exit
bool is_init_completed(); // returns true when bootstrapping has completed
void set_init_completed(); // set basic init to completed
#endif // SHARE_VM_RUNTIME_INIT_HPP
C:\hotspot-69087d08d473\src\share\vm/runtime/interfaceSupport.cpp
#include "precompiled.hpp"
#include "gc_implementation/shared/markSweep.hpp"
#include "gc_interface/collectedHeap.hpp"
#include "gc_interface/collectedHeap.inline.hpp"
#include "memory/genCollectedHeap.hpp"
#include "memory/resourceArea.hpp"
#include "runtime/init.hpp"
#include "runtime/interfaceSupport.hpp"
#include "runtime/orderAccess.inline.hpp"
#include "runtime/threadLocalStorage.hpp"
#include "runtime/vframe.hpp"
#include "utilities/preserveException.hpp"
PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
#ifdef ASSERT
long InterfaceSupport::_number_of_calls = 0;
long InterfaceSupport::_scavenge_alot_counter = 1;
long InterfaceSupport::_fullgc_alot_counter = 1;
long InterfaceSupport::_fullgc_alot_invocation = 0;
Histogram* RuntimeHistogram;
RuntimeHistogramElement::RuntimeHistogramElement(const char* elementName) {
static volatile jint RuntimeHistogram_lock = 0;
_name = elementName;
uintx count = 0;
while (Atomic::cmpxchg(1, &RuntimeHistogram_lock, 0) != 0) {
while (OrderAccess::load_acquire(&RuntimeHistogram_lock) != 0) {
count +=1;
if ( (WarnOnStalledSpinLock > 0)
&& (count % WarnOnStalledSpinLock == 0)) {
warning("RuntimeHistogram_lock seems to be stalled");
}
}
}
if (RuntimeHistogram == NULL) {
RuntimeHistogram = new Histogram("VM Runtime Call Counts",200);
}
RuntimeHistogram->add_element(this);
Atomic::dec(&RuntimeHistogram_lock);
}
void InterfaceSupport::trace(const char* result_type, const char* header) {
tty->print_cr("%6d %s", _number_of_calls, header);
}
void InterfaceSupport::gc_alot() {
Thread *thread = Thread::current();
if (!thread->is_Java_thread()) return; // Avoid concurrent calls
JavaThread *current_thread = (JavaThread *)thread;
if (current_thread->active_handles() == NULL) return;
if (thread->skip_gcalot()) return;
if (Threads::is_vm_complete()) {
if (++_fullgc_alot_invocation < FullGCALotStart) {
return;
}
if (FullGCALot) _fullgc_alot_counter--;
if (_fullgc_alot_counter == 0) {
if (!Universe::release_fullgc_alot_dummy()) {
warning("FullGCALot: Unable to release more dummies at bottom of heap");
}
HandleMark hm(thread);
Universe::heap()->collect(GCCause::_full_gc_alot);
unsigned int invocations = Universe::heap()->total_full_collections();
if (FullGCALotInterval > 1) {
_fullgc_alot_counter = 1+(long)((double)FullGCALotInterval*os::random()/(max_jint+1.0));
if (PrintGCDetails && Verbose) {
tty->print_cr("Full gc no: %u\tInterval: %d", invocations,
_fullgc_alot_counter);
}
} else {
_fullgc_alot_counter = 1;
}
if (invocations % 100 == 0) {
if (PrintGCDetails && Verbose) tty->print_cr("Full gc no: %u", invocations);
}
} else {
if (ScavengeALot) _scavenge_alot_counter--;
if (_scavenge_alot_counter == 0) {
HandleMark hm(thread);
Universe::heap()->collect(GCCause::_scavenge_alot);
unsigned int invocations = Universe::heap()->total_collections() - Universe::heap()->total_full_collections();
if (ScavengeALotInterval > 1) {
_scavenge_alot_counter = 1+(long)((double)ScavengeALotInterval*os::random()/(max_jint+1.0));
if (PrintGCDetails && Verbose) {
tty->print_cr("Scavenge no: %u\tInterval: %d", invocations,
_scavenge_alot_counter);
}
} else {
_scavenge_alot_counter = 1;
}
if (invocations % 1000 == 0) {
if (PrintGCDetails && Verbose) tty->print_cr("Scavenge no: %u", invocations);
}
}
}
}
}
vframe* vframe_array[50];
int walk_stack_counter = 0;
void InterfaceSupport::walk_stack_from(vframe* start_vf) {
int i = 0;
for (vframe* f = start_vf; f; f = f->sender() ) {
if (i < 50) vframe_array[i++] = f;
}
}
void InterfaceSupport::walk_stack() {
JavaThread* thread = JavaThread::current();
walk_stack_counter++;
if (!thread->has_last_Java_frame()) return;
ResourceMark rm(thread);
RegisterMap reg_map(thread);
walk_stack_from(thread->last_java_vframe(®_map));
}
# ifdef ENABLE_ZAP_DEAD_LOCALS
static int zap_traversals = 0;
void InterfaceSupport::zap_dead_locals_old() {
JavaThread* thread = JavaThread::current();
if (zap_traversals == -1) // edit constant for debugging
warning("I am here");
int zap_frame_count = 0; // count frames to help debugging
for (StackFrameStream sfs(thread); !sfs.is_done(); sfs.next()) {
sfs.current()->zap_dead_locals(thread, sfs.register_map());
++zap_frame_count;
}
++zap_traversals;
}
# endif
int deoptimizeAllCounter = 0;
int zombieAllCounter = 0;
void InterfaceSupport::zombieAll() {
int value = zombieAllCounter / Threads::number_of_threads();
if (is_init_completed() && value > ZombieALotInterval) {
zombieAllCounter = 0;
VM_ZombieAll op;
VMThread::execute(&op);
}
zombieAllCounter++;
}
void InterfaceSupport::unlinkSymbols() {
VM_UnlinkSymbols op;
VMThread::execute(&op);
}
void InterfaceSupport::deoptimizeAll() {
int value = deoptimizeAllCounter / Threads::number_of_threads();
if (is_init_completed()) {
if (DeoptimizeALot && value > DeoptimizeALotInterval) {
deoptimizeAllCounter = 0;
VM_DeoptimizeAll op;
VMThread::execute(&op);
} else if (DeoptimizeRandom && (value & 0x1F) == (os::random() & 0x1F)) {
VM_DeoptimizeAll op;
VMThread::execute(&op);
}
}
deoptimizeAllCounter++;
}
void InterfaceSupport::stress_derived_pointers() {
#ifdef COMPILER2
JavaThread *thread = JavaThread::current();
if (!is_init_completed()) return;
ResourceMark rm(thread);
bool found = false;
for (StackFrameStream sfs(thread); !sfs.is_done() && !found; sfs.next()) {
CodeBlob* cb = sfs.current()->cb();
if (cb != NULL && cb->oop_maps() ) {
OopMap* map = cb->oop_map_for_return_address(sfs.current()->pc());
assert(map != NULL, "no oopmap found for pc");
found = map->has_derived_pointer();
}
}
if (found) {
Scavenge::invoke(0);
}
#endif
}
void InterfaceSupport::verify_stack() {
JavaThread* thread = JavaThread::current();
ResourceMark rm(thread);
if (!thread->has_pending_exception()) {
StackFrameStream sfs(thread);
CodeBlob* cb = sfs.current()->cb();
if (cb != NULL && !(cb->is_runtime_stub() || cb->is_uncommon_trap_stub())) return;
for (; !sfs.is_done(); sfs.next()) {
sfs.current()->verify(sfs.register_map());
}
}
}
void InterfaceSupport::verify_last_frame() {
JavaThread* thread = JavaThread::current();
ResourceMark rm(thread);
RegisterMap reg_map(thread);
frame fr = thread->last_frame();
fr.verify(®_map);
}
#endif // ASSERT
void InterfaceSupport_init() {
#ifdef ASSERT
if (ScavengeALot || FullGCALot) {
srand(ScavengeALotInterval * FullGCALotInterval);
}
#endif
}
C:\hotspot-69087d08d473\src\share\vm/runtime/interfaceSupport.hpp
#ifndef SHARE_VM_RUNTIME_INTERFACESUPPORT_HPP
#define SHARE_VM_RUNTIME_INTERFACESUPPORT_HPP
#include "memory/gcLocker.hpp"
#include "runtime/handles.inline.hpp"
#include "runtime/mutexLocker.hpp"
#include "runtime/orderAccess.hpp"
#include "runtime/os.hpp"
#include "runtime/safepoint.hpp"
#include "runtime/thread.inline.hpp"
#include "runtime/vmThread.hpp"
#include "utilities/globalDefinitions.hpp"
#include "utilities/preserveException.hpp"
#include "utilities/top.hpp"
class HandleMarkCleaner: public StackObj {
private:
Thread* _thread;
public:
HandleMarkCleaner(Thread* thread) {
_thread = thread;
_thread->last_handle_mark()->push();
}
~HandleMarkCleaner() {
_thread->last_handle_mark()->pop_and_restore();
}
private:
inline void* operator new(size_t size, void* ptr) throw() {
return ptr;
}
};
class InterfaceSupport: AllStatic {
# ifdef ASSERT
public:
static long _scavenge_alot_counter;
static long _fullgc_alot_counter;
static long _number_of_calls;
static long _fullgc_alot_invocation;
static void trace(const char* result_type, const char* header);
static void check_gc_alot() { if (ScavengeALot || FullGCALot) gc_alot(); }
static void gc_alot();
static void walk_stack_from(vframe* start_vf);
static void walk_stack();
# ifdef ENABLE_ZAP_DEAD_LOCALS
static void zap_dead_locals_old();
# endif
static void zombieAll();
static void unlinkSymbols();
static void deoptimizeAll();
static void stress_derived_pointers();
static void verify_stack();
static void verify_last_frame();
# endif
public:
#ifdef TARGET_OS_FAMILY_linux
# include "interfaceSupport_linux.hpp"
#endif
#ifdef TARGET_OS_FAMILY_solaris
# include "interfaceSupport_solaris.hpp"
#endif
#ifdef TARGET_OS_FAMILY_windows
# include "interfaceSupport_windows.hpp"
#endif
#ifdef TARGET_OS_FAMILY_aix
# include "interfaceSupport_aix.hpp"
#endif
#ifdef TARGET_OS_FAMILY_bsd
# include "interfaceSupport_bsd.hpp"
#endif
};
class ThreadStateTransition : public StackObj {
protected:
JavaThread* _thread;
public:
ThreadStateTransition(JavaThread *thread) {
_thread = thread;
assert(thread != NULL && thread->is_Java_thread(), "must be Java thread");
}
static inline void transition(JavaThread *thread, JavaThreadState from, JavaThreadState to) {
assert(from != _thread_in_Java, "use transition_from_java");
assert(from != _thread_in_native, "use transition_from_native");
assert((from & 1) == 0 && (to & 1) == 0, "odd numbers are transitions states");
assert(thread->thread_state() == from, "coming from wrong thread state");
thread->set_thread_state((JavaThreadState)(from + 1));
if (os::is_MP()) {
if (UseMembar) {
OrderAccess::fence();
} else {
os::write_memory_serialize_page(thread);
}
}
if (SafepointSynchronize::do_call_back()) {
SafepointSynchronize::block(thread);
}
thread->set_thread_state(to);
CHECK_UNHANDLED_OOPS_ONLY(thread->clear_unhandled_oops();)
}
static inline void transition_and_fence(JavaThread *thread, JavaThreadState from, JavaThreadState to) {
assert(thread->thread_state() == from, "coming from wrong thread state");
assert((from & 1) == 0 && (to & 1) == 0, "odd numbers are transitions states");
thread->set_thread_state((JavaThreadState)(from + 1));
if (os::is_MP()) {
if (UseMembar) {
OrderAccess::fence();
} else {
InterfaceSupport::serialize_memory(thread);
}
}
if (SafepointSynchronize::do_call_back()) {
SafepointSynchronize::block(thread);
}
thread->set_thread_state(to);
CHECK_UNHANDLED_OOPS_ONLY(thread->clear_unhandled_oops();)
}
static inline void transition_from_java(JavaThread *thread, JavaThreadState to) {
assert(thread->thread_state() == _thread_in_Java, "coming from wrong thread state");
thread->set_thread_state(to);
}
static inline void transition_from_native(JavaThread *thread, JavaThreadState to) {
assert((to & 1) == 0, "odd numbers are transitions states");
assert(thread->thread_state() == _thread_in_native, "coming from wrong thread state");
thread->set_thread_state(_thread_in_native_trans);
if (os::is_MP()) {
if (UseMembar) {
OrderAccess::fence();
} else {
InterfaceSupport::serialize_memory(thread);
}
}
if (SafepointSynchronize::do_call_back() || thread->is_suspend_after_native()) {
JavaThread::check_safepoint_and_suspend_for_native_trans(thread);
CHECK_UNHANDLED_OOPS_ONLY(thread->clear_unhandled_oops();)
}
thread->set_thread_state(to);
}
protected:
void trans(JavaThreadState from, JavaThreadState to) { transition(_thread, from, to); }
void trans_from_java(JavaThreadState to) { transition_from_java(_thread, to); }
void trans_from_native(JavaThreadState to) { transition_from_native(_thread, to); }
void trans_and_fence(JavaThreadState from, JavaThreadState to) { transition_and_fence(_thread, from, to); }
};
class ThreadInVMfromJava : public ThreadStateTransition {
public:
ThreadInVMfromJava(JavaThread* thread) : ThreadStateTransition(thread) {
trans_from_java(_thread_in_vm);
}
~ThreadInVMfromJava() {
trans(_thread_in_vm, _thread_in_Java);
if (_thread->has_special_runtime_exit_condition()) _thread->handle_special_runtime_exit_condition();
}
};
class ThreadInVMfromUnknown {
private:
JavaThread* _thread;
public:
ThreadInVMfromUnknown() : _thread(NULL) {
Thread* t = Thread::current();
if (t->is_Java_thread()) {
JavaThread* t2 = (JavaThread*) t;
if (t2->thread_state() == _thread_in_native) {
_thread = t2;
ThreadStateTransition::transition_from_native(t2, _thread_in_vm);
}
}
}
~ThreadInVMfromUnknown() {
if (_thread) {
ThreadStateTransition::transition_and_fence(_thread, _thread_in_vm, _thread_in_native);
}
}
};
class ThreadInVMfromNative : public ThreadStateTransition {
public:
ThreadInVMfromNative(JavaThread* thread) : ThreadStateTransition(thread) {
trans_from_native(_thread_in_vm);
}
~ThreadInVMfromNative() {
trans_and_fence(_thread_in_vm, _thread_in_native);
}
};
class ThreadToNativeFromVM : public ThreadStateTransition {
public:
ThreadToNativeFromVM(JavaThread *thread) : ThreadStateTransition(thread) {
assert(!thread->owns_locks(), "must release all locks when leaving VM");
thread->frame_anchor()->make_walkable(thread);
trans_and_fence(_thread_in_vm, _thread_in_native);
if (_thread->has_special_runtime_exit_condition()) _thread->handle_special_runtime_exit_condition(false);
}
~ThreadToNativeFromVM() {
trans_from_native(_thread_in_vm);
}
};
class ThreadBlockInVM : public ThreadStateTransition {
public:
ThreadBlockInVM(JavaThread *thread)
: ThreadStateTransition(thread) {
thread->frame_anchor()->make_walkable(thread);
trans_and_fence(_thread_in_vm, _thread_blocked);
}
~ThreadBlockInVM() {
trans_and_fence(_thread_blocked, _thread_in_vm);
}
};
class ThreadInVMfromJavaNoAsyncException : public ThreadStateTransition {
public:
ThreadInVMfromJavaNoAsyncException(JavaThread* thread) : ThreadStateTransition(thread) {
trans_from_java(_thread_in_vm);
}
~ThreadInVMfromJavaNoAsyncException() {
trans(_thread_in_vm, _thread_in_Java);
if (_thread->has_special_runtime_exit_condition())
_thread->handle_special_runtime_exit_condition(false);
}
};
#ifdef ASSERT
class VMEntryWrapper {
public:
VMEntryWrapper() {
if (VerifyLastFrame) {
InterfaceSupport::verify_last_frame();
}
}
~VMEntryWrapper() {
InterfaceSupport::check_gc_alot();
if (WalkStackALot) {
InterfaceSupport::walk_stack();
}
#ifdef ENABLE_ZAP_DEAD_LOCALS
if (ZapDeadLocalsOld) {
InterfaceSupport::zap_dead_locals_old();
}
#endif
#ifdef COMPILER2
if (StressDerivedPointers) {
InterfaceSupport::stress_derived_pointers();
}
#endif
if (DeoptimizeALot || DeoptimizeRandom) {
InterfaceSupport::deoptimizeAll();
}
if (ZombieALot) {
InterfaceSupport::zombieAll();
}
if (UnlinkSymbolsALot) {
InterfaceSupport::unlinkSymbols();
}
if (VerifyStack) {
InterfaceSupport::verify_stack();
}
}
};
class VMNativeEntryWrapper {
public:
VMNativeEntryWrapper() {
if (GCALotAtAllSafepoints) InterfaceSupport::check_gc_alot();
}
~VMNativeEntryWrapper() {
if (GCALotAtAllSafepoints) InterfaceSupport::check_gc_alot();
}
};
#endif
#ifdef ASSERT
class RuntimeHistogramElement : public HistogramElement {
public:
RuntimeHistogramElement(const char* name);
};
#define TRACE_CALL(result_type, header) \
InterfaceSupport::_number_of_calls++; \
if (TraceRuntimeCalls) \
InterfaceSupport::trace(#result_type, #header); \
if (CountRuntimeCalls) { \
static RuntimeHistogramElement* e = new RuntimeHistogramElement(#header); \
if (e != NULL) e->increment_count(); \
}
#else
#define TRACE_CALL(result_type, header) \
#endif
#define VM_LEAF_BASE(result_type, header) \
TRACE_CALL(result_type, header) \
debug_only(NoHandleMark __hm;) \
os::verify_stack_alignment(); \
#define VM_ENTRY_BASE_FROM_LEAF(result_type, header, thread) \
TRACE_CALL(result_type, header) \
debug_only(ResetNoHandleMark __rnhm;) \
HandleMarkCleaner __hm(thread); \
Thread* THREAD = thread; \
os::verify_stack_alignment(); \
#define VM_ENTRY_BASE(result_type, header, thread) \
TRACE_CALL(result_type, header) \
HandleMarkCleaner __hm(thread); \
Thread* THREAD = thread; \
os::verify_stack_alignment(); \
#define VM_QUICK_ENTRY_BASE(result_type, header, thread) \
TRACE_CALL(result_type, header) \
debug_only(NoHandleMark __hm;) \
Thread* THREAD = thread; \
os::verify_stack_alignment(); \
#define IRT_ENTRY(result_type, header) \
result_type header { \
ThreadInVMfromJava __tiv(thread); \
VM_ENTRY_BASE(result_type, header, thread) \
debug_only(VMEntryWrapper __vew;)
#define IRT_LEAF(result_type, header) \
result_type header { \
VM_LEAF_BASE(result_type, header) \
debug_only(No_Safepoint_Verifier __nspv(true);)
#define IRT_ENTRY_NO_ASYNC(result_type, header) \
result_type header { \
ThreadInVMfromJavaNoAsyncException __tiv(thread); \
VM_ENTRY_BASE(result_type, header, thread) \
debug_only(VMEntryWrapper __vew;)
#define IRT_END }
#define JRT_ENTRY(result_type, header) \
result_type header { \
ThreadInVMfromJava __tiv(thread); \
VM_ENTRY_BASE(result_type, header, thread) \
debug_only(VMEntryWrapper __vew;)
#define JRT_LEAF(result_type, header) \
result_type header { \
VM_LEAF_BASE(result_type, header) \
debug_only(JRT_Leaf_Verifier __jlv;)
#define JRT_ENTRY_NO_ASYNC(result_type, header) \
result_type header { \
ThreadInVMfromJavaNoAsyncException __tiv(thread); \
VM_ENTRY_BASE(result_type, header, thread) \
debug_only(VMEntryWrapper __vew;)
#define JRT_BLOCK_ENTRY(result_type, header) \
result_type header { \
TRACE_CALL(result_type, header) \
HandleMarkCleaner __hm(thread);
#define JRT_BLOCK \
{ \
ThreadInVMfromJava __tiv(thread); \
Thread* THREAD = thread; \
debug_only(VMEntryWrapper __vew;)
#define JRT_BLOCK_END }
#define JRT_END }
#define JNI_ENTRY(result_type, header) \
JNI_ENTRY_NO_PRESERVE(result_type, header) \
WeakPreserveExceptionMark __wem(thread);
#define JNI_ENTRY_NO_PRESERVE(result_type, header) \
extern "C" { \
result_type JNICALL header { \
JavaThread* thread=JavaThread::thread_from_jni_environment(env); \
assert( !VerifyJNIEnvThread || (thread == Thread::current()), "JNIEnv is only valid in same thread"); \
ThreadInVMfromNative __tiv(thread); \
debug_only(VMNativeEntryWrapper __vew;) \
VM_ENTRY_BASE(result_type, header, thread)
#define JNI_QUICK_ENTRY(result_type, header) \
extern "C" { \
result_type JNICALL header { \
JavaThread* thread=JavaThread::thread_from_jni_environment(env); \
assert( !VerifyJNIEnvThread || (thread == Thread::current()), "JNIEnv is only valid in same thread"); \
ThreadInVMfromNative __tiv(thread); \
debug_only(VMNativeEntryWrapper __vew;) \
VM_QUICK_ENTRY_BASE(result_type, header, thread)
#define JNI_LEAF(result_type, header) \
extern "C" { \
result_type JNICALL header { \
JavaThread* thread=JavaThread::thread_from_jni_environment(env); \
assert( !VerifyJNIEnvThread || (thread == Thread::current()), "JNIEnv is only valid in same thread"); \
VM_LEAF_BASE(result_type, header)
#define JNI_END } }
#define JVM_ENTRY(result_type, header) \
extern "C" { \
result_type JNICALL header { \
JavaThread* thread=JavaThread::thread_from_jni_environment(env); \
ThreadInVMfromNative __tiv(thread); \
debug_only(VMNativeEntryWrapper __vew;) \
VM_ENTRY_BASE(result_type, header, thread)
#define JVM_ENTRY_NO_ENV(result_type, header) \
extern "C" { \
result_type JNICALL header { \
JavaThread* thread = (JavaThread*)ThreadLocalStorage::thread(); \
ThreadInVMfromNative __tiv(thread); \
debug_only(VMNativeEntryWrapper __vew;) \
VM_ENTRY_BASE(result_type, header, thread)
#define JVM_QUICK_ENTRY(result_type, header) \
extern "C" { \
result_type JNICALL header { \
JavaThread* thread=JavaThread::thread_from_jni_environment(env); \
ThreadInVMfromNative __tiv(thread); \
debug_only(VMNativeEntryWrapper __vew;) \
VM_QUICK_ENTRY_BASE(result_type, header, thread)
#define JVM_LEAF(result_type, header) \
extern "C" { \
result_type JNICALL header { \
VM_Exit::block_if_vm_exited(); \
VM_LEAF_BASE(result_type, header)
#define JVM_ENTRY_FROM_LEAF(env, result_type, header) \
{ { \
JavaThread* thread=JavaThread::thread_from_jni_environment(env); \
ThreadInVMfromNative __tiv(thread); \
debug_only(VMNativeEntryWrapper __vew;) \
VM_ENTRY_BASE_FROM_LEAF(result_type, header, thread)
#define JVM_END } }
#endif // SHARE_VM_RUNTIME_INTERFACESUPPORT_HPP
C:\hotspot-69087d08d473\src\share\vm/runtime/java.cpp
#include "precompiled.hpp"
#include "classfile/classLoader.hpp"
#include "classfile/symbolTable.hpp"
#include "classfile/systemDictionary.hpp"
#include "code/codeCache.hpp"
#include "compiler/compileBroker.hpp"
#include "compiler/compilerOracle.hpp"
#include "interpreter/bytecodeHistogram.hpp"
#include "jfr/jfrEvents.hpp"
#include "jfr/support/jfrThreadId.hpp"
#include "memory/genCollectedHeap.hpp"
#include "memory/oopFactory.hpp"
#include "memory/universe.hpp"
#include "oops/constantPool.hpp"
#include "oops/generateOopMap.hpp"
#include "oops/instanceKlass.hpp"
#include "oops/instanceOop.hpp"
#include "oops/method.hpp"
#include "oops/objArrayOop.hpp"
#include "oops/oop.inline.hpp"
#include "oops/symbol.hpp"
#include "prims/jvmtiExport.hpp"
#include "runtime/arguments.hpp"
#include "runtime/biasedLocking.hpp"
#include "runtime/compilationPolicy.hpp"
#include "runtime/deoptimization.hpp"
#include "runtime/fprofiler.hpp"
#include "runtime/init.hpp"
#include "runtime/interfaceSupport.hpp"
#include "runtime/java.hpp"
#include "runtime/memprofiler.hpp"
#include "runtime/sharedRuntime.hpp"
#include "runtime/statSampler.hpp"
#include "runtime/sweeper.hpp"
#include "runtime/task.hpp"
#include "runtime/thread.inline.hpp"
#include "runtime/timer.hpp"
#include "runtime/vm_operations.hpp"
#include "services/memTracker.hpp"
#include "utilities/dtrace.hpp"
#include "utilities/globalDefinitions.hpp"
#include "utilities/histogram.hpp"
#include "utilities/macros.hpp"
#include "utilities/vmError.hpp"
#ifdef TARGET_ARCH_x86
# include "vm_version_x86.hpp"
#endif
#ifdef TARGET_ARCH_aarch64
# include "vm_version_aarch64.hpp"
#endif
#ifdef TARGET_ARCH_sparc
# include "vm_version_sparc.hpp"
#endif
#ifdef TARGET_ARCH_zero
# include "vm_version_zero.hpp"
#endif
#ifdef TARGET_ARCH_arm
# include "vm_version_arm.hpp"
#endif
#ifdef TARGET_ARCH_ppc
# include "vm_version_ppc.hpp"
#endif
#if INCLUDE_ALL_GCS
#include "gc_implementation/concurrentMarkSweep/concurrentMarkSweepThread.hpp"
#include "gc_implementation/parallelScavenge/psScavenge.hpp"
#include "gc_implementation/parallelScavenge/psScavenge.inline.hpp"
#endif // INCLUDE_ALL_GCS
#ifdef COMPILER1
#include "c1/c1_Compiler.hpp"
#include "c1/c1_Runtime1.hpp"
#endif
#ifdef COMPILER2
#include "code/compiledIC.hpp"
#include "compiler/methodLiveness.hpp"
#include "opto/compile.hpp"
#include "opto/indexSet.hpp"
#include "opto/runtime.hpp"
#endif
#if INCLUDE_JFR
#include "jfr/jfr.hpp"
#endif
#ifndef USDT2
HS_DTRACE_PROBE_DECL(hotspot, vm__shutdown);
#endif /* !USDT2 */
#ifndef PRODUCT
GrowableArray<Method*>* collected_invoked_methods;
void collect_invoked_methods(Method* m) {
if (m->invocation_count() + m->compiled_invocation_count() >= 1 ) {
collected_invoked_methods->push(m);
}
}
PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
GrowableArray<Method*>* collected_profiled_methods;
void collect_profiled_methods(Method* m) {
Thread* thread = Thread::current();
HandleMark hm(thread);
methodHandle mh(thread, m);
if ((m->method_data() != NULL) &&
(PrintMethodData || CompilerOracle::should_print(mh))) {
collected_profiled_methods->push(m);
}
}
int compare_methods(Method** a, Method** b) {
return ((*b)->invocation_count() + (*b)->compiled_invocation_count())
- ((*a)->invocation_count() + (*a)->compiled_invocation_count());
}
void print_method_invocation_histogram() {
ResourceMark rm;
HandleMark hm;
collected_invoked_methods = new GrowableArray<Method*>(1024);
SystemDictionary::methods_do(collect_invoked_methods);
collected_invoked_methods->sort(&compare_methods);
tty->cr();
tty->print_cr("Histogram Over MethodOop Invocation Counters (cutoff = %d):", MethodHistogramCutoff);
tty->cr();
tty->print_cr("____Count_(I+C)____Method________________________Module_________________");
unsigned total = 0, int_total = 0, comp_total = 0, static_total = 0, final_total = 0,
synch_total = 0, nativ_total = 0, acces_total = 0;
for (int index = 0; index < collected_invoked_methods->length(); index++) {
Method* m = collected_invoked_methods->at(index);
int c = m->invocation_count() + m->compiled_invocation_count();
if (c >= MethodHistogramCutoff) m->print_invocation_count();
int_total += m->invocation_count();
comp_total += m->compiled_invocation_count();
if (m->is_final()) final_total += c;
if (m->is_static()) static_total += c;
if (m->is_synchronized()) synch_total += c;
if (m->is_native()) nativ_total += c;
if (m->is_accessor()) acces_total += c;
}
tty->cr();
total = int_total + comp_total;
tty->print_cr("Invocations summary:");
tty->print_cr("\t%9d (%4.1f%%) interpreted", int_total, 100.0 * int_total / total);
tty->print_cr("\t%9d (%4.1f%%) compiled", comp_total, 100.0 * comp_total / total);
tty->print_cr("\t%9d (100%%) total", total);
tty->print_cr("\t%9d (%4.1f%%) synchronized", synch_total, 100.0 * synch_total / total);
tty->print_cr("\t%9d (%4.1f%%) final", final_total, 100.0 * final_total / total);
tty->print_cr("\t%9d (%4.1f%%) static", static_total, 100.0 * static_total / total);
tty->print_cr("\t%9d (%4.1f%%) native", nativ_total, 100.0 * nativ_total / total);
tty->print_cr("\t%9d (%4.1f%%) accessor", acces_total, 100.0 * acces_total / total);
tty->cr();
SharedRuntime::print_call_statistics(comp_total);
}
void print_method_profiling_data() {
ResourceMark rm;
HandleMark hm;
collected_profiled_methods = new GrowableArray<Method*>(1024);
SystemDictionary::methods_do(collect_profiled_methods);
collected_profiled_methods->sort(&compare_methods);
int count = collected_profiled_methods->length();
int total_size = 0;
if (count > 0) {
for (int index = 0; index < count; index++) {
Method* m = collected_profiled_methods->at(index);
ttyLocker ttyl;
tty->print_cr("------------------------------------------------------------------------");
m->print_invocation_count();
tty->print_cr(" mdo size: %d bytes", m->method_data()->size_in_bytes());
tty->cr();
if (m->method_data() != NULL && m->method_data()->parameters_type_data() != NULL) {
tty->fill_to(2);
m->method_data()->parameters_type_data()->print_data_on(tty);
}
m->print_codes();
total_size += m->method_data()->size_in_bytes();
}
tty->print_cr("------------------------------------------------------------------------");
tty->print_cr("Total MDO size: %d bytes", total_size);
}
}
void print_bytecode_count() {
if (CountBytecodes || TraceBytecodes || StopInterpreterAt) {
tty->print_cr("[BytecodeCounter::counter_value = %d]", BytecodeCounter::counter_value());
}
}
AllocStats alloc_stats;
void print_statistics() {
#ifdef ASSERT
if (CountRuntimeCalls) {
extern Histogram *RuntimeHistogram;
RuntimeHistogram->print();
}
if (CountJNICalls) {
extern Histogram *JNIHistogram;
JNIHistogram->print();
}
if (CountJVMCalls) {
extern Histogram *JVMHistogram;
JVMHistogram->print();
}
#endif
if (MemProfiling) {
MemProfiler::disengage();
}
if (CITime) {
CompileBroker::print_times();
}
#ifdef COMPILER1
if ((PrintC1Statistics || LogVMOutput || LogCompilation) && UseCompiler) {
FlagSetting fs(DisplayVMOutput, DisplayVMOutput && PrintC1Statistics);
Runtime1::print_statistics();
Deoptimization::print_statistics();
SharedRuntime::print_statistics();
nmethod::print_statistics();
}
#endif /* COMPILER1 */
#ifdef COMPILER2
if ((PrintOptoStatistics || LogVMOutput || LogCompilation) && UseCompiler) {
FlagSetting fs(DisplayVMOutput, DisplayVMOutput && PrintOptoStatistics);
Compile::print_statistics();
#ifndef COMPILER1
Deoptimization::print_statistics();
nmethod::print_statistics();
SharedRuntime::print_statistics();
#endif //COMPILER1
os::print_statistics();
}
if (PrintLockStatistics || PrintPreciseBiasedLockingStatistics || PrintPreciseRTMLockingStatistics) {
OptoRuntime::print_named_counters();
}
if (TimeLivenessAnalysis) {
MethodLiveness::print_times();
}
#ifdef ASSERT
if (CollectIndexSetStatistics) {
IndexSet::print_statistics();
}
#endif // ASSERT
#endif // COMPILER2
if (CountCompiledCalls) {
print_method_invocation_histogram();
}
if (ProfileInterpreter COMPILER1_PRESENT(|| C1UpdateMethodData)) {
print_method_profiling_data();
}
if (TimeCompiler) {
COMPILER2_PRESENT(Compile::print_timers();)
}
if (TimeCompilationPolicy) {
CompilationPolicy::policy()->print_time();
}
if (TimeOopMap) {
GenerateOopMap::print_time();
}
if (ProfilerCheckIntervals) {
PeriodicTask::print_intervals();
}
if (PrintSymbolTableSizeHistogram) {
SymbolTable::print_histogram();
}
if (CountBytecodes || TraceBytecodes || StopInterpreterAt) {
BytecodeCounter::print();
}
if (PrintBytecodePairHistogram) {
BytecodePairHistogram::print();
}
if (PrintCodeCache) {
MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
CodeCache::print();
}
if (PrintMethodFlushingStatistics) {
NMethodSweeper::print();
}
if (PrintCodeCache2) {
MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
CodeCache::print_internals();
}
if (PrintClassStatistics) {
SystemDictionary::print_class_statistics();
}
if (PrintMethodStatistics) {
SystemDictionary::print_method_statistics();
}
if (PrintVtableStats) {
klassVtable::print_statistics();
klassItable::print_statistics();
}
if (VerifyOops && Verbose) {
tty->print_cr("+VerifyOops count: %d", StubRoutines::verify_oop_count());
}
print_bytecode_count();
if (PrintMallocStatistics) {
tty->print("allocation stats: ");
alloc_stats.print();
tty->cr();
}
if (PrintSystemDictionaryAtExit) {
SystemDictionary::print();
}
if (PrintBiasedLockingStatistics) {
BiasedLocking::print_counters();
}
#ifdef ENABLE_ZAP_DEAD_LOCALS
#ifdef COMPILER2
if (ZapDeadCompiledLocals) {
tty->print_cr("Compile::CompiledZap_count = %d", Compile::CompiledZap_count);
tty->print_cr("OptoRuntime::ZapDeadCompiledLocals_count = %d", OptoRuntime::ZapDeadCompiledLocals_count);
}
#endif // COMPILER2
#endif // ENABLE_ZAP_DEAD_LOCALS
if (PrintNMTStatistics) {
MemTracker::final_report(tty);
}
}
#else // PRODUCT MODE STATISTICS
void print_statistics() {
if (CITime) {
CompileBroker::print_times();
}
if (PrintCodeCache) {
MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
CodeCache::print();
}
if (PrintMethodFlushingStatistics) {
NMethodSweeper::print();
}
#ifdef COMPILER2
if (PrintPreciseBiasedLockingStatistics || PrintPreciseRTMLockingStatistics) {
OptoRuntime::print_named_counters();
}
#endif
if (PrintBiasedLockingStatistics) {
BiasedLocking::print_counters();
}
if (PrintNMTStatistics) {
MemTracker::final_report(tty);
}
}
#endif
extern "C" {
typedef void (*__exit_proc)(void);
}
class ExitProc : public CHeapObj<mtInternal> {
private:
__exit_proc _proc;
ExitProc* _next;
public:
ExitProc(__exit_proc proc) {
_proc = proc;
_next = NULL;
}
void evaluate() { _proc(); }
ExitProc* next() const { return _next; }
void set_next(ExitProc* next) { _next = next; }
};
static ExitProc* exit_procs = NULL;
extern "C" {
void register_on_exit_function(void (*func)(void)) {
ExitProc *entry = new ExitProc(func);
if (entry != NULL) {
entry->set_next(exit_procs);
exit_procs = entry;
}
}
}
void before_exit(JavaThread * thread) {
#define BEFORE_EXIT_NOT_RUN 0
#define BEFORE_EXIT_RUNNING 1
#define BEFORE_EXIT_DONE 2
static jint volatile _before_exit_status = BEFORE_EXIT_NOT_RUN;
{ MutexLocker ml(BeforeExit_lock);
switch (_before_exit_status) {
case BEFORE_EXIT_NOT_RUN:
_before_exit_status = BEFORE_EXIT_RUNNING;
break;
case BEFORE_EXIT_RUNNING:
while (_before_exit_status == BEFORE_EXIT_RUNNING) {
BeforeExit_lock->wait();
}
assert(_before_exit_status == BEFORE_EXIT_DONE, "invalid state");
return;
case BEFORE_EXIT_DONE:
return;
}
}
ExitProc* current = exit_procs;
while (current != NULL) {
ExitProc* next = current->next();
current->evaluate();
delete current;
current = next;
}
if (ShowMessageBoxOnError && is_error_reported()) {
os::infinite_sleep();
}
if (PeriodicTask::num_tasks() > 0)
WatcherThread::stop();
if (Arguments::has_profile()) {
FlatProfiler::disengage();
FlatProfiler::print(10);
}
StatSampler::disengage();
StatSampler::destroy();
Universe::heap()->stop();
if (PrintGCDetails) {
Universe::print();
AdaptiveSizePolicyOutput(0);
if (Verbose) {
ClassLoaderDataGraph::dump_on(gclog_or_tty);
}
}
if (PrintBytecodeHistogram) {
BytecodeHistogram::print();
}
if (JvmtiExport::should_post_thread_life()) {
JvmtiExport::post_thread_end(thread);
}
EventThreadEnd event;
if (event.should_commit()) {
event.set_thread(JFR_THREAD_ID(thread));
event.commit();
}
JFR_ONLY(Jfr::on_vm_shutdown();)
JvmtiExport::post_vm_death();
Threads::shutdown_vm_agents();
os::terminate_signal_thread();
print_statistics();
Universe::heap()->print_tracing_info();
{ MutexLocker ml(BeforeExit_lock);
_before_exit_status = BEFORE_EXIT_DONE;
BeforeExit_lock->notify_all();
}
if (VerifyStringTableAtExit) {
int fail_cnt = 0;
{
MutexLocker ml(StringTable_lock);
fail_cnt = StringTable::verify_and_compare_entries();
}
if (fail_cnt != 0) {
tty->print_cr("ERROR: fail_cnt=%d", fail_cnt);
guarantee(fail_cnt == 0, "unexpected StringTable verification failures");
}
}
#undef BEFORE_EXIT_NOT_RUN
#undef BEFORE_EXIT_RUNNING
#undef BEFORE_EXIT_DONE
}
void vm_exit(int code) {
Thread* thread = ThreadLocalStorage::is_initialized() ?
ThreadLocalStorage::get_thread_slow() : NULL;
if (thread == NULL) {
vm_direct_exit(code);
}
if (VMThread::vm_thread() != NULL) {
VM_Exit op(code);
if (thread->is_Java_thread())
((JavaThread*)thread)->set_thread_state(_thread_in_vm);
VMThread::execute(&op);
vm_direct_exit(code);
} else {
vm_direct_exit(code);
}
ShouldNotReachHere();
}
void notify_vm_shutdown() {
#ifndef USDT2
HS_DTRACE_PROBE(hotspot, vm__shutdown);
HS_DTRACE_WORKAROUND_TAIL_CALL_BUG();
#else /* USDT2 */
HOTSPOT_VM_SHUTDOWN();
#endif /* USDT2 */
}
void vm_direct_exit(int code) {
notify_vm_shutdown();
os::wait_for_keypress_at_exit();
::exit(code);
}
void vm_perform_shutdown_actions() {
if (is_init_completed()) {
Thread* thread = ThreadLocalStorage::is_initialized() ?
ThreadLocalStorage::get_thread_slow() : NULL;
if (thread != NULL && thread->is_Java_thread()) {
JavaThread* jt = (JavaThread*)thread;
jt->frame_anchor()->make_walkable(jt);
jt->set_thread_state(_thread_in_native);
}
}
notify_vm_shutdown();
}
void vm_shutdown()
{
vm_perform_shutdown_actions();
os::wait_for_keypress_at_exit();
os::shutdown();
}
void vm_abort(bool dump_core) {
vm_perform_shutdown_actions();
os::wait_for_keypress_at_exit();
os::abort(dump_core);
ShouldNotReachHere();
}
void vm_notify_during_shutdown(const char* error, const char* message) {
if (error != NULL) {
tty->print_cr("Error occurred during initialization of VM");
tty->print("%s", error);
if (message != NULL) {
tty->print_cr(": %s", message);
}
else {
tty->cr();
}
}
if (ShowMessageBoxOnError && WizardMode) {
fatal("Error occurred during initialization of VM");
}
}
void vm_exit_during_initialization(Handle exception) {
tty->print_cr("Error occurred during initialization of VM");
Thread *THREAD = Thread::current();
if (HAS_PENDING_EXCEPTION) {
CLEAR_PENDING_EXCEPTION;
}
java_lang_Throwable::print(exception, tty);
tty->cr();
java_lang_Throwable::print_stack_trace(exception(), tty);
tty->cr();
vm_notify_during_shutdown(NULL, NULL);
vm_abort(false);
}
void vm_exit_during_initialization(Symbol* ex, const char* message) {
ResourceMark rm;
vm_notify_during_shutdown(ex->as_C_string(), message);
vm_abort(false);
}
void vm_exit_during_initialization(const char* error, const char* message) {
vm_notify_during_shutdown(error, message);
vm_abort(false);
}
void vm_shutdown_during_initialization(const char* error, const char* message) {
vm_notify_during_shutdown(error, message);
vm_shutdown();
}
JDK_Version JDK_Version::_current;
const char* JDK_Version::_runtime_name;
const char* JDK_Version::_runtime_version;
void JDK_Version::initialize() {
jdk_version_info info;
assert(!_current.is_valid(), "Don't initialize twice");
void *lib_handle = os::native_java_library();
jdk_version_info_fn_t func = CAST_TO_FN_PTR(jdk_version_info_fn_t,
os::dll_lookup(lib_handle, "JDK_GetVersionInfo0"));
if (func == NULL) {
_current._partially_initialized = true;
} else {
(*func)(&info, sizeof(info));
int major = JDK_VERSION_MAJOR(info.jdk_version);
int minor = JDK_VERSION_MINOR(info.jdk_version);
int micro = JDK_VERSION_MICRO(info.jdk_version);
int build = JDK_VERSION_BUILD(info.jdk_version);
if (major == 1 && minor > 4) {
major = minor;
minor = micro;
micro = 0;
}
_current = JDK_Version(major, minor, micro, info.update_version,
info.special_update_version, build,
info.thread_park_blocker == 1,
info.post_vm_init_hook_enabled == 1,
info.pending_list_uses_discovered_field == 1);
}
}
void JDK_Version::fully_initialize(
uint8_t major, uint8_t minor, uint8_t micro, uint8_t update) {
assert(major < 6, "not needed for JDK version >= 6");
assert(is_partially_initialized(), "must not initialize");
if (major < 5) {
micro = minor;
minor = major;
major = 1;
}
_current = JDK_Version(major, minor, micro, update);
}
void JDK_Version_init() {
JDK_Version::initialize();
}
static int64_t encode_jdk_version(const JDK_Version& v) {
return
((int64_t)v.major_version() << (BitsPerByte * 5)) |
((int64_t)v.minor_version() << (BitsPerByte * 4)) |
((int64_t)v.micro_version() << (BitsPerByte * 3)) |
((int64_t)v.update_version() << (BitsPerByte * 2)) |
((int64_t)v.special_update_version() << (BitsPerByte * 1)) |
((int64_t)v.build_number() << (BitsPerByte * 0));
}
int JDK_Version::compare(const JDK_Version& other) const {
assert(is_valid() && other.is_valid(), "Invalid version (uninitialized?)");
if (!is_partially_initialized() && other.is_partially_initialized()) {
return -(other.compare(*this)); // flip the comparators
}
assert(!other.is_partially_initialized(), "Not initialized yet");
if (is_partially_initialized()) {
assert(other.major_version() >= 6,
"Invalid JDK version comparison during initialization");
return -1;
} else {
uint64_t e = encode_jdk_version(*this);
uint64_t o = encode_jdk_version(other);
return (e > o) ? 1 : ((e == o) ? 0 : -1);
}
}
void JDK_Version::to_string(char* buffer, size_t buflen) const {
assert(buffer && buflen > 0, "call with useful buffer");
size_t index = 0;
if (!is_valid()) {
jio_snprintf(buffer, buflen, "%s", "(uninitialized)");
} else if (is_partially_initialized()) {
jio_snprintf(buffer, buflen, "%s", "(uninitialized) pre-1.6.0");
} else {
int rc = jio_snprintf(
&buffer[index], buflen - index, "%d.%d", _major, _minor);
if (rc == -1) return;
index += rc;
if (_micro > 0) {
rc = jio_snprintf(&buffer[index], buflen - index, ".%d", _micro);
if (rc == -1) return;
index += rc;
}
if (_update > 0) {
rc = jio_snprintf(&buffer[index], buflen - index, "_%02d", _update);
if (rc == -1) return;
index += rc;
}
if (_special > 0) {
rc = jio_snprintf(&buffer[index], buflen - index, "%c", _special);
if (rc == -1) return;
index += rc;
}
if (_build > 0) {
rc = jio_snprintf(&buffer[index], buflen - index, "-b%02d", _build);
if (rc == -1) return;
index += rc;
}
}
}
C:\hotspot-69087d08d473\src\share\vm/runtime/java.hpp
#ifndef SHARE_VM_RUNTIME_JAVA_HPP
#define SHARE_VM_RUNTIME_JAVA_HPP
#include "runtime/os.hpp"
extern "C" { void register_on_exit_function(void (*func)(void)) ;}
extern void before_exit(JavaThread * thread);
extern void vm_exit(int code);
extern void vm_direct_exit(int code);
extern void vm_shutdown();
extern void vm_abort(bool dump_core=true);
extern void notify_vm_shutdown();
extern void vm_exit_during_initialization(Handle exception);
extern void vm_exit_during_initialization(Symbol* exception_name, const char* message);
extern void vm_exit_during_initialization(const char* error, const char* message = NULL);
extern void vm_shutdown_during_initialization(const char* error, const char* message = NULL);
class JDK_Version VALUE_OBJ_CLASS_SPEC {
friend class VMStructs;
friend class Universe;
friend void JDK_Version_init();
private:
static JDK_Version _current;
static const char* _runtime_name;
static const char* _runtime_version;
uint8_t _major;
uint8_t _minor;
uint8_t _micro;
uint16_t _update;
uint8_t _special;
uint8_t _build;
bool _partially_initialized;
bool _thread_park_blocker;
bool _pending_list_uses_discovered_field;
bool _post_vm_init_hook_enabled;
bool is_valid() const {
return (_major != 0 || _partially_initialized);
}
static void initialize();
static void fully_initialize(uint8_t major, uint8_t minor = 0,
uint8_t micro = 0, uint8_t update = 0);
public:
static bool is_partially_initialized() {
return _current._partially_initialized;
}
JDK_Version() : _major(0), _minor(0), _micro(0), _update(0),
_special(0), _build(0), _partially_initialized(false),
_thread_park_blocker(false), _post_vm_init_hook_enabled(false),
_pending_list_uses_discovered_field(false) {}
JDK_Version(uint8_t major, uint8_t minor = 0, uint8_t micro = 0,
uint16_t update = 0, uint8_t special = 0, uint8_t build = 0,
bool thread_park_blocker = false, bool post_vm_init_hook_enabled = false,
bool pending_list_uses_discovered_field = false) :
_major(major), _minor(minor), _micro(micro), _update(update),
_special(special), _build(build), _partially_initialized(false),
_thread_park_blocker(thread_park_blocker),
_post_vm_init_hook_enabled(post_vm_init_hook_enabled),
_pending_list_uses_discovered_field(pending_list_uses_discovered_field) {}
static JDK_Version current() { return _current; }
static JDK_Version jdk(uint8_t m) {
return JDK_Version(m);
}
static JDK_Version jdk_update(uint8_t major, uint16_t update_number) {
return JDK_Version(major, 0, 0, update_number);
}
uint8_t major_version() const { return _major; }
uint8_t minor_version() const { return _minor; }
uint8_t micro_version() const { return _micro; }
uint16_t update_version() const { return _update; }
uint8_t special_update_version() const { return _special; }
uint8_t build_number() const { return _build; }
bool supports_thread_park_blocker() const {
return _thread_park_blocker;
}
bool post_vm_init_hook_enabled() const {
return _post_vm_init_hook_enabled;
}
bool pending_list_uses_discovered_field() const {
return _pending_list_uses_discovered_field;
}
int compare(const JDK_Version& other) const;
int compare_major(int version) const {
if (_partially_initialized) {
if (version >= 6) {
return -1;
} else {
assert(false, "Can't make this comparison during init time");
return -1; // conservative
}
} else {
return major_version() - version;
}
}
void to_string(char* buffer, size_t buflen) const;
static const char* runtime_name() {
return _runtime_name;
}
static void set_runtime_name(const char* name) {
_runtime_name = name;
}
static const char* runtime_version() {
return _runtime_version;
}
static void set_runtime_version(const char* version) {
_runtime_version = version;
}
static bool is_jdk12x_version() {
return current().compare_major(2) == 0;
}
static bool is_jdk13x_version() {
return current().compare_major(3) == 0;
}
static bool is_jdk14x_version() {
return current().compare_major(4) == 0;
}
static bool is_jdk15x_version() {
return current().compare_major(5) == 0;
}
static bool is_jdk16x_version() {
return current().compare_major(6) == 0;
}
static bool is_jdk17x_version() {
return current().compare_major(7) == 0;
}
static bool is_jdk18x_version() {
return current().compare_major(8) == 0;
}
static bool is_gte_jdk13x_version() {
return current().compare_major(3) >= 0;
}
static bool is_gte_jdk14x_version() {
return current().compare_major(4) >= 0;
}
static bool is_gte_jdk15x_version() {
return current().compare_major(5) >= 0;
}
static bool is_gte_jdk16x_version() {
return current().compare_major(6) >= 0;
}
static bool is_gte_jdk17x_version() {
return current().compare_major(7) >= 0;
}
static bool is_gte_jdk18x_version() {
return current().compare_major(8) >= 0;
}
};
#endif // SHARE_VM_RUNTIME_JAVA_HPP
C:\hotspot-69087d08d473\src\share\vm/runtime/javaCalls.cpp
#include "precompiled.hpp"
#include "classfile/systemDictionary.hpp"
#include "classfile/vmSymbols.hpp"
#include "code/nmethod.hpp"
#include "compiler/compileBroker.hpp"
#include "interpreter/interpreter.hpp"
#include "interpreter/linkResolver.hpp"
#include "memory/universe.inline.hpp"
#include "oops/oop.inline.hpp"
#include "prims/jniCheck.hpp"
#include "runtime/compilationPolicy.hpp"
#include "runtime/handles.inline.hpp"
#include "runtime/interfaceSupport.hpp"
#include "runtime/javaCalls.hpp"
#include "runtime/mutexLocker.hpp"
#include "runtime/signature.hpp"
#include "runtime/stubRoutines.hpp"
#include "runtime/thread.inline.hpp"
JavaCallWrapper::JavaCallWrapper(methodHandle callee_method, Handle receiver, JavaValue* result, TRAPS) {
JavaThread* thread = (JavaThread *)THREAD;
bool clear_pending_exception = true;
guarantee(thread->is_Java_thread(), "crucial check - the VM thread cannot and must not escape to Java code");
assert(!thread->owns_locks(), "must release all locks when leaving VM");
guarantee(!thread->is_Compiler_thread(), "cannot make java calls from the compiler");
_result = result;
JNIHandleBlock* new_handles = JNIHandleBlock::allocate_block(thread);
ThreadStateTransition::transition(thread, _thread_in_vm, _thread_in_Java);
if (thread->has_special_runtime_exit_condition()) {
thread->handle_special_runtime_exit_condition();
if (HAS_PENDING_EXCEPTION) {
clear_pending_exception = false;
}
}
_callee_method = callee_method();
_receiver = receiver();
#ifdef CHECK_UNHANDLED_OOPS
THREAD->allow_unhandled_oop(&_receiver);
#endif // CHECK_UNHANDLED_OOPS
_thread = (JavaThread *)thread;
_handles = _thread->active_handles(); // save previous handle block & Java frame linkage
_anchor.copy(_thread->frame_anchor());
_thread->frame_anchor()->clear();
debug_only(_thread->inc_java_call_counter());
_thread->set_active_handles(new_handles); // install new handle block and reset Java frame linkage
assert (_thread->thread_state() != _thread_in_native, "cannot set native pc to NULL");
if(clear_pending_exception) {
_thread->clear_pending_exception();
}
if (_anchor.last_Java_sp() == NULL) {
_thread->record_base_of_stack_pointer();
}
}
JavaCallWrapper::~JavaCallWrapper() {
assert(_thread == JavaThread::current(), "must still be the same thread");
JNIHandleBlock *_old_handles = _thread->active_handles();
_thread->set_active_handles(_handles);
_thread->frame_anchor()->zap();
debug_only(_thread->dec_java_call_counter());
if (_anchor.last_Java_sp() == NULL) {
_thread->set_base_of_stack_pointer(NULL);
}
ThreadStateTransition::transition_from_java(_thread, _thread_in_vm);
_thread->frame_anchor()->copy(&_anchor);
JNIHandleBlock::release_block(_old_handles, _thread);
}
void JavaCallWrapper::oops_do(OopClosure* f) {
f->do_oop((oop*)&_receiver);
handles()->oops_do(f);
}
static BasicType runtime_type_from(JavaValue* result) {
switch (result->get_type()) {
case T_BOOLEAN: // fall through
case T_CHAR : // fall through
case T_SHORT : // fall through
case T_INT : // fall through
#ifndef _LP64
case T_OBJECT : // fall through
case T_ARRAY : // fall through
#endif
case T_BYTE : // fall through
case T_VOID : return T_INT;
case T_LONG : return T_LONG;
case T_FLOAT : return T_FLOAT;
case T_DOUBLE : return T_DOUBLE;
#ifdef _LP64
case T_ARRAY : // fall through
case T_OBJECT: return T_OBJECT;
#endif
}
ShouldNotReachHere();
return T_ILLEGAL;
}
void JavaCalls::call_default_constructor(JavaThread* thread, methodHandle method, Handle receiver, TRAPS) {
assert(method->name() == vmSymbols::object_initializer_name(), "Should only be called for default constructor");
assert(method->signature() == vmSymbols::void_method_signature(), "Should only be called for default constructor");
InstanceKlass* ik = method->method_holder();
if (ik->is_initialized() && ik->has_vanilla_constructor()) {
} else {
static JavaValue result(T_VOID);
JavaCallArguments args(receiver);
call(&result, method, &args, CHECK);
}
}
void JavaCalls::call_virtual(JavaValue* result, KlassHandle spec_klass, Symbol* name, Symbol* signature, JavaCallArguments* args, TRAPS) {
CallInfo callinfo;
Handle receiver = args->receiver();
KlassHandle recvrKlass(THREAD, receiver.is_null() ? (Klass*)NULL : receiver->klass());
LinkResolver::resolve_virtual_call(
callinfo, receiver, recvrKlass, spec_klass, name, signature,
KlassHandle(), false, true, CHECK);
methodHandle method = callinfo.selected_method();
assert(method.not_null(), "should have thrown exception");
JavaCalls::call(result, method, args, CHECK);
}
void JavaCalls::call_virtual(JavaValue* result, Handle receiver, KlassHandle spec_klass, Symbol* name, Symbol* signature, TRAPS) {
JavaCallArguments args(receiver); // One oop argument
call_virtual(result, spec_klass, name, signature, &args, CHECK);
}
void JavaCalls::call_virtual(JavaValue* result, Handle receiver, KlassHandle spec_klass, Symbol* name, Symbol* signature, Handle arg1, TRAPS) {
JavaCallArguments args(receiver); // One oop argument
args.push_oop(arg1);
call_virtual(result, spec_klass, name, signature, &args, CHECK);
}
void JavaCalls::call_virtual(JavaValue* result, Handle receiver, KlassHandle spec_klass, Symbol* name, Symbol* signature, Handle arg1, Handle arg2, TRAPS) {
JavaCallArguments args(receiver); // One oop argument
args.push_oop(arg1);
args.push_oop(arg2);
call_virtual(result, spec_klass, name, signature, &args, CHECK);
}
void JavaCalls::call_special(JavaValue* result, KlassHandle klass, Symbol* name, Symbol* signature, JavaCallArguments* args, TRAPS) {
CallInfo callinfo;
LinkResolver::resolve_special_call(callinfo, args->receiver(), klass, name, signature, KlassHandle(), false, CHECK);
methodHandle method = callinfo.selected_method();
assert(method.not_null(), "should have thrown exception");
JavaCalls::call(result, method, args, CHECK);
}
void JavaCalls::call_special(JavaValue* result, Handle receiver, KlassHandle klass, Symbol* name, Symbol* signature, TRAPS) {
JavaCallArguments args(receiver); // One oop argument
call_special(result, klass, name, signature, &args, CHECK);
}
void JavaCalls::call_special(JavaValue* result, Handle receiver, KlassHandle klass, Symbol* name, Symbol* signature, Handle arg1, TRAPS) {
JavaCallArguments args(receiver); // One oop argument
args.push_oop(arg1);
call_special(result, klass, name, signature, &args, CHECK);
}
void JavaCalls::call_special(JavaValue* result, Handle receiver, KlassHandle klass, Symbol* name, Symbol* signature, Handle arg1, Handle arg2, TRAPS) {
JavaCallArguments args(receiver); // One oop argument
args.push_oop(arg1);
args.push_oop(arg2);
call_special(result, klass, name, signature, &args, CHECK);
}
void JavaCalls::call_static(JavaValue* result, KlassHandle klass, Symbol* name, Symbol* signature, JavaCallArguments* args, TRAPS) {
CallInfo callinfo;
LinkResolver::resolve_static_call(callinfo, klass, name, signature, KlassHandle(), false, true, CHECK);
methodHandle method = callinfo.selected_method();
assert(method.not_null(), "should have thrown exception");
JavaCalls::call(result, method, args, CHECK);
}
void JavaCalls::call_static(JavaValue* result, KlassHandle klass, Symbol* name, Symbol* signature, TRAPS) {
JavaCallArguments args; // No argument
call_static(result, klass, name, signature, &args, CHECK);
}
void JavaCalls::call_static(JavaValue* result, KlassHandle klass, Symbol* name, Symbol* signature, Handle arg1, TRAPS) {
JavaCallArguments args(arg1); // One oop argument
call_static(result, klass, name, signature, &args, CHECK);
}
void JavaCalls::call_static(JavaValue* result, KlassHandle klass, Symbol* name, Symbol* signature, Handle arg1, Handle arg2, TRAPS) {
JavaCallArguments args; // One oop argument
args.push_oop(arg1);
args.push_oop(arg2);
call_static(result, klass, name, signature, &args, CHECK);
}
void JavaCalls::call(JavaValue* result, methodHandle method, JavaCallArguments* args, TRAPS) {
assert(THREAD->is_Java_thread(), "only JavaThreads can make JavaCalls");
os::os_exception_wrapper(call_helper, result, &method, args, THREAD);
}
void JavaCalls::call_helper(JavaValue* result, methodHandle* m, JavaCallArguments* args, TRAPS) {
assert(!DumpSharedSpaces, "must not execute Java bytecodes when dumping");
methodHandle method = *m;
JavaThread* thread = (JavaThread*)THREAD;
assert(thread->is_Java_thread(), "must be called by a java thread");
assert(method.not_null(), "must have a method to call");
assert(!SafepointSynchronize::is_at_safepoint(), "call to Java code during VM operation");
assert(!thread->handle_area()->no_handle_mark_active(), "cannot call out to Java here");
CHECK_UNHANDLED_OOPS_ONLY(thread->clear_unhandled_oops();)
if (CheckJNICalls) {
args->verify(method, result->get_type());
}
else debug_only(args->verify(method, result->get_type()));
if (method->is_empty_method()) {
assert(result->get_type() == T_VOID, "an empty method must return a void value");
return;
}
#ifdef ASSERT
{ InstanceKlass* holder = method->method_holder();
assert(holder->is_linked(), "rewritting must have taken place");
}
#endif
assert(!thread->is_Compiler_thread(), "cannot compile from the compiler");
if (CompilationPolicy::must_be_compiled(method)) {
CompileBroker::compile_method(method, InvocationEntryBci,
CompilationPolicy::policy()->initial_compile_level(),
methodHandle(), 0, "must_be_compiled", CHECK);
}
address entry_point = method->from_interpreted_entry();
if (JvmtiExport::can_post_interpreter_events() && thread->is_interp_only_mode()) {
entry_point = method->interpreter_entry();
}
BasicType result_type = runtime_type_from(result);
bool oop_result_flag = (result->get_type() == T_OBJECT || result->get_type() == T_ARRAY);
intptr_t* result_val_address = (intptr_t*)(result->get_value_addr());
Handle receiver = (!method->is_static()) ? args->receiver() : Handle();
if (thread->stack_yellow_zone_disabled()) {
thread->reguard_stack();
}
if (!os::stack_shadow_pages_available(THREAD, method)) {
Exceptions::throw_stack_overflow_exception(THREAD, __FILE__, __LINE__, method);
return;
} else {
os::bang_stack_shadow_pages();
}
{ JavaCallWrapper link(method, receiver, result, CHECK);
{ HandleMark hm(thread); // HandleMark used by HandleMarkCleaner
StubRoutines::call_stub()(
(address)&link,
result_val_address, // see NOTE above (compiler problem)
result_type,
method(),
entry_point,
args->parameters(),
args->size_of_parameters(),
CHECK
);
result = link.result(); // circumvent MS C++ 5.0 compiler bug (result is clobbered across call)
if (oop_result_flag) {
thread->set_vm_result((oop) result->get_jobject());
}
}
} // Exit JavaCallWrapper (can block - potential return oop must be preserved)
if (oop_result_flag) {
result->set_jobject((jobject)thread->vm_result());
thread->set_vm_result(NULL);
}
}
inline bool is_value_state_indirect_oop(uint state) {
assert(state != JavaCallArguments::value_state_oop,
"Checking for handles after removal");
assert(state < JavaCallArguments::value_state_limit, "Invalid value state");
return state != JavaCallArguments::value_state_primitive;
}
inline oop resolve_indirect_oop(intptr_t value, uint state) {
switch (state) {
case JavaCallArguments::value_state_handle:
{
oop* ptr = reinterpret_cast<oop*>(value);
return Handle::raw_resolve(ptr);
}
case JavaCallArguments::value_state_jobject:
{
jobject obj = reinterpret_cast<jobject>(value);
return JNIHandles::resolve(obj);
}
default:
ShouldNotReachHere();
return NULL;
}
}
intptr_t* JavaCallArguments::parameters() {
for(int i = 0; i < _size; i++) {
uint state = _value_state[i];
assert(state != value_state_oop, "Multiple handle conversions");
if (is_value_state_indirect_oop(state)) {
oop obj = resolve_indirect_oop(_value[i], state);
_value[i] = cast_from_oop<intptr_t>(obj);
_value_state[i] = value_state_oop;
}
}
return _value;
}
class SignatureChekker : public SignatureIterator {
private:
int _pos;
BasicType _return_type;
u_char* _value_state;
intptr_t* _value;
public:
bool _is_return;
SignatureChekker(Symbol* signature,
BasicType return_type,
bool is_static,
u_char* value_state,
intptr_t* value) :
SignatureIterator(signature),
_pos(0),
_return_type(return_type),
_value_state(value_state),
_value(value),
_is_return(false)
{
if (!is_static) {
check_value(true); // Receiver must be an oop
}
}
void check_value(bool type) {
uint state = _value_state[_pos++];
if (type) {
guarantee(is_value_state_indirect_oop(state),
"signature does not match pushed arguments");
} else {
guarantee(state == JavaCallArguments::value_state_primitive,
"signature does not match pushed arguments");
}
}
void check_doing_return(bool state) { _is_return = state; }
void check_return_type(BasicType t) {
guarantee(_is_return && t == _return_type, "return type does not match");
}
void check_int(BasicType t) {
if (_is_return) {
check_return_type(t);
return;
}
check_value(false);
}
void check_double(BasicType t) { check_long(t); }
void check_long(BasicType t) {
if (_is_return) {
check_return_type(t);
return;
}
check_value(false);
check_value(false);
}
void check_obj(BasicType t) {
if (_is_return) {
check_return_type(t);
return;
}
intptr_t v = _value[_pos];
if (v != 0) {
guarantee((size_t)v >= (size_t)os::vm_page_size(),
"Bad JNI oop argument");
oop vv = resolve_indirect_oop(v, _value_state[_pos]);
guarantee(vv->is_oop_or_null(true),
"Bad JNI oop argument");
}
check_value(true); // Verify value state.
}
void do_bool() { check_int(T_BOOLEAN); }
void do_char() { check_int(T_CHAR); }
void do_float() { check_int(T_FLOAT); }
void do_double() { check_double(T_DOUBLE); }
void do_byte() { check_int(T_BYTE); }
void do_short() { check_int(T_SHORT); }
void do_int() { check_int(T_INT); }
void do_long() { check_long(T_LONG); }
void do_void() { check_return_type(T_VOID); }
void do_object(int begin, int end) { check_obj(T_OBJECT); }
void do_array(int begin, int end) { check_obj(T_OBJECT); }
};
void JavaCallArguments::verify(methodHandle method, BasicType return_type) {
guarantee(method->size_of_parameters() == size_of_parameters(), "wrong no. of arguments pushed");
if (return_type == T_ARRAY) return_type = T_OBJECT;
Symbol* signature = method->signature();
SignatureChekker sc(signature,
return_type,
method->is_static(),
_value_state,
_value);
sc.iterate_parameters();
sc.check_doing_return(true);
sc.iterate_returntype();
}
C:\hotspot-69087d08d473\src\share\vm/runtime/javaCalls.hpp
#ifndef SHARE_VM_RUNTIME_JAVACALLS_HPP
#define SHARE_VM_RUNTIME_JAVACALLS_HPP
#include "memory/allocation.hpp"
#include "oops/method.hpp"
#include "runtime/handles.hpp"
#include "runtime/javaFrameAnchor.hpp"
#include "runtime/thread.inline.hpp"
#include "runtime/vmThread.hpp"
#ifdef TARGET_ARCH_x86
# include "jniTypes_x86.hpp"
#endif
#ifdef TARGET_ARCH_aarch64
# include "jniTypes_aarch64.hpp"
#endif
#ifdef TARGET_ARCH_sparc
# include "jniTypes_sparc.hpp"
#endif
#ifdef TARGET_ARCH_zero
# include "jniTypes_zero.hpp"
#endif
#ifdef TARGET_ARCH_arm
# include "jniTypes_arm.hpp"
#endif
#ifdef TARGET_ARCH_ppc
# include "jniTypes_ppc.hpp"
#endif
class JavaCallWrapper: StackObj {
friend class VMStructs;
private:
JavaThread* _thread; // the thread to which this call belongs
JNIHandleBlock* _handles; // the saved handle block
Method* _callee_method; // to be able to collect arguments if entry frame is top frame
oop _receiver; // the receiver of the call (if a non-static call)
JavaFrameAnchor _anchor; // last thread anchor state that we must restore
JavaValue* _result; // result value
public:
JavaCallWrapper(methodHandle callee_method, Handle receiver, JavaValue* result, TRAPS);
~JavaCallWrapper();
JavaThread* thread() const { return _thread; }
JNIHandleBlock* handles() const { return _handles; }
JavaFrameAnchor* anchor(void) { return &_anchor; }
JavaValue* result() const { return _result; }
Method* callee_method() { return _callee_method; }
oop receiver() { return _receiver; }
void oops_do(OopClosure* f);
bool is_first_frame() const { return _anchor.last_Java_sp() == NULL; }
};
class JavaCallArguments : public StackObj {
private:
enum Constants {
_default_size = 8 // Must be at least # of arguments in JavaCalls methods
};
intptr_t _value_buffer [_default_size + 1];
u_char _value_state_buffer[_default_size + 1];
intptr_t* _value;
u_char* _value_state;
int _size;
int _max_size;
bool _start_at_zero; // Support late setting of receiver
sssssssss72
最新推荐文章于 2024-05-11 15:00:28 发布