blob: 67e8499fdfa67a5b3262a2ee875336f06ce84e99 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2016 CEA LIST.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Created on: 17 janv. 2015
*
* Contributors:
* Arnault Lapitre (CEA LIST) arnault.lapitre@cea.fr
* - Initial API and implementation
******************************************************************************/
#ifndef AVM_PROCESS_COVERAGE_AVMCOVERAGEDIRECTIVETRACEBUILDER_H_
#define AVM_PROCESS_COVERAGE_AVMCOVERAGEDIRECTIVETRACEBUILDER_H_
#include <collection/List.h>
#include <collection/Typedef.h>
#include <fml/buffer/LifoBuffer.h>
#include <fml/executable/AvmTransition.h>
#include <fml/executable/InstanceOfBuffer.h>
#include <fml/runtime/ExecutionData.h>
#include <fml/runtime/RuntimeID.h>
#include <fml/trace/TracePoint.h>
#include <fml/trace/TraceSequence.h>
#include <fam/coverage/AvmCoverageHeuristicProperty.h>
namespace sep
{
class AvmCoverageTransitionView;
class OutStream;
class ExecutableForm;
class ExecutionContext;
class APExecutionData;
class InstanceOfMachine;
class InstanceOfPort;
class RuntimeForm;
class AvmTraceProperty : public TraceSequence
{
public:
/**
* ATTRIBUTE
*/
AvmCoverageTransitionView * mTransitionCoverage;
avm_size_t mSize;
avm_size_t mUncoveredCount;
avm_size_t mGuardCount;
avm_size_t mUnconditionalCount;
avm_size_t mUnstableCount;
/**
* CONSTRUCTOR
* Default
*/
AvmTraceProperty(AvmCoverageTransitionView * aTransitionCoverage)
: TraceSequence( CLASS_KIND_T( AvmTraceProperty ) ),
mTransitionCoverage( aTransitionCoverage ),
mSize( 0 ),
mUncoveredCount( 0 ),
mGuardCount( 0 ),
mUnconditionalCount( 0 ),
mUnstableCount( 0 )
{
//!! NOTHING
}
AvmTraceProperty(ExecutionContext * anEC = NULL)
: TraceSequence( anEC ),
mTransitionCoverage( NULL ),
mSize( 0 ),
mUncoveredCount( 0 ),
mGuardCount( 0 ),
mUnconditionalCount( 0 ),
mUnstableCount( 0 )
{
//!! NOTHING
}
/**
* CONSTRUCTOR
* Copy
*/
AvmTraceProperty(const TraceSequence & aTrace)
: TraceSequence( aTrace ),
mTransitionCoverage( NULL ),
mSize( 0 ),
mUncoveredCount( 0 ),
mGuardCount( 0 ),
mUnconditionalCount( 0 ),
mUnstableCount( 0 )
{
updadeSize();
}
AvmTraceProperty(const AvmTraceProperty & aTraceProperty)
: TraceSequence( aTraceProperty ),
mTransitionCoverage( aTraceProperty.mTransitionCoverage ),
mSize( aTraceProperty.mSize ),
mUncoveredCount( aTraceProperty.mUncoveredCount ),
mGuardCount( aTraceProperty.mGuardCount ),
mUnconditionalCount( aTraceProperty.mUnconditionalCount ),
mUnstableCount( aTraceProperty.mUnstableCount )
{
//!! NOTHING
}
/**
* DESTRUCTOR
*/
virtual ~AvmTraceProperty()
{
//!! NOTHING
}
/**
* Configure
*/
inline bool configure(AvmTraceProperty & aTraceElement)
{
clear();
mTransitionCoverage = aTraceElement.mTransitionCoverage;
return( true );
}
/**
* Utils for TraceSequence
*/
void checkDecrementation(AvmTransition * aTransition);
void checkIncrementation(AvmTransition * aTransition);
inline void append(const RuntimeID & aRID, AvmTransition * aTransition)
{
points.push_back( BF( new TracePoint(
ENUM_TRACE_POINT::TRACE_TRANSITION_NATURE,
AVM_OPCODE_INVOKE_TRANSITION, aRID, aTransition) ) );
++mSize;
checkIncrementation( aTransition );
}
inline void clear()
{
points.clear();
mSize = 0;
mUncoveredCount = 0;
mGuardCount = 0;
mUnconditionalCount = 0;
mUnstableCount = 0;
}
inline void copyTrace(AvmTraceProperty & aTraceElement)
{
TraceSequence::copyTrace( aTraceElement );
mTransitionCoverage = aTraceElement.mTransitionCoverage;
mSize = aTraceElement.mSize;
mUncoveredCount = aTraceElement.mUncoveredCount;
mGuardCount = aTraceElement.mGuardCount;
mUnconditionalCount = aTraceElement.mUnconditionalCount;
mUnstableCount = aTraceElement.mUnstableCount;
}
inline bool empty() const
{
return( mSize == 0 );
}
inline void pop_back(avm_size_t ptsCount)
{
mSize = mSize - ptsCount;
for( ; ptsCount > 0 ; --ptsCount )
{
checkDecrementation( backTransition() );
points.pop_back();
}
}
inline void pop_front(avm_size_t ptsCount)
{
mSize = mSize - ptsCount;
for( ; ptsCount > 0 ; --ptsCount )
{
checkDecrementation( frontTransition() );
points.pop_front();
}
}
inline void resize(avm_size_t newSize)
{
if( newSize == 0 )
{
clear();
}
else for( ; mSize > newSize ; --mSize )
{
checkDecrementation( backTransition() );
points.pop_back();
}
}
/**
* mSize
* mUnconditionalCount
* mUnstableCount
*/
void updadeSize();
inline avm_size_t xSize() const
{
// return( mSize );
// return( mSize - mUnconditionalCount );
// return( mSize - mUnconditionalCount - mUnstableCount );
// if( backTransition()->isUnstableTarget() )
// {
// return( 2 * mSize + mGuardCount -
// mUncoveredCount - mUnconditionalCount - mUnstableCount );
// }
// else
{
return( mSize + mGuardCount -
mUncoveredCount - mUnconditionalCount - mUnstableCount );
}
}
bool compare( bool (* isComp)(avm_size_t, avm_size_t),
const AvmTraceProperty & aTraceElement );
template< class Compare >
bool isInf(Compare isComp, const AvmTraceProperty & aTraceElement)
{
return( isComp(xSize(), aTraceElement.xSize()) );
}
template< class Compare >
bool isSup(Compare isComp, const AvmTraceProperty & aTraceElement)
{
return( isComp(xSize(), aTraceElement.xSize()) );
}
inline bool sizeEQ(const AvmTraceProperty & aTraceElement) const
{
return( xSize() == aTraceElement.xSize() );
}
inline bool sizeGT(const AvmTraceProperty & aTraceElement) const
{
return( xSize() > aTraceElement.xSize() );
}
inline bool sizeGTE(const AvmTraceProperty & aTraceElement) const
{
return( xSize() >= aTraceElement.xSize() );
}
inline bool sizeLT(const AvmTraceProperty & aTraceElement) const
{
return( xSize() < aTraceElement.xSize() );
}
inline bool sizeLTE(const AvmTraceProperty & aTraceElement) const
{
return( xSize() <= aTraceElement.xSize() );
}
/**
* back / front;
* AvmTransition
*/
inline AvmTransition * backTransition() const
{
return( points.back().to_ptr< TracePoint >()->
object->to< AvmTransition >() );
}
inline AvmTransition * frontTransition() const
{
return( points.front().to_ptr< TracePoint >()->
object->to< AvmTransition >() );
}
/**
* Serialization
*/
virtual void toStream(OutStream & os, bool verbose = false) const;
};
DEFINE_LIST_REF( AvmTraceProperty )
class AvmCoverageDirectiveTraceBuilder : public IHeuristicClass
{
protected:
/**
* TYPEDEF
*/
typedef List< ListOfAvmTransition > ListOfListOfAvmTransition;
/**
* ATTRIBUTE
*/
const ExecutionContext * mEC;
APExecutionData mED;
RuntimeID mRID;
AvmTransition * mTransition;
TracePoint * mTransitionPoint;
AvmTraceProperty mTraceElement;
avm_size_t mComputingPathCountLimit;
avm_size_t mComputingPathSizeLimit;
bool mGoalAchievedFlag;
// ListOfAvmTransition mTransitionPath;
// ListOfInstanceOfPort mExpectedInput;
InstanceOfBuffer mVirtualBuffer;
LifoBuffer mEmitOutput;
TableOfRuntimeFormState mTableOfRuntimeStatus;
// computing variable for method << computePathToTransition >>
ListOfListOfAvmTransition anyTransitionPaths;
ListOfListOfAvmTransition prefixLoopTransitionPaths;
ListOfAvmTransition outgoingTransitions;
ListOfAvmTransition aTransitionPath;
ListOfAvmTransition::const_iterator itTrans;
ListOfAvmTransition::const_iterator endTrans;
InstanceOfMachine * tgtInstance;
ExecutableForm * fwdMachine;
ExecutableForm * tgtMachine;
public:
/**
* CONSTRUCTOR
* Default
*/
AvmCoverageDirectiveTraceBuilder(
ENUM_HEURISTIC_CLASS anHeuristicClass = HEURISTIC_SMART_CLASS,
avm_size_t pathCountLimit = 32, avm_size_t pathSizeLimit = 32)
: IHeuristicClass( anHeuristicClass ),
mEC( NULL ),
mED( ),
mRID( ),
mTransition( NULL ),
mTransitionPoint( NULL ),
mTraceElement( ),
mComputingPathCountLimit( pathCountLimit ),
mComputingPathSizeLimit( pathSizeLimit ),
mGoalAchievedFlag( false ),
//mTransitionPath( ),
//mExpectedInput( ),
mVirtualBuffer(NULL, NULL, 0, TYPE_MULTI_LIFO_SPECIFIER, -1),
mEmitOutput( & mVirtualBuffer ),
mTableOfRuntimeStatus( 0 ),
// computing variable for method << computePathToTransition >>
anyTransitionPaths( ),
prefixLoopTransitionPaths( ),
outgoingTransitions( ),
aTransitionPath( ),
itTrans( ),
endTrans( ),
tgtInstance( NULL ),
fwdMachine( NULL ),
tgtMachine( NULL )
{
//!! NOTHING
}
/**
* CONSTRUCTOR
* Other
*/
AvmCoverageDirectiveTraceBuilder(
const ExecutionContext * anEC, TracePoint * tpTransition,
ENUM_HEURISTIC_CLASS anHeuristicClass = HEURISTIC_SMART_CLASS,
avm_size_t pathCountLimit = 64, avm_size_t pathSizeLimit = 64);
AvmCoverageDirectiveTraceBuilder(const ExecutionContext * anEC,
const RuntimeID & aRID, AvmTransition * aTransition,
ENUM_HEURISTIC_CLASS anHeuristicClass = HEURISTIC_SMART_CLASS,
avm_size_t pathCountLimit = 16, avm_size_t pathSizeLimit = 16);
/**
* mComputingPathCountLimit
* mComputingPathSizeLimit
*/
void setComputingLimit(avm_size_t pathCountLimit, avm_size_t pathSizeLimit)
{
mComputingPathCountLimit = pathCountLimit;
mComputingPathSizeLimit = pathSizeLimit;
}
////////////////////////////////////////////////////////////////////////////
// Configure
////////////////////////////////////////////////////////////////////////////
bool configure(AvmTraceProperty & aTraceElement,
const ExecutionContext * anEC, TracePoint * tpTransition,
ENUM_HEURISTIC_CLASS anHeuristicClass = HEURISTIC_SMART_CLASS,
avm_size_t pathCountLimit = 64, avm_size_t pathSizeLimit = 64);
bool configure(AvmTraceProperty & aTraceElement,
const ExecutionContext * anEC,
const RuntimeID & aRID, AvmTransition * aTransition,
ENUM_HEURISTIC_CLASS anHeuristicClass = HEURISTIC_SMART_CLASS,
avm_size_t pathCountLimit = 16, avm_size_t pathSizeLimit = 16);
////////////////////////////////////////////////////////////////////////////
// API
////////////////////////////////////////////////////////////////////////////
bool initialize();
bool computePath();
bool computePath(AvmTraceProperty & aTraceElement);
bool computePath(AvmTraceProperty & aTraceElement, ExecutionContext * anEC,
const RuntimeID & aRID, AvmTransition * aTransition,
ENUM_HEURISTIC_CLASS anHeuristicClass = HEURISTIC_SMART_CLASS,
avm_size_t pathCountLimit = 16, avm_size_t pathSizeLimit = 16);
void report(OutStream & os);
bool computePath(const RuntimeID & aRID, AvmTransition * aTransition);
bool fireTransition(const RuntimeID & aRID, AvmTransition * aTransition);
void traceTransition(const RuntimeID & aRID, AvmTransition * aTransition);
bool computePathToTransition(
const RuntimeID & aRID, AvmTransition * aTransition);
inline bool computePathFromRunnable(
const RuntimeID & aRID, AvmTransition * aTransition)
{
switch( mHeuristicClass )
{
case IHeuristicClass::HEURISTIC_BASIC_CLASS:
{
return( computeBasicPathFromRunnable(aRID, aTransition) );
}
case IHeuristicClass::HEURISTIC_NAIVE_CLASS:
case IHeuristicClass::HEURISTIC_SMART_CLASS:
case IHeuristicClass::HEURISTIC_AGRESSIVE_CLASS:
case IHeuristicClass::HEURISTIC_NOTHING_ELSE_CLASS:
default:
{
return( computeSmartPathFromRunnable(aRID, aTransition) );
}
}
}
bool computeBasicPathFromRunnable(
const RuntimeID & aRID, AvmTransition * aTransition);
bool computeSmartPathFromRunnable(
const RuntimeID & aRID, AvmTransition * aTransition);
bool computePathToInput(
const RuntimeID & aRID, InstanceOfPort * anInputTrace);
bool computePathToTransition(
const RuntimeID & aRID, AvmTransition * aTransition,
ListOfAvmTransition & oneTransitionPath);
bool computePathToTransition(
const RuntimeID & aRID, AvmTransition * aTransition,
ListOfListOfAvmTransition & allTransitionPaths);
void computeTargetMachine(RuntimeID & aRID, AvmCode * aCode);
};
} /* namespace sep */
#endif /* AVM_PROCESS_COVERAGE_AVMCOVERAGEDIRECTIVETRACEBUILDER_H_ */