Delay materialization of new objects until the UpdateSession::close().

* Change: In Hurricane::Go, instead of immediatly materializing a newly
    created Go (inserting it in a QuadTree) delay it until the closing
    of the UpdateSession. We call "invalidate()" in "_postCreate()"
    instead of "materialize()". This way, the abutment box of Gos is
    taken into account only when the session is closed. There was a
    problem when the abutment box was changing after the object creation
    misleading the algorithm of the QuadTree. This was occuring only
    when an object was created, not modificated, because in the later case
    the Session mechanism was used. Now, the Session mechanism is used
    in all cases.
      As a side effect, it will speed up the parser by making all QuadTree
    insertions in one step.
* Change: In Hurricane::JsonCell, forgot to call Cell::materialize() when
    the Cell is completed (as was done in ordinary parsers). The call is
    made in the destructor of the JsonCell.
* Change: In Hurricane::Cell, add QuadTree in the inspector support.
This commit is contained in:
Jean-Paul Chaput 2016-09-08 21:50:17 +02:00
parent 8376d0c209
commit 6562792e53
7 changed files with 106 additions and 92 deletions

View File

@ -1051,6 +1051,8 @@ void Cell::materialize()
{
if (_flags.isset(Flags::Materialized)) return;
cdebug_log(18,1) << "Cell::materialize() " << this << endl;
_flags |= Flags::Materialized;
for ( Instance* instance : getInstances() ) {
@ -1060,6 +1062,8 @@ void Cell::materialize()
for ( Net* net : getNets () ) net ->materialize();
for ( Marker* marker : getMarkers() ) marker->materialize();
cdebug_tabw(18,-1);
}
void Cell::unmaterialize()
@ -1212,20 +1216,21 @@ Record* Cell::_getRecord() const
{
Record* record = Inherit::_getRecord();
if (record) {
record->add( getSlot("_library" , _library ) );
record->add( getSlot("_name" , &_name ) );
record->add( getSlot("_instances" , &_instanceMap ) );
record->add( getSlot("_quadTree" , _quadTree ) );
record->add( getSlot("_slaveInstances", &_slaveInstanceSet) );
record->add( getSlot("_netMap" , &_netMap ) );
record->add( getSlot("_netAliasSet" , &_netAliasSet ) );
record->add( getSlot("_pinMap" , &_pinMap ) );
record->add( getSlot("_sliceMap" , _sliceMap ) );
record->add( getSlot("_markerSet" , &_markerSet ) );
record->add( getSlot("_slaveEntityMap", &_slaveEntityMap ) );
record->add( getSlot("_abutmentBox" , &_abutmentBox ) );
record->add( getSlot("_boundingBox" , &_boundingBox ) );
record->add( getSlot("_flags" , &_flags ) );
record->add( getSlot("_library" , _library ) );
record->add( getSlot("_name" , &_name ) );
record->add( getSlot("_instances" , &_instanceMap ) );
record->add( getSlot("_quadTree" , _quadTree ) );
record->add( getSlot("_extensionSlices", &_extensionSlices ) );
record->add( getSlot("_slaveInstances" , &_slaveInstanceSet) );
record->add( getSlot("_netMap" , &_netMap ) );
record->add( getSlot("_netAliasSet" , &_netAliasSet ) );
record->add( getSlot("_pinMap" , &_pinMap ) );
record->add( getSlot("_sliceMap" , _sliceMap ) );
record->add( getSlot("_markerSet" , &_markerSet ) );
record->add( getSlot("_slaveEntityMap" , &_slaveEntityMap ) );
record->add( getSlot("_abutmentBox" , &_abutmentBox ) );
record->add( getSlot("_boundingBox" , &_boundingBox ) );
record->add( getSlot("_flags" , &_flags ) );
}
return record;
}
@ -1699,6 +1704,8 @@ Initializer<JsonCell> jsonCellInitialize ( 10 );
JsonCell::JsonCell(unsigned long flags)
// ************************************
: JsonEntity(flags)
, _cell (NULL)
, _materializationState(Go::autoMaterializationIsDisabled())
{
remove( ".Cell" );
add( "_library" , typeid(string) );
@ -1706,6 +1713,19 @@ JsonCell::JsonCell(unsigned long flags)
add( "_abutmentBox" , typeid(Box) );
add( "+instanceMap" , typeid(JsonArray) );
add( "+netMap" , typeid(JsonArray) );
Go::enableAutoMaterialization();
}
JsonCell::~JsonCell()
// ******************
{
cdebug_log(19,0) << "JsonCell::~JsonCell() " << _cell << endl;
Go::enableAutoMaterialization();
if (_cell) _cell->materialize();
if (_materializationState) Go::disableAutoMaterialization();
}
string JsonCell::getTypeName() const
@ -1728,10 +1748,10 @@ void JsonCell::toData(JsonStack& stack)
Library* library = DataBase::getDB()->getLibrary( get<string>(stack,"_library")
, DataBase::CreateLib|DataBase::WarnCreateLib );
Cell* cell = Cell::create( library, get<string>(stack,"_name") );
cell->setAbutmentBox( stack.as<Box>("_abutmentBox") );
_cell = Cell::create( library, get<string>(stack,"_name") );
_cell->setAbutmentBox( stack.as<Box>("_abutmentBox") );
update( stack, cell );
update( stack, _cell );
}
} // End of Hurricane namespace.

