Performance improvements for DRC rules.

This commit is contained in:
Jeff Young 2021-01-11 22:08:07 +00:00
parent a36f655dcd
commit 63e2046eb0
3 changed files with 91 additions and 7 deletions

View File

@ -265,6 +265,12 @@ public:
class CONTEXT class CONTEXT
{ {
public: public:
CONTEXT() :
m_stackPtr( 0 )
{
m_ownedValues.reserve( 20 );
}
virtual ~CONTEXT() virtual ~CONTEXT()
{ {
for( VALUE* value : m_ownedValues ) for( VALUE* value : m_ownedValues )
@ -280,25 +286,23 @@ public:
void Push( VALUE* v ) void Push( VALUE* v )
{ {
m_stack.push( v ); m_stack[ m_stackPtr++ ] = v;
} }
VALUE* Pop() VALUE* Pop()
{ {
if( m_stack.size() == 0 ) if( m_stackPtr == 0 )
{ {
ReportError( _( "Malformed expression" ) ); ReportError( _( "Malformed expression" ) );
return AllocValue(); return AllocValue();
} }
VALUE* value = m_stack.top(); return m_stack[ --m_stackPtr ];
m_stack.pop();
return value;
} }
int SP() const int SP() const
{ {
return m_stack.size(); return m_stackPtr;
}; };
void SetErrorCallback( std::function<void( const wxString& aMessage, int aOffset )> aCallback ) void SetErrorCallback( std::function<void( const wxString& aMessage, int aOffset )> aCallback )
@ -312,7 +316,8 @@ public:
private: private:
std::vector<VALUE*> m_ownedValues; std::vector<VALUE*> m_ownedValues;
std::stack<VALUE*> m_stack; VALUE* m_stack[100]; // std::stack not performant enough
int m_stackPtr;
ERROR_STATUS m_errorStatus; ERROR_STATUS m_errorStatus;
std::function<void( const wxString& aMessage, int aOffset )> m_errorCallback; std::function<void( const wxString& aMessage, int aOffset )> m_errorCallback;

View File

@ -613,6 +613,34 @@ LIBEVAL::VALUE PCB_EXPR_VAR_REF::GetValue( LIBEVAL::CONTEXT* aCtx )
} }
LIBEVAL::VALUE PCB_EXPR_NETCLASS_REF::GetValue( LIBEVAL::CONTEXT* aCtx )
{
BOARD_ITEM* item = GetObject( aCtx );
if( !item )
return LIBEVAL::VALUE();
if( item->IsConnected() )
return LIBEVAL::VALUE( static_cast<BOARD_CONNECTED_ITEM*>( item )->GetNetClassName() );
else
return LIBEVAL::VALUE();
}
LIBEVAL::VALUE PCB_EXPR_NETNAME_REF::GetValue( LIBEVAL::CONTEXT* aCtx )
{
BOARD_ITEM* item = GetObject( aCtx );
if( !item )
return LIBEVAL::VALUE();
if( item->IsConnected() )
return LIBEVAL::VALUE( static_cast<BOARD_CONNECTED_ITEM*>( item )->GetNetname() );
else
return LIBEVAL::VALUE();
}
LIBEVAL::FUNC_CALL_REF PCB_EXPR_UCODE::CreateFuncCall( const wxString& aName ) LIBEVAL::FUNC_CALL_REF PCB_EXPR_UCODE::CreateFuncCall( const wxString& aName )
{ {
PCB_EXPR_BUILTIN_FUNCTIONS& registry = PCB_EXPR_BUILTIN_FUNCTIONS::Instance(); PCB_EXPR_BUILTIN_FUNCTIONS& registry = PCB_EXPR_BUILTIN_FUNCTIONS::Instance();
@ -627,6 +655,27 @@ std::unique_ptr<LIBEVAL::VAR_REF> PCB_EXPR_UCODE::CreateVarRef( const wxString&
PROPERTY_MANAGER& propMgr = PROPERTY_MANAGER::Instance(); PROPERTY_MANAGER& propMgr = PROPERTY_MANAGER::Instance();
std::unique_ptr<PCB_EXPR_VAR_REF> vref; std::unique_ptr<PCB_EXPR_VAR_REF> vref;
// Check for a couple of very common cases and compile them straight to "object code".
if( aField.CmpNoCase( "NetClass" ) )
{
if( aVar == "A" )
return std::make_unique<PCB_EXPR_NETCLASS_REF>( 0 );
else if( aVar == "B" )
return std::make_unique<PCB_EXPR_NETCLASS_REF>( 1 );
else
return nullptr;
}
else if( aField.CmpNoCase( "NetName" ) )
{
if( aVar == "A" )
return std::make_unique<PCB_EXPR_NETNAME_REF>( 0 );
else if( aVar == "B" )
return std::make_unique<PCB_EXPR_NETNAME_REF>( 1 );
else
return nullptr;
}
if( aVar == "A" ) if( aVar == "A" )
vref = std::make_unique<PCB_EXPR_VAR_REF>( 0 ); vref = std::make_unique<PCB_EXPR_VAR_REF>( 0 );
else if( aVar == "B" ) else if( aVar == "B" )

View File

@ -116,6 +116,36 @@ private:
}; };
// "Object code" version of a netclass reference (for performance).
class PCB_EXPR_NETCLASS_REF : public PCB_EXPR_VAR_REF
{
public:
PCB_EXPR_NETCLASS_REF( int aItemIndex ) :
PCB_EXPR_VAR_REF( aItemIndex )
{
SetType( LIBEVAL::VT_STRING );
//printf("*** CreateVarRef %p %d\n", this, aItemIndex );
}
LIBEVAL::VALUE GetValue( LIBEVAL::CONTEXT* aCtx ) override;
};
// "Object code" version of a netname reference (for performance).
class PCB_EXPR_NETNAME_REF : public PCB_EXPR_VAR_REF
{
public:
PCB_EXPR_NETNAME_REF( int aItemIndex ) :
PCB_EXPR_VAR_REF( aItemIndex )
{
SetType( LIBEVAL::VT_STRING );
//printf("*** CreateVarRef %p %d\n", this, aItemIndex );
}
LIBEVAL::VALUE GetValue( LIBEVAL::CONTEXT* aCtx ) override;
};
class PCB_EXPR_BUILTIN_FUNCTIONS class PCB_EXPR_BUILTIN_FUNCTIONS
{ {
public: public: