Mercurial > hg > graal-compiler
view graal/com.oracle.truffle.object/src/com/oracle/truffle/object/debug/ShapeProfiler.java @ 19647:393da6e56fd9
Do not need to compute post dominators for schedule.
author | Thomas Wuerthinger <thomas.wuerthinger@oracle.com> |
---|---|
date | Sat, 28 Feb 2015 15:16:29 +0100 |
parents | 2c3666f44855 |
children |
line wrap: on
line source
/* * Copyright (c) 2014, 2014, 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. * * 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.truffle.object.debug; import java.io.*; import java.text.*; import java.util.*; import java.util.concurrent.*; import com.oracle.truffle.api.object.*; import com.oracle.truffle.object.*; public class ShapeProfiler { private static final String LINE_SEPARATOR = "***********************************************"; private static final String BULLET = "* "; private static final String TOKEN_SEPARATOR = "\t"; private final ConcurrentLinkedQueue<DynamicObject> queue; public ShapeProfiler() { queue = new ConcurrentLinkedQueue<>(); } public void track(DynamicObject obj) { queue.add(obj); } public void dump(PrintWriter out) { ShapeStats globalStats = new ShapeStats("Cumulative results for all shapes"); for (DynamicObject obj : queue) { Shape shape = obj.getShape(); globalStats.profile(shape); } globalStats.dump(out); } public void dump(PrintWriter out, int topResults) { if (topResults > 0) { IdentityHashMap<Shape, ShapeStats> shapeMap = new IdentityHashMap<>(); for (DynamicObject obj : queue) { Shape shape = obj.getShape(); ShapeStats stats = shapeMap.get(shape); if (stats == null) { shapeMap.put(shape, stats = new ShapeStats(createLabel(shape))); } stats.profile(shape); } List<ShapeStats> allStats = new ArrayList<>(shapeMap.values()); Collections.sort(allStats, new Comparator<ShapeStats>() { public int compare(ShapeStats a, ShapeStats b) { return Long.compare(b.jsObjects, a.jsObjects); } }); ShapeStats avgStats = new ShapeStats("Cumulative results for top " + topResults + " shapes"); for (int i = 0; i < topResults; i++) { ShapeStats stats = allStats.get(i); stats.setLabel("Shape " + (i + 1) + ": " + stats.getLabel()); stats.dump(out); avgStats.add(stats); } avgStats.dump(out); } // Dump also cumulative results. dump(out); } private static String createLabel(Shape shape) { String label = shape.toString(); return label.substring(label.indexOf('{') + 1, label.lastIndexOf('}')); } private static class ShapeStats { private String label; private long jsObjects; private long oac; private long oas; private long ofs; private long pac; private long pas; private long pfs; public ShapeStats(String label) { this.label = label; } public String getLabel() { return label; } public void setLabel(String label) { this.label = label; } public void profile(Shape shape) { jsObjects++; oac += shape.getObjectArrayCapacity(); oas += shape.getObjectArraySize(); ofs += shape.getObjectFieldSize(); pac += shape.getPrimitiveArrayCapacity(); pas += shape.getPrimitiveArraySize(); pfs += shape.getPrimitiveFieldSize(); } public void add(ShapeStats stats) { jsObjects += stats.jsObjects; oac += stats.oac; oas += stats.oas; ofs += stats.ofs; oac += stats.oac; oas += stats.oas; ofs += stats.ofs; } public void dump(PrintWriter out) { DecimalFormat format = new DecimalFormat("###.####"); out.println(LINE_SEPARATOR); out.println(BULLET + label); out.println(LINE_SEPARATOR); out.println(BULLET + "Allocated objects:\t" + jsObjects); out.println(BULLET + "Total object array capacity:\t" + oac); out.println(BULLET + "Total object array size:\t" + oas); out.println(BULLET + "Total object field size:\t" + ofs); out.println(BULLET + "Average object array capacity:\t" + avgOAC(format)); out.println(BULLET + "Average object array size:\t" + avgOAS(format)); out.println(BULLET + "Average object field size:\t" + avgOFS(format)); out.println(LINE_SEPARATOR); out.println(BULLET + "Total primitive array capacity:\t" + pac); out.println(BULLET + "Total primitive array size:\t" + pas); out.println(BULLET + "Total primitive field size:\t" + pfs); out.println(BULLET + "Average primitive array capacity:\t" + avgPAC(format)); out.println(BULLET + "Average primitive array size:\t" + avgPAS(format)); out.println(BULLET + "Average primitive field size:\t" + avgPFS(format)); out.println(LINE_SEPARATOR); out.println(BULLET + toString()); out.println(LINE_SEPARATOR + "\n"); out.flush(); } @Override public String toString() { DecimalFormat format = new DecimalFormat("###.####"); // @formatter:off return "{" + label + "}" + TOKEN_SEPARATOR + jsObjects + TOKEN_SEPARATOR + avgOAC(format) + TOKEN_SEPARATOR + avgOAS(format) + TOKEN_SEPARATOR + avgOFS(format) + TOKEN_SEPARATOR + avgPAC(format) + TOKEN_SEPARATOR + avgPAS(format) + TOKEN_SEPARATOR + avgPFS(format); // @formatter:on } private String avgOAC(DecimalFormat format) { return format.format((double) oac / jsObjects); } private String avgOAS(DecimalFormat format) { return format.format((double) oas / jsObjects); } private String avgOFS(DecimalFormat format) { return format.format((double) ofs / jsObjects); } private String avgPAC(DecimalFormat format) { return format.format((double) pac / jsObjects); } private String avgPAS(DecimalFormat format) { return format.format((double) pas / jsObjects); } private String avgPFS(DecimalFormat format) { return format.format((double) pfs / jsObjects); } } public static ShapeProfiler getInstance() { return shapeProf; } private static final ShapeProfiler shapeProf; static { if (ObjectStorageOptions.Profile) { shapeProf = new ShapeProfiler(); Runtime.getRuntime().addShutdownHook(new Thread() { @Override public void run() { getInstance().dump(new PrintWriter(System.out), ObjectStorageOptions.ProfileTopResults); } }); } else { shapeProf = null; } } }