View File

@ -73,7 +73,7 @@ namespace Hurricane {
void ExtensionGo::unmaterialize ()
{
cdebug_log(18,1) << "ExtensionGo::unmaterialize() - start" << (void*)this << endl;
cdebug_log(18,1) << "ExtensionGo::unmaterialize() - start" << endl;
if ( isMaterialized() ) {
ExtensionSlice* slice = _cell->getExtensionSlice( getName() );

View File

@ -62,7 +62,7 @@ void Go::_postCreate()
Inherit::_postCreate();
if (not autoMaterializationIsDisabled()) {
materialize();
invalidate( true );
} // materialized after entire post creation
}

View File

@ -20,6 +20,7 @@
#include "hurricane/QuadTree.h"
#include "hurricane/Go.h"
#include "hurricane/Error.h"
#include "hurricane/Warning.h"
namespace Hurricane {
@ -232,18 +233,16 @@ QuadTree::~QuadTree()
const Box& QuadTree::getBoundingBox() const
// ****************************************
{
if (_boundingBox.isEmpty()) {
Box& boundingBox = ((QuadTree*)this)->_boundingBox;
if (_ulChild) boundingBox.merge(_ulChild->getBoundingBox());
if (_urChild) boundingBox.merge(_urChild->getBoundingBox());
if (_llChild) boundingBox.merge(_llChild->getBoundingBox());
if (_lrChild) boundingBox.merge(_lrChild->getBoundingBox());
for_each_go(go, _goSet.getElements()) {
boundingBox.merge(go->getBoundingBox());
end_for;
}
}
return _boundingBox;
if (_boundingBox.isEmpty()) {
Box& boundingBox = const_cast<Box&>( _boundingBox );
if (_ulChild) boundingBox.merge(_ulChild->getBoundingBox());
if (_urChild) boundingBox.merge(_urChild->getBoundingBox());
if (_llChild) boundingBox.merge(_llChild->getBoundingBox());
if (_lrChild) boundingBox.merge(_lrChild->getBoundingBox());
for ( Go* go : _goSet.getElements() )
boundingBox.merge(go->getBoundingBox());
}
return _boundingBox;
}
Gos QuadTree::getGos() const
@ -322,23 +321,23 @@ string QuadTree::_getString() const
}
Record* QuadTree::_getRecord() const
// ***************************
// *********************************
{
Record* record = NULL;
if (_size) {
record = new Record(getString(this));
record->add(getSlot("Parent", _parent));
record->add(getSlot("X", &_x));
record->add(getSlot("Y", &_y));
record->add(getSlot("BoundingBox", &_boundingBox));
record->add(getSlot("Size", &_size));
record->add(getSlot("Gos", &_goSet));
record->add(getSlot("ULChild", _ulChild));
record->add(getSlot("URChild", _urChild));
record->add(getSlot("LLChild", _llChild));
record->add(getSlot("LRChild", _lrChild));
}
return record;
Record* record = NULL;
if (_size) {
record = new Record( getString(this) );
record->add( getSlot("_parent" , _parent ) );
record->add( DbU::getValueSlot("_x", &_x ) );
record->add( DbU::getValueSlot("_y", &_y ) );
record->add( getSlot("_boundingBox", &_boundingBox) );
record->add( getSlot("_size" , &_size ) );
record->add( getSlot("_goSet" , &_goSet ) );
record->add( getSlot("_ulChild" , _ulChild ) );
record->add( getSlot("_urChild" , _urChild ) );
record->add( getSlot("_llChild" , _llChild ) );
record->add( getSlot("_lrChild" , _lrChild ) );
}
return record;
}
QuadTree* QuadTree::_getDeepestChild(const Box& box)

View File

@ -155,37 +155,36 @@ void Go::invalidate(bool propagateFlag)
Property* property = getProperty( UpdateSession::getPropertyName() );
if (property) {
if (not dynamic_cast<UpdateSession*>(property))
throw Error( "Can't invalidate go : bad update session type" );
} else {
SlaveEntityMap::iterator it;
SlaveEntityMap::iterator end;
getCell()->_getSlaveEntities( this, it, end );
for( ; it!=end ; it++ ) {
Go* go = dynamic_cast<Go*>( it->second );
if (go) go->invalidate( propagateFlag );
}
if (isMaterialized()) {
unmaterialize();
put( UPDATOR_STACK->top() );
}
Property* cellUpdateSession = getCell()->getProperty( UpdateSession::getPropertyName() );
if (not cellUpdateSession) {
// Put the cell in the UpdateSession relation, but *do not* unmaterialize it.
//cerr << "Notify Cell::CellAboutToChange to: " << getCell() << endl;
getCell()->put ( UPDATOR_STACK->top() );
getCell()->notify( Cell::Flags::CellAboutToChange );
for ( Instance* instance : getCell()->getSlaveInstances() ) {
instance->invalidate( false );
}
}
if (not dynamic_cast<UpdateSession*>(property))
throw Error( "Can't invalidate go : bad update session type" );
} else {
SlaveEntityMap::iterator it;
SlaveEntityMap::iterator end;
getCell()->_getSlaveEntities( this, it, end );
for( ; it!=end ; it++ ) {
Go* go = dynamic_cast<Go*>( it->second );
if (go) go->invalidate( propagateFlag );
}
cdebug_log(18,0) << "Go::invalidate(" << this << ") - Completed." << endl;
if (isMaterialized() or not Go::autoMaterializationIsDisabled()) {
unmaterialize();
put( UPDATOR_STACK->top() );
}
Property* cellUpdateSession = getCell()->getProperty( UpdateSession::getPropertyName() );
if (not cellUpdateSession) {
// Put the cell in the UpdateSession relation, but *do not* unmaterialize it.
//cerr << "Notify Cell::CellAboutToChange to: " << getCell() << endl;
getCell()->put ( UPDATOR_STACK->top() );
getCell()->notify( Cell::Flags::CellAboutToChange );
for ( Instance* instance : getCell()->getSlaveInstances() ) {
instance->invalidate( false );
}
}
}
cdebug_tabw(18,-1);
cdebug_log(18,0) << "Go::invalidate(" << this << ") - Completed." << endl;
}
void UpdateSession::open()

View File

@ -566,9 +566,12 @@ class JsonCell : public JsonEntity {
public: static void initialize();
public: JsonCell(unsigned long flags);
public: virtual ~JsonCell();
public: virtual string getTypeName() const;
public: virtual JsonCell* clone(unsigned long) const;
public: virtual void toData(JsonStack&);
private: Cell* _cell;
private: bool _materializationState;
};
} // End of Hurricane namespace.

