/*
* This file is part of the Jikes RVM project (http://jikesrvm.org).
*
* This file is licensed to You under the Common Public License (CPL);
* You may not use this file except in compliance with the License. You
* may obtain a copy of the License at
*
* http://www.opensource.org/licenses/cpl1.0.php
*
* See the COPYRIGHT.txt file distributed with this work for information
* regarding copyright ownership.
*/
package org.jikesrvm.adaptive.recompilation.instrumentation;
import org.jikesrvm.adaptive.controller.VM_Controller;
import org.jikesrvm.adaptive.database.VM_AOSDatabase;
import org.jikesrvm.adaptive.measurements.instrumentation.VM_Instrumentation;
import org.jikesrvm.adaptive.measurements.instrumentation.VM_MethodInvocationCounterData;
import org.jikesrvm.compilers.opt.OPT_CompilerPhase;
import org.jikesrvm.compilers.opt.OPT_Options;
import org.jikesrvm.compilers.opt.ir.OPT_BasicBlock;
import org.jikesrvm.compilers.opt.ir.OPT_IR;
import org.jikesrvm.compilers.opt.ir.OPT_Instruction;
/**
* An OPT_CompilerPhase that inserts a method invocation counter on the first
* basic block of the method. It uses a
* VM_InstrumentedEventCounterManager to obtain the space to put the
* counters.
*
* Note: one counter data, (VM_MethodInvocationCounterData) is shared
* across all methods, and is initialized at boot time. This is
* unlike other kinds of instrumentation (such as basic block
* counters) where a separate data object is maintained for each
* method.
*/
public class OPT_InsertMethodInvocationCounter extends OPT_CompilerPhase {
/**
* Return this instance of this phase. This phase contains no
* per-compilation instance fields.
* @param ir not used
* @return this
*/
public OPT_CompilerPhase newExecution(OPT_IR ir) {
return this;
}
public final boolean shouldPerform(OPT_Options options) {
return VM_Controller.options.INSERT_METHOD_COUNTERS_OPT;
}
public final String getName() { return "InsertMethodInvocationCounters"; }
/**
* Insert basic block counters
*
* @param ir the governing IR
*/
public final void perform(OPT_IR ir) {
// Don't insert counters in uninterruptible or
// save volatile methods, or when instrumentation is disabled
if (!ir.method.isInterruptible() ||
!VM_Instrumentation.instrumentationEnabled() ||
ir.method.getDeclaringClass().hasSaveVolatileAnnotation()) {
return;
}
OPT_BasicBlock firstBB = ir.cfg.entry();
VM_MethodInvocationCounterData data = VM_AOSDatabase.methodInvocationCounterData;
int cmid = ir.compiledMethod.getId();
// Create a dummy instruction that is later converted into an
// increment of the appropriate VM_CounterArray element.
OPT_Instruction c = data.createEventCounterInstruction(cmid);
// Insert it at the beginning of the basic block
firstBB.prependInstructionRespectingPrologue(c);
}
}