Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions substratevm/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ This changelog summarizes major changes to GraalVM Native Image.
* (GR-39390) (GR-39649) (GR-40033) Red Hat added support for the JFR events `JavaMonitorEnter`, `JavaMonitorWait`, and `ThreadSleep`.
* (GR-39497) Add `-H:BuildOutputJSONFile=<file.json>` option for [JSON build output](https://github.com/oracle/graal/edit/master/docs/reference-manual/native-image/BuildOutput.md#machine-readable-build-output). Please feel free to provide feedback so that we can stabilize the schema/API.
* (GR-40170) Add `--silent` option to silence the build output.
* (GR-39475) Add initial support for jvmstat.

## Version 22.2.0
* (GR-20653) Re-enable the usage of all CPU features for JIT compilation on AMD64.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/*
* Copyright (c) 2022, 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.oracle.svm.core.genscavenge.jvmstat;

import org.graalvm.nativeimage.Platform;
import org.graalvm.nativeimage.Platforms;

import com.oracle.svm.core.genscavenge.GCImpl;
import com.oracle.svm.core.genscavenge.HeapImpl;
import com.oracle.svm.core.genscavenge.jvmstat.SerialGCPerfData.PerfDataGeneration;
import com.oracle.svm.core.genscavenge.jvmstat.SerialGCPerfData.SpacePerfData;
import com.oracle.svm.core.jvmstat.PerfDataHolder;

public class EpsilonGCPerfData implements PerfDataHolder {
private final SpacePerfData space;
private final PerfDataGeneration generation;

@Platforms(Platform.HOSTED_ONLY.class)
public EpsilonGCPerfData() {
space = new SpacePerfData(1, 0);
generation = new PerfDataGeneration(1, new SpacePerfData[]{space});
}

@Override
public void allocate() {
generation.allocate("Heap");
space.allocate("Heap");
}

@Override
public void update() {
long maxCapacity = GCImpl.getPolicy().getMaximumHeapSize().rawValue();
long usedBytes = HeapImpl.getHeapImpl().getAccounting().getEdenUsedBytes().rawValue();

space.used.setValue(usedBytes);
generation.capacity.setValue(usedBytes);
generation.maxCapacity.setValue(maxCapacity);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/*
* Copyright (c) 2022, 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.oracle.svm.core.genscavenge.jvmstat;

import java.util.Collections;
import java.util.List;

import org.graalvm.nativeimage.ImageSingletons;
import org.graalvm.nativeimage.hosted.Feature;

import com.oracle.svm.core.SubstrateOptions;
import com.oracle.svm.core.graal.InternalFeature;
import com.oracle.svm.core.jvmstat.PerfDataFeature;
import com.oracle.svm.core.jvmstat.PerfManager;

public class GenScavengePerfDataFeature implements InternalFeature {
@Override
public List<Class<? extends Feature>> getRequiredFeatures() {
return Collections.singletonList(PerfDataFeature.class);
}

@Override
public void afterRegistration(AfterRegistrationAccess access) {
if (ImageSingletons.contains(PerfManager.class)) {
PerfManager manager = ImageSingletons.lookup(PerfManager.class);
if (SubstrateOptions.UseEpsilonGC.getValue()) {
manager.register(new EpsilonGCPerfData());
} else if (SubstrateOptions.UseSerialGC.getValue()) {
manager.register(new SerialGCPerfData());
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,210 @@
/*
* Copyright (c) 2022, 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.oracle.svm.core.genscavenge.jvmstat;

import org.graalvm.nativeimage.ImageSingletons;
import org.graalvm.nativeimage.Platform;
import org.graalvm.nativeimage.Platforms;

import com.oracle.svm.core.genscavenge.GCAccounting;
import com.oracle.svm.core.genscavenge.GCImpl;
import com.oracle.svm.core.genscavenge.HeapAccounting;
import com.oracle.svm.core.genscavenge.HeapImpl;
import com.oracle.svm.core.genscavenge.HeapParameters;
import com.oracle.svm.core.jvmstat.PerfDataHolder;
import com.oracle.svm.core.jvmstat.PerfLongConstant;
import com.oracle.svm.core.jvmstat.PerfLongCounter;
import com.oracle.svm.core.jvmstat.PerfLongVariable;
import com.oracle.svm.core.jvmstat.PerfManager;
import com.oracle.svm.core.jvmstat.PerfStringConstant;
import com.oracle.svm.core.jvmstat.PerfUnit;

/**
* Performance data for our serial GC.
*/
public class SerialGCPerfData implements PerfDataHolder {
private final PerfDataGCPolicy gcPolicy;
private final PerfDataCollector youngCollector;
private final PerfDataCollector oldCollector;
private final PerfDataGeneration youngGen;
private final PerfDataGeneration oldGen;

@Platforms(Platform.HOSTED_ONLY.class)
public SerialGCPerfData() {
gcPolicy = new PerfDataGCPolicy();

youngCollector = new PerfDataCollector(0);
oldCollector = new PerfDataCollector(1);

int youngSpaceCount = 1 + HeapParameters.getMaxSurvivorSpaces();
SpacePerfData[] youngGenSpaces = new SpacePerfData[youngSpaceCount];
for (int i = 0; i < youngSpaceCount; i++) {
youngGenSpaces[i] = new SpacePerfData(0, i);
}
youngGen = new PerfDataGeneration(0, youngGenSpaces);

int oldSpaceIndex = youngSpaceCount;
SpacePerfData[] oldGenSpaces = new SpacePerfData[]{
new SpacePerfData(1, oldSpaceIndex)
};
oldGen = new PerfDataGeneration(1, oldGenSpaces);
}

@Override
public void allocate() {
gcPolicy.allocate();

youngCollector.allocate("Serial young collection pauses");
oldCollector.allocate("Serial full collection pauses");

youngGen.allocate("young");
youngGen.spaces[0].allocate("eden");
for (int i = 1; i < youngGen.spaces.length; i++) {
youngGen.spaces[i].allocate("s" + (i - 1));
}

oldGen.allocate("old");
oldGen.spaces[0].allocate("old");
assert oldGen.spaces.length == 1;
}

@Override
public void update() {
GCAccounting accounting = GCImpl.getGCImpl().getAccounting();
HeapAccounting heapAccounting = HeapImpl.getHeapImpl().getAccounting();

long maxNewSize = GCImpl.getPolicy().getMaximumYoungGenerationSize().rawValue();
youngCollector.invocations.setValue(accounting.getIncrementalCollectionCount());
youngCollector.time.setValue(accounting.getIncrementalCollectionTotalNanos());

youngGen.capacity.setValue(heapAccounting.getYoungUsedBytes().rawValue());
youngGen.maxCapacity.setValue(maxNewSize);

youngGen.spaces[0].used.setValue(heapAccounting.getEdenUsedBytes().rawValue());
for (int i = 1; i < youngGen.spaces.length; i++) {
youngGen.spaces[i].used.setValue(heapAccounting.getSurvivorSpaceAfterChunkBytes(i - 1).rawValue());
}

long maxOldSize = GCImpl.getPolicy().getMaximumHeapSize().rawValue() - maxNewSize;
oldCollector.invocations.setValue(accounting.getCompleteCollectionCount());
oldCollector.time.setValue(accounting.getCompleteCollectionTotalNanos());

oldGen.capacity.setValue(accounting.getOldGenerationAfterChunkBytes().rawValue());
oldGen.maxCapacity.setValue(maxOldSize);

oldGen.spaces[0].used.setValue(accounting.getOldGenerationAfterChunkBytes().rawValue());
}

private static class PerfDataGCPolicy {
private final PerfLongConstant collectors;
private final PerfLongConstant generations;
private final PerfStringConstant name;

@Platforms(Platform.HOSTED_ONLY.class)
PerfDataGCPolicy() {
PerfManager manager = ImageSingletons.lookup(PerfManager.class);
collectors = manager.createLongConstant("sun.gc.policy.collectors", PerfUnit.NONE);
generations = manager.createLongConstant("sun.gc.policy.generations", PerfUnit.NONE);
name = manager.createStringConstant("sun.gc.policy.name");
}

public void allocate() {
collectors.allocate(1);
generations.allocate(2);
name.allocate(GCImpl.getPolicy().getName());
}
}

private static class PerfDataCollector {
private final PerfStringConstant name;

private final PerfLongCounter invocations;
private final PerfLongCounter time;

@Platforms(Platform.HOSTED_ONLY.class)
PerfDataCollector(int index) {
PerfManager manager = ImageSingletons.lookup(PerfManager.class);
this.name = manager.createStringConstant("sun.gc.collector." + index + ".name");

this.invocations = manager.createLongCounter("sun.gc.collector." + index + ".invocations", PerfUnit.EVENTS);
this.time = manager.createLongCounter("sun.gc.collector." + index + ".time", PerfUnit.TICKS);
}

public void allocate(String collectorName) {
name.allocate(collectorName);

invocations.allocate();
time.allocate();
}
}

static class PerfDataGeneration {
private final PerfStringConstant name;
private final PerfLongConstant numSpaces;

final PerfLongVariable capacity;
final PerfLongVariable maxCapacity;
private final SpacePerfData[] spaces;

@Platforms(Platform.HOSTED_ONLY.class)
PerfDataGeneration(int generationIndex, SpacePerfData[] spaces) {
PerfManager manager = ImageSingletons.lookup(PerfManager.class);
this.name = manager.createStringConstant("sun.gc.generation." + generationIndex + ".name");
this.numSpaces = manager.createLongConstant("sun.gc.generation." + generationIndex + ".spaces", PerfUnit.NONE);

this.capacity = manager.createLongVariable("sun.gc.generation." + generationIndex + ".capacity", PerfUnit.BYTES);
this.maxCapacity = manager.createLongVariable("sun.gc.generation." + generationIndex + ".maxCapacity", PerfUnit.BYTES);
this.spaces = spaces;
}

public void allocate(String generationName) {
name.allocate(generationName);
numSpaces.allocate(spaces.length);

capacity.allocate();
maxCapacity.allocate();
}
}

static class SpacePerfData {
private final PerfStringConstant name;

final PerfLongVariable used;

@Platforms(Platform.HOSTED_ONLY.class)
SpacePerfData(int generationIndex, int spaceIndex) {
PerfManager manager = ImageSingletons.lookup(PerfManager.class);
name = manager.createStringConstant("sun.gc.generation." + generationIndex + ".space." + spaceIndex + ".name");

used = manager.createLongVariable("sun.gc.generation." + generationIndex + ".space." + spaceIndex + ".used", PerfUnit.BYTES);
}

public void allocate(String spaceName) {
name.allocate(spaceName);

used.allocate();
}
}
}
Loading