Path: blob/master/runtime/gc_realtime/AllocationContextRealtime.cpp
5986 views
1/*******************************************************************************2* Copyright (c) 1991, 2019 IBM Corp. and others3*4* This program and the accompanying materials are made available under5* the terms of the Eclipse Public License 2.0 which accompanies this6* distribution and is available at https://www.eclipse.org/legal/epl-2.0/7* or the Apache License, Version 2.0 which accompanies this distribution and8* is available at https://www.apache.org/licenses/LICENSE-2.0.9*10* This Source Code may also be made available under the following11* Secondary Licenses when the conditions for such availability set12* forth in the Eclipse Public License, v. 2.0 are satisfied: GNU13* General Public License, version 2 with the GNU Classpath14* Exception [1] and GNU General Public License, version 2 with the15* OpenJDK Assembly Exception [2].16*17* [1] https://www.gnu.org/software/classpath/license.html18* [2] http://openjdk.java.net/legal/assembly-exception.html19*20* SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 OR LicenseRef-GPL-2.0 WITH Assembly-exception21*******************************************************************************/2223#include "omr.h"24#include "omrcfg.h"2526#include "AtomicOperations.hpp"27#include "EnvironmentBase.hpp"28#include "EnvironmentRealtime.hpp"29#include "GCExtensionsBase.hpp"30#include "GlobalGCStats.hpp"31#include "HeapRegionDescriptorSegregated.hpp"32#include "HeapRegionDescriptorRealtime.hpp"33#include "MetronomeStats.hpp"34#include "RealtimeGC.hpp"35#include "RealtimeMarkingScheme.hpp"36#include "RegionPoolSegregated.hpp"37#include "Scheduler.hpp"38#include "SizeClasses.hpp"3940#include "AllocationContextRealtime.hpp"4142MM_AllocationContextRealtime *43MM_AllocationContextRealtime::newInstance(MM_EnvironmentBase *env, MM_GlobalAllocationManagerSegregated *gam, MM_RegionPoolSegregated *regionPool)44{45MM_AllocationContextRealtime *allocCtxt = (MM_AllocationContextRealtime *)env->getForge()->allocate(sizeof(MM_AllocationContextRealtime), MM_AllocationCategory::FIXED, OMR_GET_CALLSITE());46if (allocCtxt) {47new(allocCtxt) MM_AllocationContextRealtime(env, gam, regionPool);48if (!allocCtxt->initialize(env)) {49allocCtxt->kill(env);50allocCtxt = NULL;51}52}53return allocCtxt;54}5556bool57MM_AllocationContextRealtime::initialize(MM_EnvironmentBase *env)58{59if (!MM_AllocationContextSegregated::initialize(env)) {60return false;61}6263return true;64}6566void67MM_AllocationContextRealtime::tearDown(MM_EnvironmentBase *env)68{69MM_AllocationContextSegregated::tearDown(env);70}7172void73MM_AllocationContextRealtime::signalSmallRegionDepleted(MM_EnvironmentBase *env, uintptr_t sizeClass)74{75/* If we do not have a region yet, try to trigger a GC */76MM_GCExtensionsBase *ext = env->getExtensions();77MM_Scheduler *sched = (MM_Scheduler *)ext->dispatcher;78sched->checkStartGC((MM_EnvironmentRealtime *) env);79}8081bool82MM_AllocationContextRealtime::trySweepAndAllocateRegionFromSmallSizeClass(MM_EnvironmentBase *env, uintptr_t sizeClass, uintptr_t *sweepCount, U_64 *sweepStartTime)83{84bool result = false;8586#if defined(OMR_GC_REALTIME)87MM_GCExtensionsBase *ext = env->getExtensions();88MM_RealtimeGC *realtimeGC = ext->realtimeGC;89MM_SizeClasses *sizeClasses = ext->defaultSizeClasses;9091uintptr_t nonDeterministicSweepCount = *sweepCount;92U_64 nonDeterministicSweepStartTime = *sweepStartTime;9394/* Do not attempt this optimization while sweeping arraylets (at least not while the region may contain a spine). */95if (realtimeGC->shouldPerformNonDeterministicSweep()) {96OMRPORT_ACCESS_FROM_ENVIRONMENT(env);97/* Heuristic (or better, extrapolation): if occupancy is very high, do not retry too many times to sweep.98* Still, try at least once no matter how high the occupancy is (even if sharp 1.0), to jump over a local walls (short series of full regions).99* The heuristic assumes that the sweep list is (roughly) ordered by occupancy (low occupancy at front).100*/101if (nonDeterministicSweepCount <= (sizeClasses->getNumCells(sizeClass) * (1 - _regionPool->getOccupancy(sizeClass)))) {102103if (nonDeterministicSweepCount == 0) {104nonDeterministicSweepStartTime = omrtime_hires_clock();105}106107MM_HeapRegionDescriptorSegregated *region = _regionPool->sweepAndAllocateRegionFromSmallSizeClass(env, sizeClass);108if (region != NULL) {109/* Count each non determinist sweep */110ext->globalGCStats.metronomeStats.nonDeterministicSweepCount += 1;111nonDeterministicSweepCount++;112/* Find the longest streak (both as count of sweeps and time spent) of consecutive sweeps for one alloc */113if (nonDeterministicSweepCount > ext->globalGCStats.metronomeStats.nonDeterministicSweepConsecutive) {114ext->globalGCStats.metronomeStats.nonDeterministicSweepConsecutive = nonDeterministicSweepCount;115}116U_64 deltaTime = omrtime_hires_delta(nonDeterministicSweepStartTime, omrtime_hires_clock(), OMRPORT_TIME_DELTA_IN_MICROSECONDS);117if (deltaTime > ext->globalGCStats.metronomeStats.nonDeterministicSweepDelay) {118ext->globalGCStats.metronomeStats.nonDeterministicSweepDelay = deltaTime;119}120MM_AtomicOperations::storeSync();121_smallRegions[sizeClass] = region;122/* Don't update bytesAllocated because unswept regions are still considered to be in use */123result = true;124}125}126}127#endif128129return result;130}131132uintptr_t *133MM_AllocationContextRealtime::allocateLarge(MM_EnvironmentBase *env, uintptr_t sizeInBytesRequired)134{135MM_GCExtensionsBase *ext = env->getExtensions();136MM_Scheduler *sched = (MM_Scheduler *)ext->dispatcher;137138/* See if we should start a GC */139sched->checkStartGC((MM_EnvironmentRealtime *) env);140141/* Call parent to try to get a large object region */142uintptr_t *result = MM_AllocationContextSegregated::allocateLarge(env, sizeInBytesRequired);143//TODO SATB extract into a method144if ((NULL != result) && (GC_MARK == ((MM_EnvironmentRealtime *) env)->getAllocationColor())) {145ext->realtimeGC->getMarkingScheme()->mark((omrobjectptr_t)result);146}147148return result;149}150151bool152MM_AllocationContextRealtime::shouldPreMarkSmallCells(MM_EnvironmentBase *env)153{154MM_GCExtensionsBase *ext = env->getExtensions();155bool result = false;156157if (NULL != ext->realtimeGC) {158MM_EnvironmentRealtime *envRT = (MM_EnvironmentRealtime *) env;159result = (GC_MARK == envRT->getAllocationColor());160}161162return result;163}164165166