blob: 8698b1d48069084af0139f31e0aa07c9b35f6f83 [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 "HitUnorderedProcessor.h"
#include <fml/operator/OperatorManager.h>
#include <fml/runtime/ExecutionContext.h>
#include <fam/hitorjump/AvmHitOrJumpProcessor.h>
namespace sep
{
/**
* CONSTRUCTOR
* Default
*/
HitUnorderedProcessor::HitUnorderedProcessor(
AvmHitOrJumpProcessor & hojProcessor, EvaluationEnvironment & anENV)
: BaseHitProcessor(hojProcessor, anENV,
OperatorManager::OPERATOR_INTERLEAVING),
mHitCoverageBitset( ),
mHitSelectedCoverageBitset( ),
mHitSelectedEC( )
{
//!! NOTHING
}
////////////////////////////////////////////////////////////////////////////////
// CONFIGURE API
////////////////////////////////////////////////////////////////////////////////
bool HitUnorderedProcessor::resetConfig()
{
return( BaseHitProcessor::resetConfig() );
}
////////////////////////////////////////////////////////////////////////////////
// HIT FILTERING API
////////////////////////////////////////////////////////////////////////////////
bool HitUnorderedProcessor::goalWillNeverAchieved(ExecutionContext * anEC)
{
if( not isPureStateTransitionNatureFlag )
{
return( false );
}
else
{
// traceOffset = 0;
// for( ; traceOffset != mCoverageStatistics.mNumberOfElements ; ++traceOffset )
// {
// if( mCoverageStatistics.coverageBitset.test(traceOffset) )
// {
// //!! continue;
// }
// else if( BaseHitProcessor::willNeverHit(
// anEC,mTraceObjective[traceOffset]) )
// {
// if( not BaseHitProcessor::hit(anEC,mTraceObjective[traceOffset]) )
// {
// ++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;
//AVM_ENDIF_DEBUG_LEVEL_FLAG( MEDIUM , PROCESSOR )
//
// return( true );
// }
// }
// }
return( false );
}
}
bool HitUnorderedProcessor::hit(avm_size_t jumpHeight)
{
if( goalAchieved() )
{
return( true );
}
mJumpHeight = jumpHeight;
// ALGO for UNORDERED
mHitCount = 0;
mMaxHitEC.clear();
mHitCoverageBitset.clear();
if( mRelativeRootEC.singleton() )
{
hit(mRelativeRootEC.front(), mCoverageStatistics.mCoverageBitset, 0);
}
else
{
ExecutionContext::child_iterator itChildEC;
ExecutionContext::child_iterator endChildEC;
ecItEnd = mRelativeRootEC.end();
for( ecIt = mRelativeRootEC.begin() ; ecIt != ecItEnd ; ++ecIt )
{
itChildEC = (*ecIt)->begin();
endChildEC = (*ecIt)->end();
for( ; itChildEC != endChildEC ; ++itChildEC )
{
hit((*itChildEC), hitCoverageBitset(*ecIt), 0);
}
}
mHitSelectedEC.clear();
mHitSelectedCoverageBitset.clear();
}
if( mHitCount > 0 )
{
mCoverageStatistics.addCoveredElement( mHitCount );
// based on mCoverageStatistics.mNumberOfCovered
if( mCoverageStatistics.goalAchieved() )
{
mCoverageStatistics.mCoverageBitset.set();
}
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 HitUnorderedProcessor::hit(ExecutionContext * anEC,
Bitset coverageBitset, avm_size_t hitCount)
{
if( mBlackHoleEC.contains(anEC) )
{
return;
}
avm_size_t saveHitCount = hitCount;
traceOffset = 0;
for( ; traceOffset != mCoverageStatistics.mNumberOfElements ; ++traceOffset )
{
if( coverageBitset.test(traceOffset) )
{
//!! continue;
}
else if( BaseHitProcessor::hit(anEC, mTraceObjective[traceOffset]) )
{
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[traceOffset]);
coverageBitset.set(traceOffset, true),
++hitCount;
if( not mHitOrJumpProcessor.mFoldingFlag )
{
break;
}
}
}
if( (saveHitCount == hitCount) )
{
if( mHitOrJumpProcessor.mHitConsecutiveFlag && coverageBitset.any() )
{
// 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;
}
else if( willNeverHit(anEC, coverageBitset) )
{
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;
}
}
if( hitCount == mCoverageStatistics.getNumberOfUncovered() )
{
AVM_IF_DEBUG_LEVEL_FLAG( HIGH , PROCESSOR )
anEC->getwFlags().setObjectiveAchievedTrace();
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],
mHitCoverageBitset[hitOffset], mHitCount);
}
}
mMaxHitEC.clear();
mHitCoverageBitset.clear();
mHitCount = hitCount;
}
mMaxHitEC.push_back( anEC );
mHitCoverageBitset.push_back(coverageBitset);
}
else if( anEC->hasNext() )
{
ExecutionContext::child_iterator itChildEC = anEC->begin();
ExecutionContext::child_iterator endChildEC = anEC->end();
for( ; itChildEC != endChildEC ; ++itChildEC )
{
hit((*itChildEC), coverageBitset, hitCount);
}
}
else if( isAbsoluteLeaf(anEC) )
{
//!! CONTINUE
}
else if( hitCount > mHitCount )
{
if( mBacktrackFlag )
{
hitOffsetEnd = mMaxHitEC.size();
for( hitOffset = 0 ; hitOffset != hitOffsetEnd ; ++hitOffset )
{
saveBacktrackable(mMaxHitEC[hitOffset],
mHitCoverageBitset[hitOffset], mHitCount);
}
}
mMaxHitEC.clear();
mHitCoverageBitset.clear();
mHitCount = hitCount;
mMaxHitEC.push_back( anEC );
mHitCoverageBitset.push_back(coverageBitset);
}
else if( hitCount > 0 )
{
if( hitCount == mHitCount )
{
mMaxHitEC.push_back( anEC );
mHitCoverageBitset.push_back(coverageBitset);
}
else
{
anEC->setWeightMax();
if( mBacktrackFlag )
{
saveBacktrackable(anEC, coverageBitset, 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, coverageBitset, hitCount);
}
}
}
void HitUnorderedProcessor::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);
mCoverageStatistics.mCoverageBitset = mHitCoverageBitset[ jumpOffset ];
mHitSelectedEC.append( mMaxHitEC[ jumpOffset ] );
mHitSelectedCoverageBitset.append( mHitCoverageBitset[ jumpOffset ] );
}
Bitset & HitUnorderedProcessor::hitCoverageBitset(ExecutionContext * anEC)
{
hitOffsetEnd = mHitSelectedEC.size();
for( hitOffset = 0 ; hitOffset != hitOffsetEnd ; ++hitOffset )
{
if( mHitSelectedEC[hitOffset] == anEC )
{
return( mHitSelectedCoverageBitset[hitOffset] );
}
}
return( mCoverageStatistics.mCoverageBitset );
}
////////////////////////////////////////////////////////////////////////////////
// FILTERING TOOLS
////////////////////////////////////////////////////////////////////////////////
void HitUnorderedProcessor::saveBacktrackable(ExecutionContext * anEC,
Bitset & coverageBitset, avm_size_t hitCount)
{
if( anEC->hasNext() )
{
//!! NOTHING
}
else if( willNeverHit(anEC, coverageBitset) )
{
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, coverageBitset );
mBacktrackHitEC.append( anEC );
}
}
bool HitUnorderedProcessor::willNeverHit(
ExecutionContext * anEC, Bitset & coverageBitset)
{
if( isAbsoluteLeaf(anEC) )
{
return( true );
}
else if( not isPureStateTransitionNatureFlag )
{
return( false );
}
traceOffset = 0;
for( ; traceOffset != mCoverageStatistics.mNumberOfElements ; ++traceOffset )
{
if( coverageBitset.test(traceOffset) )
{
//!! continue;
}
else if( BaseHitProcessor::willNeverHit(
anEC,mTraceObjective[traceOffset]) )
{
++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;
AVM_ENDIF_DEBUG_LEVEL_FLAG( MEDIUM , PROCESSOR )
return( true );
}
}
return( false );
}
} /* namespace sep */