blob: 04112d1bf9ddeab850ee6dff5164031bc8f67b6f [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: 31 janv. 2014
*
* Contributors:
* Arnault Lapitre (CEA LIST) arnault.lapitre@cea.fr
* - Initial API and implementation
******************************************************************************/
#include "HitOrderedProcessor.h"
#include <fml/operator/OperatorManager.h>
#include <fml/runtime/ExecutionContext.h>
#include <fam/hitorjump/AvmHitOrJumpProcessor.h>
namespace sep
{
/**
* CONSTRUCTOR
* Default
*/
HitOrderedProcessor::HitOrderedProcessor(
AvmHitOrJumpProcessor & hojProcessor, EvaluationEnvironment & anENV)
: BaseHitProcessor(hojProcessor, anENV , OperatorManager::OPERATOR_SEQUENCE ),
mLastObjective( )
{
//!! NOTHING
}
////////////////////////////////////////////////////////////////////////////////
// CONFIGURE API
////////////////////////////////////////////////////////////////////////////////
bool HitOrderedProcessor::configure(WObject * wfParameterObject)
{
bool mConfigFlag = BaseHitProcessor::configure(wfParameterObject);
if( isPureStateTransitionNatureFlag && mTraceObjective.nonempty() )
{
mLastObjective = mTraceObjective.last();
}
return( mConfigFlag );
}
bool HitOrderedProcessor::resetConfig()
{
return( BaseHitProcessor::resetConfig() );
}
////////////////////////////////////////////////////////////////////////////////
// HIT FILTERING API
////////////////////////////////////////////////////////////////////////////////
bool HitOrderedProcessor::goalWillNeverAchieved(ExecutionContext * anEC)
{
if( mLastObjective.invalid() )
{
return( false );
}
else if( BaseHitProcessor::hit(anEC, mLastObjective) )
{
return( false );
}
else if( willNeverHit(anEC, mLastObjective) )
{
++mCoverageStatistics.mNumberOfBlackHole;
mBlackHoleEC.append(anEC);
AVM_IF_DEBUG_LEVEL_FLAG( MEDIUM , PROCESSOR )
AVM_OS_TRACE << "<<<<< goalWillNeverAchieved< BLACK HOLE > >>>>>" << std::endl
<< "EC:> " << anEC->str_min() << std::endl
<< str_indent( mLastObjective ) << std::endl;
AVM_ENDIF_DEBUG_LEVEL_FLAG( MEDIUM , PROCESSOR )
return( true );
}
else
{
return( false );
}
}
bool HitOrderedProcessor::hit(avm_size_t jumpHeight)
{
if( goalAchieved() )
{
return( true );
}
mJumpHeight = jumpHeight;
// ALGO for ORDERED
mHitCount = 0;
mMaxHitEC.clear();
ExecutionContext::child_iterator itChildEC;
ExecutionContext::child_iterator endChildEC;
ecIt = mRelativeRootEC.begin();
ecItEnd = mRelativeRootEC.end();
for( ; ecIt != ecItEnd ; ++ecIt )
{
itChildEC = (*ecIt)->begin();
endChildEC = (*ecIt)->end();
for( ; itChildEC != endChildEC ; ++itChildEC )
{
hit((*itChildEC), mCoverageStatistics.mNumberOfCovered, 0);
}
}
if( mHitCount > 0 )
{
traceOffset = mCoverageStatistics.mNumberOfCovered;
mCoverageStatistics.addCoveredElement( mHitCount );
// set the coverage bitset
for( ; traceOffset < mCoverageStatistics.mNumberOfCovered ; ++traceOffset )
{
mCoverageStatistics.mCoverageBitset.set(traceOffset, true);
}
mRelativeLeafEC.clear();
hitOffsetEnd = mMaxHitEC.size();
for( hitOffset = 0 ; hitOffset != hitOffsetEnd ; ++hitOffset )
{
AVM_IF_DEBUG_LEVEL_FLAG( HIGH , PROCESSOR )
AVM_OS_TRACE << "<<<<< hit< candidate > >>>>> EC< id:"
<< mMaxHitEC[ hitOffset ]->getIdNumber() << " >" << std::endl;
AVM_ENDIF_DEBUG_LEVEL_FLAG( HIGH , PROCESSOR )
mMaxHitEC[ hitOffset ]->setWeight(0);
mRelativeLeafEC.append( mMaxHitEC[ hitOffset ] );
}
return( true );
}
AVM_IF_DEBUG_LEVEL_FLAG( MEDIUM , PROCESSOR )
AVM_OS_TRACE << std::endl;
AVM_ENDIF_DEBUG_LEVEL_FLAG( MEDIUM , PROCESSOR )
return( false );
}
void HitOrderedProcessor::hit(ExecutionContext * anEC,
avm_size_t uncoveredOffset, avm_size_t hitCount)
{
if( mBlackHoleEC.contains(anEC) )
{
return;
}
avm_size_t saveHitCount = hitCount;
for( ; uncoveredOffset != mCoverageStatistics.mNumberOfElements ;
++uncoveredOffset )
{
if( BaseHitProcessor::hit(anEC, mTraceObjective[uncoveredOffset]) )
{
AVM_IF_DEBUG_LEVEL_FLAG( HIGH , PROCESSOR )
AVM_OS_TRACE << "<<<<< hit< 1 > >>>>> EC< id:"
<< anEC->getIdNumber() << " >" << std::endl;
AVM_ENDIF_DEBUG_LEVEL_FLAG( HIGH , PROCESSOR )
anEC->getwFlags().setCoverageElementTrace();
anEC->addInfo(mHitOrJumpProcessor, mTraceObjective[uncoveredOffset]);
++hitCount;
if( not mHitOrJumpProcessor.mFoldingFlag )
{
break;
}
}
else
{
if( mHitOrJumpProcessor.mHitConsecutiveFlag &&
(saveHitCount == hitCount) && (uncoveredOffset > 0) )
{
// TODO
AVM_IF_DEBUG_LEVEL_FLAG( HIGH , PROCESSOR )
AVM_OS_TRACE << "<<<<< hit#consecutive< FAILED > >>>>> EC< id:"
<< anEC->getIdNumber() << " >" << std::endl;
AVM_ENDIF_DEBUG_LEVEL_FLAG( HIGH , PROCESSOR )
return;
}
if( willNeverReached(anEC, mTraceObjective[uncoveredOffset]) )
{
AVM_IF_DEBUG_LEVEL_FLAG( HIGH , PROCESSOR )
AVM_OS_TRACE << "<<<<< hit#never< 1 > >>>>> EC< id:"
<< anEC->getIdNumber() << " >" << std::endl;
AVM_ENDIF_DEBUG_LEVEL_FLAG( HIGH , PROCESSOR )
return;
}
break;
}
}
if( hitCount == mCoverageStatistics.getNumberOfUncovered() )
{
anEC->getwFlags().setObjectiveAchievedTrace();
AVM_IF_DEBUG_LEVEL_FLAG( HIGH , PROCESSOR )
AVM_OS_TRACE << "<<<<< hit< goal achieved > >>>>> EC< id:"
<< anEC->getIdNumber() << " >" << std::endl;
AVM_ENDIF_DEBUG_LEVEL_FLAG( HIGH , PROCESSOR )
if( hitCount > mHitCount )
{
if( mBacktrackFlag )
{
hitOffsetEnd = mMaxHitEC.size();
for( hitOffset = 0 ; hitOffset != hitOffsetEnd ; ++hitOffset )
{
saveBacktrackable(mMaxHitEC[hitOffset], mHitCount);
}
}
mMaxHitEC.clear();
mHitCount = hitCount;
}
mMaxHitEC.push_back( anEC );
}
else if( anEC->hasNext() )
{
ExecutionContext::child_iterator itChildEC = anEC->begin();
ExecutionContext::child_iterator endChildEC = anEC->end();
for( ; itChildEC != endChildEC ; ++itChildEC )
{
hit((*itChildEC), uncoveredOffset, hitCount);
}
}
else if( isAbsoluteLeaf(anEC) )
{
//!! CONTINUE
}
else if( hitCount > mHitCount )
{
if( mBacktrackFlag )
{
hitOffsetEnd = mMaxHitEC.size();
for( hitOffset = 0 ; hitOffset != hitOffsetEnd ; ++hitOffset )
{
saveBacktrackable(mMaxHitEC[hitOffset], mHitCount);
}
}
mMaxHitEC.clear();
mHitCount = hitCount;
mMaxHitEC.push_back( anEC );
}
else if( (hitCount > 0) )
{
if( hitCount == mHitCount )
{
mMaxHitEC.push_back( anEC );
}
else
{
anEC->setWeightMax();
if( mBacktrackFlag )
{
saveBacktrackable(anEC, hitCount);
}
}
}
else if( hitCount == 0 )
{
AVM_IF_DEBUG_LEVEL_FLAG( HIGH , PROCESSOR )
AVM_OS_TRACE << "<<<<< nop >>>>> EC< id:"
<< anEC->getIdNumber() << " >" << std::endl;
AVM_ENDIF_DEBUG_LEVEL_FLAG( HIGH , PROCESSOR )
anEC->setWeightMax();
if( mBacktrackFlag )
{
saveBacktrackable(anEC, hitCount);
}
}
}
void HitOrderedProcessor::hitSelect(avm_size_t jumpOffset)
{
AVM_IF_DEBUG_LEVEL_FLAG( HIGH , PROCESSOR )
AVM_OS_TRACE << "<<<<< hit< 0 > >>>>> EC< id:"
<< mMaxHitEC[ jumpOffset ]->getIdNumber() << " >" << std::endl;
AVM_ENDIF_DEBUG_LEVEL_FLAG( HIGH , PROCESSOR )
mMaxHitEC[ jumpOffset ]->setWeight(0);
}
////////////////////////////////////////////////////////////////////////////////
// FILTERING TOOLS
////////////////////////////////////////////////////////////////////////////////
void HitOrderedProcessor::saveBacktrackable(
ExecutionContext * anEC, avm_size_t hitCount)
{
if( anEC->hasNext() )
{
//!! NOTHING
}
else if( willNeverReached(anEC, mTraceObjective
[ mCoverageStatistics.getNumberOfCovered() + hitCount ]) )
{
AVM_IF_DEBUG_LEVEL_FLAG( HIGH , PROCESSOR )
AVM_OS_TRACE << "<<<<< hit#never< 1 > >>>>> EC< id:"
<< anEC->getIdNumber() << " >" << std::endl;
AVM_ENDIF_DEBUG_LEVEL_FLAG( HIGH , PROCESSOR )
}
else
{
AVM_IF_DEBUG_LEVEL_FLAG( HIGH , PROCESSOR )
AVM_OS_TRACE << "<<<<< hit< backtract > >>>>> EC< id:"
<< anEC->getIdNumber() << " >" << std::endl;
AVM_ENDIF_DEBUG_LEVEL_FLAG( HIGH , PROCESSOR )
anEC->getUniqInformation()->getUniqHitOrJumpObjectiveInfo()->
setCoverageStatistics( mCoverageStatistics , hitCount );
mBacktrackHitEC.append( anEC );
}
}
bool HitOrderedProcessor::willNeverReached(
ExecutionContext * anEC, const BF & arg)
{
if( isAbsoluteLeaf(anEC) )
{
return( true );
}
else if( BaseHitProcessor::willNeverHit(anEC, arg) )
{
++mCoverageStatistics.mNumberOfBlackHole;
mBlackHoleEC.append(anEC);
AVM_IF_DEBUG_LEVEL_FLAG( MEDIUM , PROCESSOR )
AVM_OS_TRACE << "<<<<< HoJ< BLACK HOLE > >>>>>" << std::endl
<< "EC:> " << anEC->str_min() << std::endl
<< str_indent( arg ) << std::endl;
AVM_ENDIF_DEBUG_LEVEL_FLAG( MEDIUM , PROCESSOR )
return( true );
}
else
{
return( false );
}
}
} /* namespace sep */