View File

@ -19,12 +19,7 @@
// License along with Hurricane. If not, see
// <http://www.gnu.org/licenses/>.
//
// ===================================================================
//
// $Id$
//
// x-----------------------------------------------------------------x
// | |
// +-----------------------------------------------------------------+
// | H U R R I C A N E |
// | V L S I B a c k e n d D a t a - B a s e |
// | |
@ -32,19 +27,16 @@
// | E-mail : Jean-Paul.Chaput@lip6.fr |
// | =============================================================== |
// | C++ Header : "./hurricane/ExtensionSlice.h" |
// | *************************************************************** |
// | U p d a t e s |
// | |
// x-----------------------------------------------------------------x
// +-----------------------------------------------------------------+
#ifndef __HURRICANE_EXTENSION_SLICE__
#define __HURRICANE_EXTENSION_SLICE__
#ifndef HURRICANE_EXTENSION_SLICE_H
#define HURRICANE_EXTENSION_SLICE_H
#include "hurricane/Mask.h"
#include "hurricane/Name.h"
#include "hurricane/ExtensionSlices.h"
#include "hurricane/QuadTree.h"
#include "hurricane/Mask.h"
#include "hurricane/Name.h"
#include "hurricane/ExtensionSlices.h"
#include "hurricane/QuadTree.h"
namespace Hurricane {
@ -107,5 +99,6 @@ namespace Hurricane {
} // End of Hurricane namespace.
INSPECTOR_P_SUPPORT(Hurricane::ExtensionSlice);
# endif // __HURRICANE_EXTENSION_SLICE__
# endif // HURRICANE_EXTENSION_SLICE_H