< 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 >