From 6562792e53eb486abe90920b7e94d2397a451a94 Mon Sep 17 00:00:00 2001 From: Jean-Paul Chaput Date: Thu, 8 Sep 2016 21:50:17 +0200 Subject: [PATCH] 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. --- hurricane/src/hurricane/Cell.cpp | 54 ++++++++++++------ hurricane/src/hurricane/ExtensionGo.cpp | 2 +- hurricane/src/hurricane/Go.cpp | 2 +- hurricane/src/hurricane/QuadTree.cpp | 55 +++++++++---------- hurricane/src/hurricane/UpdateSession.cpp | 55 +++++++++---------- hurricane/src/hurricane/hurricane/Cell.h | 3 + .../src/hurricane/hurricane/ExtensionSlice.h | 27 ++++----- 7 files changed, 106 insertions(+), 92 deletions(-) diff --git a/hurricane/src/hurricane/Cell.cpp b/hurricane/src/hurricane/Cell.cpp index a73b2b7c..d907a236 100644 --- a/hurricane/src/hurricane/Cell.cpp +++ b/hurricane/src/hurricane/Cell.cpp @@ -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 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(stack,"_library") , DataBase::CreateLib|DataBase::WarnCreateLib ); - Cell* cell = Cell::create( library, get(stack,"_name") ); - cell->setAbutmentBox( stack.as("_abutmentBox") ); + _cell = Cell::create( library, get(stack,"_name") ); + _cell->setAbutmentBox( stack.as("_abutmentBox") ); - update( stack, cell ); + update( stack, _cell ); } } // End of Hurricane namespace. diff --git a/hurricane/src/hurricane/ExtensionGo.cpp b/hurricane/src/hurricane/ExtensionGo.cpp index f8aefce1..b6ce2b50 100644 --- a/hurricane/src/hurricane/ExtensionGo.cpp +++ b/hurricane/src/hurricane/ExtensionGo.cpp @@ -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() ); diff --git a/hurricane/src/hurricane/Go.cpp b/hurricane/src/hurricane/Go.cpp index be6ffb04..59758bc0 100644 --- a/hurricane/src/hurricane/Go.cpp +++ b/hurricane/src/hurricane/Go.cpp @@ -62,7 +62,7 @@ void Go::_postCreate() Inherit::_postCreate(); if (not autoMaterializationIsDisabled()) { - materialize(); + invalidate( true ); } // materialized after entire post creation } diff --git a/hurricane/src/hurricane/QuadTree.cpp b/hurricane/src/hurricane/QuadTree.cpp index 168adf25..eb33baa5 100644 --- a/hurricane/src/hurricane/QuadTree.cpp +++ b/hurricane/src/hurricane/QuadTree.cpp @@ -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( _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) diff --git a/hurricane/src/hurricane/UpdateSession.cpp b/hurricane/src/hurricane/UpdateSession.cpp index 55316a0c..ee0a6bdd 100644 --- a/hurricane/src/hurricane/UpdateSession.cpp +++ b/hurricane/src/hurricane/UpdateSession.cpp @@ -155,37 +155,36 @@ void Go::invalidate(bool propagateFlag) Property* property = getProperty( UpdateSession::getPropertyName() ); if (property) { - - if (not dynamic_cast(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( 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(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( 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() diff --git a/hurricane/src/hurricane/hurricane/Cell.h b/hurricane/src/hurricane/hurricane/Cell.h index 82d32077..f6a4c580 100644 --- a/hurricane/src/hurricane/hurricane/Cell.h +++ b/hurricane/src/hurricane/hurricane/Cell.h @@ -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. diff --git a/hurricane/src/hurricane/hurricane/ExtensionSlice.h b/hurricane/src/hurricane/hurricane/ExtensionSlice.h index d8eea63b..88848ad3 100644 --- a/hurricane/src/hurricane/hurricane/ExtensionSlice.h +++ b/hurricane/src/hurricane/hurricane/ExtensionSlice.h @@ -19,12 +19,7 @@ // License along with Hurricane. If not, see // . // -// =================================================================== -// -// $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