< prev index next >
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotCompiledCodeBuilder.java
Print this page
rev 52509 : [mq]: graal
*** 22,52 ****
--- 22,59 ----
*/
package org.graalvm.compiler.hotspot;
+ import static org.graalvm.compiler.hotspot.HotSpotCompiledCodeBuilder.Options.ShowSubstitutionSourceInfo;
import static org.graalvm.util.CollectionsUtil.anyMatch;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.EnumMap;
import java.util.List;
+ import java.util.ListIterator;
import java.util.Map;
import java.util.stream.Stream;
import java.util.stream.Stream.Builder;
+ import org.graalvm.compiler.api.replacements.MethodSubstitution;
+ import org.graalvm.compiler.api.replacements.Snippet;
import org.graalvm.compiler.code.CompilationResult;
import org.graalvm.compiler.code.CompilationResult.CodeAnnotation;
import org.graalvm.compiler.code.CompilationResult.CodeComment;
import org.graalvm.compiler.code.CompilationResult.JumpTable;
import org.graalvm.compiler.code.DataSection;
import org.graalvm.compiler.code.SourceMapping;
import org.graalvm.compiler.debug.GraalError;
import org.graalvm.compiler.graph.NodeSourcePosition;
+ import org.graalvm.compiler.options.Option;
+ import org.graalvm.compiler.options.OptionKey;
+ import org.graalvm.compiler.options.OptionValues;
import jdk.vm.ci.code.CodeCacheProvider;
import jdk.vm.ci.code.DebugInfo;
import jdk.vm.ci.code.StackSlot;
import jdk.vm.ci.code.site.ConstantReference;
*** 62,79 ****
import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethod;
import jdk.vm.ci.meta.Assumptions.Assumption;
import jdk.vm.ci.meta.ResolvedJavaMethod;
public class HotSpotCompiledCodeBuilder {
! public static HotSpotCompiledCode createCompiledCode(CodeCacheProvider codeCache, ResolvedJavaMethod method, HotSpotCompilationRequest compRequest, CompilationResult compResult) {
String name = compResult.getName();
byte[] targetCode = compResult.getTargetCode();
int targetCodeSize = compResult.getTargetCodeSize();
! Site[] sites = getSortedSites(codeCache, compResult);
Assumption[] assumptions = compResult.getAssumptions();
ResolvedJavaMethod[] methods = compResult.getMethods();
--- 69,92 ----
import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethod;
import jdk.vm.ci.meta.Assumptions.Assumption;
import jdk.vm.ci.meta.ResolvedJavaMethod;
public class HotSpotCompiledCodeBuilder {
+ public static class Options {
+ // @formatter:off
+ @Option(help = "Controls whether the source position information of snippets and method substitutions" +
+ " are exposed to HotSpot. Can be useful when profiling to get more precise position information.")
+ public static final OptionKey<Boolean> ShowSubstitutionSourceInfo = new OptionKey<>(false);
+ }
! public static HotSpotCompiledCode createCompiledCode(CodeCacheProvider codeCache, ResolvedJavaMethod method, HotSpotCompilationRequest compRequest, CompilationResult compResult, OptionValues options) {
String name = compResult.getName();
byte[] targetCode = compResult.getTargetCode();
int targetCodeSize = compResult.getTargetCodeSize();
! Site[] sites = getSortedSites(compResult, options, codeCache.shouldDebugNonSafepoints() && method != null);
Assumption[] assumptions = compResult.getAssumptions();
ResolvedJavaMethod[] methods = compResult.getMethods();
*** 203,253 ****
/**
* HotSpot expects sites to be presented in ascending order of PC (see
* {@code DebugInformationRecorder::add_new_pc_offset}). In addition, it expects
* {@link Infopoint} PCs to be unique.
*/
! private static Site[] getSortedSites(CodeCacheProvider codeCache, CompilationResult target) {
List<Site> sites = new ArrayList<>(
target.getExceptionHandlers().size() + target.getInfopoints().size() + target.getDataPatches().size() + target.getMarks().size() + target.getSourceMappings().size());
sites.addAll(target.getExceptionHandlers());
sites.addAll(target.getInfopoints());
sites.addAll(target.getDataPatches());
sites.addAll(target.getMarks());
! if (codeCache.shouldDebugNonSafepoints()) {
/*
* Translate the source mapping into appropriate info points. In HotSpot only one
* position can really be represented and recording the end PC seems to give the best
* results and corresponds with what C1 and C2 do. HotSpot doesn't like to see these
* unless -XX:+DebugNonSafepoints is enabled, so don't emit them in that case.
*/
! List<Site> sourcePositionSites = new ArrayList<>();
! for (SourceMapping source : target.getSourceMappings()) {
! NodeSourcePosition sourcePosition = source.getSourcePosition();
! if (sourcePosition.isPlaceholder() || sourcePosition.isSubstitution()) {
! // HotSpot doesn't understand any of the special positions so just drop them.
! continue;
}
! assert sourcePosition.verify();
! sourcePosition = sourcePosition.trim();
/*
* Don't add BYTECODE_POSITION info points that would potentially create conflicts.
! * Under certain conditions the site's pc is not the pc that gets recorded by
! * HotSpot (see @code {CodeInstaller::site_Call}). So, avoid adding any source
! * positions that can potentially map to the same pc. To do that make sure that the
* source mapping doesn't contain a pc of any important Site.
*/
! if (sourcePosition != null && !anyMatch(sites, s -> source.contains(s.pcOffset))) {
! sourcePositionSites.add(new Infopoint(source.getEndOffset(), new DebugInfo(sourcePosition), InfopointReason.BYTECODE_POSITION));
}
}
sites.addAll(sourcePositionSites);
}
SiteComparator c = new SiteComparator();
Collections.sort(sites, c);
if (c.sawCollidingInfopoints) {
Infopoint lastInfopoint = null;
List<Site> copy = new ArrayList<>(sites.size());
for (Site site : sites) {
if (site instanceof Infopoint) {
--- 216,316 ----
/**
* HotSpot expects sites to be presented in ascending order of PC (see
* {@code DebugInformationRecorder::add_new_pc_offset}). In addition, it expects
* {@link Infopoint} PCs to be unique.
*/
! private static Site[] getSortedSites(CompilationResult target, OptionValues options, boolean includeSourceInfo) {
List<Site> sites = new ArrayList<>(
target.getExceptionHandlers().size() + target.getInfopoints().size() + target.getDataPatches().size() + target.getMarks().size() + target.getSourceMappings().size());
sites.addAll(target.getExceptionHandlers());
sites.addAll(target.getInfopoints());
sites.addAll(target.getDataPatches());
sites.addAll(target.getMarks());
! if (includeSourceInfo) {
/*
* Translate the source mapping into appropriate info points. In HotSpot only one
* position can really be represented and recording the end PC seems to give the best
* results and corresponds with what C1 and C2 do. HotSpot doesn't like to see these
* unless -XX:+DebugNonSafepoints is enabled, so don't emit them in that case.
*/
!
! List<SourceMapping> sourceMappings = new ArrayList<>();
! ListIterator<SourceMapping> sourceMappingListIterator = target.getSourceMappings().listIterator();
! if (sourceMappingListIterator.hasNext()) {
! SourceMapping currentSource = sourceMappingListIterator.next();
! NodeSourcePosition sourcePosition = currentSource.getSourcePosition();
! if (!sourcePosition.isPlaceholder() && !sourcePosition.isSubstitution()) {
! sourceMappings.add(currentSource);
! }
! while (sourceMappingListIterator.hasNext()) {
! SourceMapping nextSource = sourceMappingListIterator.next();
! assert currentSource.getStartOffset() <= nextSource.getStartOffset() : "Must be presorted";
! currentSource = nextSource;
! sourcePosition = currentSource.getSourcePosition();
! if (!sourcePosition.isPlaceholder() && !sourcePosition.isSubstitution()) {
! sourceMappings.add(currentSource);
}
! }
! }
!
/*
* Don't add BYTECODE_POSITION info points that would potentially create conflicts.
! * Under certain conditions the site's pc is not the pc that gets recorded by HotSpot
! * (see @code {CodeInstaller::site_Call}). So, avoid adding any source positions that
! * can potentially map to the same pc. To do that the following code makes sure that the
* source mapping doesn't contain a pc of any important Site.
*/
! sites.sort(new SiteComparator());
!
! ListIterator<Site> siteListIterator = sites.listIterator();
! sourceMappingListIterator = sourceMappings.listIterator();
+ List<Site> sourcePositionSites = new ArrayList<>();
+ Site site = null;
+
+ // Iterate over sourceMappings and sites in parallel. Create source position infopoints
+ // only for source mappings that don't have any sites inside their intervals.
+ while (sourceMappingListIterator.hasNext()) {
+ SourceMapping source = sourceMappingListIterator.next();
+
+ // Skip sites before the current source mapping
+ if (site == null || site.pcOffset < source.getStartOffset()) {
+ while (siteListIterator.hasNext()) {
+ site = siteListIterator.next();
+ if (site.pcOffset >= source.getStartOffset()) {
+ break;
+ }
}
}
+ assert !siteListIterator.hasNext() || site.pcOffset >= source.getStartOffset();
+ if (site != null && source.getStartOffset() <= site.pcOffset && site.pcOffset <= source.getEndOffset()) {
+ // Conflicting source mapping, skip it.
+ continue;
+ } else {
+ // Since the sites are sorted there can not be any more sites in this interval.
+ }
+ assert !siteListIterator.hasNext() || site.pcOffset > source.getEndOffset();
+ // Good source mapping. Create an infopoint and add it to the list.
+ NodeSourcePosition sourcePosition = source.getSourcePosition();
+ assert sourcePosition.verify();
+ if (!ShowSubstitutionSourceInfo.getValue(options)) {
+ sourcePosition = sourcePosition.trim();
+ assert verifyTrim(sourcePosition);
+ }
+ if (sourcePosition != null) {
+ assert !anyMatch(sites, s -> source.getStartOffset() <= s.pcOffset && s.pcOffset <= source.getEndOffset());
+ sourcePositionSites.add(new Infopoint(source.getEndOffset(), new DebugInfo(sourcePosition), InfopointReason.BYTECODE_POSITION));
+ }
+ }
+
sites.addAll(sourcePositionSites);
}
SiteComparator c = new SiteComparator();
Collections.sort(sites, c);
+
if (c.sawCollidingInfopoints) {
Infopoint lastInfopoint = null;
List<Site> copy = new ArrayList<>(sites.size());
for (Site site : sites) {
if (site instanceof Infopoint) {
*** 263,270 ****
--- 326,341 ----
copy.add(site);
}
}
sites = copy;
}
+
return sites.toArray(new Site[sites.size()]);
}
+
+ private static boolean verifyTrim(NodeSourcePosition sourcePosition) {
+ for (NodeSourcePosition sp = sourcePosition; sp != null; sp = sp.getCaller()) {
+ assert (sp.getMethod().getAnnotation(Snippet.class) == null && sp.getMethod().getAnnotation(MethodSubstitution.class) == null);
+ }
+ return true;
+ }
}
< prev index next >