view graal/com.oracle.max.graal.printer/src/com/oracle/max/graal/printer/CFGPrinterObserver.java @ 4367:2d7544ea8ed9

Remove debug print out.
author Thomas Wuerthinger <thomas.wuerthinger@oracle.com>
date Thu, 26 Jan 2012 17:17:42 +0100
parents 3d8e80de2c29
children 57cb8ec5f6bb
line wrap: on
line source

/*
 * Copyright (c) 2012, 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.max.graal.printer;

import java.io.*;
import java.util.*;

import com.oracle.max.cri.ci.*;
import com.oracle.max.cri.ri.*;
import com.oracle.max.criutils.*;
import com.oracle.max.graal.alloc.util.*;
import com.oracle.max.graal.compiler.alloc.*;
import com.oracle.max.graal.compiler.gen.*;
import com.oracle.max.graal.compiler.lir.*;
import com.oracle.max.graal.compiler.observer.*;
import com.oracle.max.graal.compiler.schedule.*;
import com.oracle.max.graal.graph.*;
import com.oracle.max.graal.java.*;
import com.oracle.max.graal.nodes.*;

/**
 * Observes compilation events and uses {@link CFGPrinter} to produce a control flow graph for the <a
 * href="http://java.net/projects/c1visualizer/">C1 Visualizer</a>.
 */
public class CFGPrinterObserver implements CompilationObserver {

    /**
     * A thread local stack of {@link CFGPrinter}s to support thread-safety and re-entrant compilation.
     */
    private ThreadLocal<LinkedList<CFGPrinter>> observations = new ThreadLocal<LinkedList<CFGPrinter>>() {
        @Override
        protected java.util.LinkedList<CFGPrinter> initialValue() {
            return new LinkedList<>();
        }
    };

    @Override
    public void compilationStarted(CompilationEvent event) {
        if (TTY.isSuppressed()) {
            return;
        }
        RiRuntime runtime = event.debugObject(RiRuntime.class);
        CiTarget target = event.debugObject(CiTarget.class);

        CFGPrinter cfgPrinter = new CFGPrinter(new ByteArrayOutputStream(), target, runtime);
        cfgPrinter.printCompilation(event.debugObject(RiResolvedMethod.class));
        observations.get().push(cfgPrinter);
    }

    @Override
    public void compilationEvent(CompilationEvent event) {
        if (TTY.isSuppressed()) {
            return;
        }
        CFGPrinter cfgPrinter = observations.get().peek();
        if (cfgPrinter == null) {
            return;
        }

        RiRuntime runtime = cfgPrinter.runtime;
        if (event.debugObject(LIR.class) != null) {
            cfgPrinter.lir = event.debugObject(LIR.class);
        }
        if (event.debugObject(LIRGenerator.class) != null) {
            cfgPrinter.lirGenerator = event.debugObject(LIRGenerator.class);
        }

        BlockMap blockMap = event.debugObject(BlockMap.class);
        Graph graph = event.debugObject(Graph.class);
        IdentifyBlocksPhase schedule = event.debugObject(IdentifyBlocksPhase.class);
        LinearScan allocator = event.debugObject(LinearScan.class);
        Interval[] intervals = event.debugObject(Interval[].class);
        IntervalPrinter.Interval[] printIntervals = event.debugObject(IntervalPrinter.Interval[].class);
        CiTargetMethod targetMethod = event.debugObject(CiTargetMethod.class);

        if (blockMap != null) {
            cfgPrinter.printCFG(event.label, blockMap);
            cfgPrinter.printBytecodes(runtime.disassemble(blockMap.method));
        }
        if (cfgPrinter.lir != null) {
            cfgPrinter.printCFG(event.label, cfgPrinter.lir.codeEmittingOrder());
            if (targetMethod != null) {
                cfgPrinter.printMachineCode(runtime.disassemble(targetMethod), null);
            }
        } else if (graph != null) {
            List<? extends Block> blocks = null;
            if (schedule == null) {
                try {
                    schedule = new IdentifyBlocksPhase(true, LIRBlock.FACTORY);
                    schedule.apply((StructuredGraph) graph);
                    blocks = schedule.getBlocks();

                    ComputeLinearScanOrder clso = new ComputeLinearScanOrder(schedule.getBlocks().size(), schedule.loopCount(), (LIRBlock) schedule.getStartBlock());
                    blocks = clso.codeEmittingOrder();
                } catch (Throwable t) {
                    // nothing to do here...
                }
            }
            if (blocks != null) {
                cfgPrinter.printCFG(event.label, blocks);
            }
        }
        if (allocator != null && intervals != null) {
            cfgPrinter.printIntervals(event.label, intervals);
        }
        if (printIntervals != null) {
            cfgPrinter.printIntervals(event.label, printIntervals);
        }
    }

    @Override
    public void compilationFinished(CompilationEvent event) {
        if (TTY.isSuppressed()) {
            return;
        }
        CFGPrinter cfgPrinter = observations.get().pop();
        cfgPrinter.flush();

        OutputStream stream = CompilationPrinter.globalOut();
        if (stream != null) {
            synchronized (stream) {
                try {
                    stream.write(cfgPrinter.buffer.toByteArray());
                    stream.flush();
                } catch (IOException e) {
                    TTY.println("WARNING: Error writing CFGPrinter output: %s", e);
                }
            }
        }
    }
}