[Libreoffice-commits] core.git: stoc/source
Matthew J. Francis
mjay.francis at gmail.com
Wed Jul 8 07:52:37 PDT 2015
stoc/source/inspect/introspection.cxx | 245 +++++++++++++++++++++++++++-------
1 file changed, 199 insertions(+), 46 deletions(-)
New commits:
commit 61b1697069c50ff72339d4592add42ab72b03243
Author: Matthew J. Francis <mjay.francis at gmail.com>
Date: Mon Jul 6 08:09:24 2015 +0800
Reduce the amount of up front work in performing introspection
Previously, when using PyUNO over a remote bridge, each remote
call which returned an object could result in 50+ further calls
to query interfaces on the result, regardless of whether and
how the object was then used. The majority of these queries
were made under css.script.Invocation to pre-cache certain
information about the returned object.
By making better use of available information to eliminate
interface queries which are certain to fail, and lazily
acquiring those interfaces which are required, remote scripting
is significantly accelerated. In general, this also gives a
small speedup for local scripting.
Change-Id: I4f36da6b5f09cb0d22f21291f05fbea2ae7ae697
Signed-off-by: Stephan Bergmann <sbergman at redhat.com>
diff --git a/stoc/source/inspect/introspection.cxx b/stoc/source/inspect/introspection.cxx
index e6b9110..cfa7085 100644
--- a/stoc/source/inspect/introspection.cxx
+++ b/stoc/source/inspect/introspection.cxx
@@ -162,6 +162,7 @@ class IntrospectionAccessStatic_Impl: public salhelper::SimpleReferenceObject
{
friend class Implementation;
friend class ImplIntrospectionAccess;
+ friend class ImplIntrospectionAdapter;
// Holding CoreReflection
Reference< XIdlReflection > mxCoreReflection;
@@ -194,8 +195,16 @@ class IntrospectionAccessStatic_Impl: public salhelper::SimpleReferenceObject
sal_Int32 mnAttributePropCount;
sal_Int32 mnMethodPropCount;
- // Flag, if a FastPropertySet is supported
+ // Flags which indicate if various interfaces are present
bool mbFastPropSet;
+ bool mbPropertySet;
+ bool mbElementAccess;
+ bool mbNameAccess;
+ bool mbNameContainer;
+ bool mbIndexAccess;
+ bool mbIndexContainer;
+ bool mbEnumerationAccess;
+ bool mbIdlArray;
// Original-Handles of FastPropertySets
sal_Int32* mpOrgPropertyHandleArray;
@@ -261,6 +270,15 @@ IntrospectionAccessStatic_Impl::IntrospectionAccessStatic_Impl( Reference< XIdlR
maPropertyConceptSeq.realloc( ARRAY_SIZE_STEP );
mbFastPropSet = false;
+ mbPropertySet = false;
+ mbElementAccess = false;
+ mbNameAccess = false;
+ mbNameContainer = false;
+ mbIndexAccess = false;
+ mbIndexContainer = false;
+ mbEnumerationAccess = false;
+ mbIdlArray = false;
+
mpOrgPropertyHandleArray = NULL;
mnPropCount = 0;
@@ -772,6 +790,9 @@ class ImplIntrospectionAdapter :
// Objekt als Interface
Reference<XInterface> mxIface;
+ // Guards the caching of queried interfaces
+ osl::Mutex m_aMutex;
+
// Original-Interfaces des Objekts
Reference<XElementAccess> mxObjElementAccess;
Reference<XNameContainer> mxObjNameContainer;
@@ -781,6 +802,14 @@ class ImplIntrospectionAdapter :
Reference<XEnumerationAccess> mxObjEnumerationAccess;
Reference<XIdlArray> mxObjIdlArray;
+ Reference<XElementAccess> getXElementAccess();
+ Reference<XNameContainer> getXNameContainer();
+ Reference<XNameAccess> getXNameAccess();
+ Reference<XIndexContainer> getXIndexContainer();
+ Reference<XIndexAccess> getXIndexAccess();
+ Reference<XEnumerationAccess> getXEnumerationAccess();
+ Reference<XIdlArray> getXIdlArray();
+
public:
ImplIntrospectionAdapter( ImplIntrospectionAccess* pAccess_,
const Any& obj,
@@ -861,6 +890,112 @@ public:
throw( IllegalArgumentException, ArrayIndexOutOfBoundsException, RuntimeException, std::exception ) SAL_OVERRIDE;
};
+Reference<XElementAccess> ImplIntrospectionAdapter::getXElementAccess()
+{
+ ResettableGuard< Mutex > aGuard( m_aMutex );
+
+ if( !mxObjElementAccess.is() )
+ {
+ aGuard.clear();
+ Reference<XElementAccess> xElementAccess = Reference<XElementAccess>::query( mxIface );
+ aGuard.reset();
+ if( !mxObjElementAccess.is() )
+ mxObjElementAccess = xElementAccess;
+ }
+ return mxObjElementAccess;
+}
+
+Reference<XNameContainer> ImplIntrospectionAdapter::getXNameContainer()
+{
+ ResettableGuard< Mutex > aGuard( m_aMutex );
+
+ if( !mxObjNameContainer.is() )
+ {
+ aGuard.clear();
+ Reference<XNameContainer> xNameContainer = Reference<XNameContainer>::query( mxIface );
+ aGuard.reset();
+ if( !mxObjNameContainer.is() )
+ mxObjNameContainer = xNameContainer;
+ }
+ return mxObjNameContainer;
+}
+
+Reference<XNameAccess> ImplIntrospectionAdapter::getXNameAccess()
+{
+ ResettableGuard< Mutex > aGuard( m_aMutex );
+
+ if( !mxObjNameAccess.is() )
+ {
+ aGuard.clear();
+ Reference<XNameAccess> xNameAccess = Reference<XNameAccess>::query( mxIface );
+ aGuard.reset();
+ if( !mxObjNameAccess.is() )
+ mxObjNameAccess = xNameAccess;
+ }
+ return mxObjNameAccess;
+}
+
+Reference<XIndexContainer> ImplIntrospectionAdapter::getXIndexContainer()
+{
+ ResettableGuard< Mutex > aGuard( m_aMutex );
+
+ if( !mxObjIndexContainer.is() )
+ {
+ aGuard.clear();
+ Reference<XIndexContainer> xIndexContainer = Reference<XIndexContainer>::query( mxIface );
+ aGuard.reset();
+ if( !mxObjIndexContainer.is() )
+ mxObjIndexContainer = xIndexContainer;
+ }
+ return mxObjIndexContainer;
+}
+
+Reference<XIndexAccess> ImplIntrospectionAdapter::getXIndexAccess()
+{
+ ResettableGuard< Mutex > aGuard( m_aMutex );
+
+ if( !mxObjIndexAccess.is() )
+ {
+ aGuard.clear();
+ Reference<XIndexAccess> xIndexAccess = Reference<XIndexAccess>::query( mxIface );
+ aGuard.reset();
+ if( !mxObjIndexAccess.is() )
+ mxObjIndexAccess = xIndexAccess;
+ }
+ return mxObjIndexAccess;
+}
+
+Reference<XEnumerationAccess> ImplIntrospectionAdapter::getXEnumerationAccess()
+{
+ ResettableGuard< Mutex > aGuard( m_aMutex );
+
+ if( !mxObjEnumerationAccess.is() )
+ {
+ aGuard.clear();
+ Reference<XEnumerationAccess> xEnumerationAccess = Reference<XEnumerationAccess>::query( mxIface );
+ aGuard.reset();
+ if( !mxObjEnumerationAccess.is() )
+ mxObjEnumerationAccess = xEnumerationAccess;
+ }
+ return mxObjEnumerationAccess;
+}
+
+Reference<XIdlArray> ImplIntrospectionAdapter::getXIdlArray()
+{
+ ResettableGuard< Mutex > aGuard( m_aMutex );
+
+ if( !mxObjIdlArray.is() )
+ {
+ aGuard.clear();
+ Reference<XIdlArray> xIdlArray = Reference<XIdlArray>::query( mxIface );
+ aGuard.reset();
+ if( !mxObjIdlArray.is() )
+ mxObjIdlArray = xIdlArray;
+ }
+ return mxObjIdlArray;
+}
+
+
ImplIntrospectionAdapter::ImplIntrospectionAdapter( ImplIntrospectionAccess* pAccess_,
const Any& obj,
rtl::Reference< IntrospectionAccessStatic_Impl > const & pStaticImpl_ )
@@ -869,17 +1004,7 @@ ImplIntrospectionAdapter::ImplIntrospectionAdapter( ImplIntrospectionAccess* pAc
// Objekt als Interfaceholen
TypeClass eType = mrInspectedObject.getValueType().getTypeClass();
if( eType == TypeClass_INTERFACE )
- {
mxIface = *static_cast<Reference< XInterface > const *>(mrInspectedObject.getValue());
-
- mxObjElementAccess = Reference<XElementAccess>::query( mxIface );
- mxObjNameAccess = Reference<XNameAccess>::query( mxIface );
- mxObjNameContainer = Reference<XNameContainer>::query( mxIface );
- mxObjIndexAccess = Reference<XIndexAccess>::query( mxIface );
- mxObjIndexContainer = Reference<XIndexContainer>::query( mxIface );
- mxObjEnumerationAccess = Reference<XEnumerationAccess>::query( mxIface );
- mxObjIdlArray = Reference<XIdlArray>::query( mxIface );
- }
}
// Methoden von XInterface
@@ -897,14 +1022,14 @@ Any SAL_CALL ImplIntrospectionAdapter::queryInterface( const Type& rType )
if( !aRet.hasValue() )
{
// Wrapper fuer die Objekt-Interfaces
- if( ( mxObjElementAccess.is() && (aRet = ::cppu::queryInterface
+ if( ( mpStaticImpl->mbElementAccess && (aRet = ::cppu::queryInterface
( rType, static_cast< XElementAccess* >( static_cast< XNameAccess* >( this ) ) ) ).hasValue() )
- || ( mxObjNameAccess.is() && (aRet = ::cppu::queryInterface( rType, static_cast< XNameAccess* >( this ) ) ).hasValue() )
- || ( mxObjNameContainer.is() && (aRet = ::cppu::queryInterface( rType, static_cast< XNameContainer* >( this ) ) ).hasValue() )
- || ( mxObjIndexAccess.is() && (aRet = ::cppu::queryInterface( rType, static_cast< XIndexAccess* >( this ) ) ).hasValue() )
- || ( mxObjIndexContainer.is() && (aRet = ::cppu::queryInterface( rType, static_cast< XIndexContainer* >( this ) ) ).hasValue() )
- || ( mxObjEnumerationAccess .is() && (aRet = ::cppu::queryInterface( rType, static_cast< XEnumerationAccess* >( this ) ) ).hasValue() )
- || ( mxObjIdlArray.is() && (aRet = ::cppu::queryInterface( rType, static_cast< XIdlArray* >( this ) ) ).hasValue() )
+ || ( mpStaticImpl->mbNameAccess && (aRet = ::cppu::queryInterface( rType, static_cast< XNameAccess* >( this ) ) ).hasValue() )
+ || ( mpStaticImpl->mbNameContainer && (aRet = ::cppu::queryInterface( rType, static_cast< XNameContainer* >( this ) ) ).hasValue() )
+ || ( mpStaticImpl->mbIndexAccess && (aRet = ::cppu::queryInterface( rType, static_cast< XIndexAccess* >( this ) ) ).hasValue() )
+ || ( mpStaticImpl->mbIndexContainer && (aRet = ::cppu::queryInterface( rType, static_cast< XIndexContainer* >( this ) ) ).hasValue() )
+ || ( mpStaticImpl->mbEnumerationAccess && (aRet = ::cppu::queryInterface( rType, static_cast< XEnumerationAccess* >( this ) ) ).hasValue() )
+ || ( mpStaticImpl->mbIdlArray && (aRet = ::cppu::queryInterface( rType, static_cast< XIdlArray* >( this ) ) ).hasValue() )
)
{
}
@@ -1021,121 +1146,120 @@ sal_Bool ImplIntrospectionAdapter::hasPropertyByName(const OUString& Name)
// Methoden von XElementAccess
Type ImplIntrospectionAdapter::getElementType() throw( RuntimeException, std::exception )
{
- return mxObjElementAccess->getElementType();
+ return getXElementAccess()->getElementType();
}
sal_Bool ImplIntrospectionAdapter::hasElements() throw( RuntimeException, std::exception )
{
- return mxObjElementAccess->hasElements();
+ return getXElementAccess()->hasElements();
}
// Methoden von XNameAccess
Any ImplIntrospectionAdapter::getByName(const OUString& Name)
throw( NoSuchElementException, WrappedTargetException, RuntimeException, std::exception )
{
- return mxObjNameAccess->getByName( Name );
+ return getXNameAccess()->getByName( Name );
}
Sequence< OUString > ImplIntrospectionAdapter::getElementNames()
throw( RuntimeException, std::exception )
{
- return mxObjNameAccess->getElementNames();
+ return getXNameAccess()->getElementNames();
}
sal_Bool ImplIntrospectionAdapter::hasByName(const OUString& Name)
throw( RuntimeException, std::exception )
{
- return mxObjNameAccess->hasByName( Name );
+ return getXNameAccess()->hasByName( Name );
}
// Methoden von XNameContainer
void ImplIntrospectionAdapter::insertByName(const OUString& Name, const Any& Element)
throw( IllegalArgumentException, ElementExistException, WrappedTargetException, RuntimeException, std::exception )
{
- mxObjNameContainer->insertByName( Name, Element );
+ getXNameContainer()->insertByName( Name, Element );
}
void ImplIntrospectionAdapter::replaceByName(const OUString& Name, const Any& Element)
throw( IllegalArgumentException, NoSuchElementException, WrappedTargetException, RuntimeException, std::exception )
{
- mxObjNameContainer->replaceByName( Name, Element );
+ getXNameContainer()->replaceByName( Name, Element );
}
void ImplIntrospectionAdapter::removeByName(const OUString& Name)
throw( NoSuchElementException, WrappedTargetException, RuntimeException, std::exception )
{
- mxObjNameContainer->removeByName( Name );
+ getXNameContainer()->removeByName( Name );
}
// Methoden von XIndexAccess
// Schon in XNameAccess: virtual Reference<XIdlClass> getElementType() const
sal_Int32 ImplIntrospectionAdapter::getCount() throw( RuntimeException, std::exception )
{
- return mxObjIndexAccess->getCount();
+ return getXIndexAccess()->getCount();
}
Any ImplIntrospectionAdapter::getByIndex(sal_Int32 Index)
throw( IndexOutOfBoundsException, WrappedTargetException, RuntimeException, std::exception )
{
- return mxObjIndexAccess->getByIndex( Index );
+ return getXIndexAccess()->getByIndex( Index );
}
// Methoden von XIndexContainer
void ImplIntrospectionAdapter::insertByIndex(sal_Int32 Index, const Any& Element)
throw( IllegalArgumentException, IndexOutOfBoundsException, WrappedTargetException, RuntimeException, std::exception )
{
- mxObjIndexContainer->insertByIndex( Index, Element );
+ getXIndexContainer()->insertByIndex( Index, Element );
}
void ImplIntrospectionAdapter::replaceByIndex(sal_Int32 Index, const Any& Element)
throw( IllegalArgumentException, IndexOutOfBoundsException, WrappedTargetException, RuntimeException, std::exception )
{
- mxObjIndexContainer->replaceByIndex( Index, Element );
+ getXIndexContainer()->replaceByIndex( Index, Element );
}
void ImplIntrospectionAdapter::removeByIndex(sal_Int32 Index)
throw( IndexOutOfBoundsException, WrappedTargetException, RuntimeException, std::exception )
{
- mxObjIndexContainer->removeByIndex( Index );
+ getXIndexContainer()->removeByIndex( Index );
}
// Methoden von XEnumerationAccess
// Schon in XNameAccess: virtual Reference<XIdlClass> getElementType() const;
Reference<XEnumeration> ImplIntrospectionAdapter::createEnumeration() throw( RuntimeException, std::exception )
{
- return mxObjEnumerationAccess->createEnumeration();
+ return getXEnumerationAccess()->createEnumeration();
}
// Methoden von XIdlArray
void ImplIntrospectionAdapter::realloc(Any& array, sal_Int32 length)
throw( IllegalArgumentException, RuntimeException, std::exception )
{
- mxObjIdlArray->realloc( array, length );
+ getXIdlArray()->realloc( array, length );
}
sal_Int32 ImplIntrospectionAdapter::getLen(const Any& array)
throw( IllegalArgumentException, RuntimeException, std::exception )
{
- return mxObjIdlArray->getLen( array );
+ return getXIdlArray()->getLen( array );
}
Any ImplIntrospectionAdapter::get(const Any& array, sal_Int32 index)
throw( IllegalArgumentException, ArrayIndexOutOfBoundsException, RuntimeException, std::exception )
{
- return mxObjIdlArray->get( array, index );
+ return getXIdlArray()->get( array, index );
}
void ImplIntrospectionAdapter::set(Any& array, sal_Int32 index, const Any& value)
throw( IllegalArgumentException, ArrayIndexOutOfBoundsException, RuntimeException, std::exception )
{
- mxObjIdlArray->set( array, index, value );
+ getXIdlArray()->set( array, index, value );
}
//*** Implementation von ImplIntrospectionAccess ***
-
// Methoden von XIntrospectionAccess
sal_Int32 ImplIntrospectionAccess::getSuppliedMethodConcepts()
throw( RuntimeException, std::exception )
@@ -1347,6 +1471,7 @@ Reference<XInterface> SAL_CALL ImplIntrospectionAccess::queryAdapter( const Type
{
// Gibt es schon einen Adapter?
Reference< XInterface > xAdapter( maAdapter );
+
if( !xAdapter.is() )
{
xAdapter = *( new ImplIntrospectionAdapter( this, maInspectedObject, mpStaticImpl ) );
@@ -1620,6 +1745,7 @@ css::uno::Reference<css::beans::XIntrospectionAccess> Implementation::inspect(
Reference<XIdlClass> xImplClass;
Reference<XPropertySetInfo> xPropSetInfo;
Reference<XPropertySet> xPropSet;
+ bool bHasPropertySet = false;
// Look for interfaces XTypeProvider and PropertySet
if( eType == TypeClass_INTERFACE )
@@ -1637,7 +1763,10 @@ css::uno::Reference<css::beans::XIntrospectionAccess> Implementation::inspect(
const Type* pTypes = SupportedTypesSeq.getConstArray();
for( sal_Int32 i = 0 ; i < nTypeCount ; i++ )
{
- pClasses[i] = reflection->forName(pTypes[i].getTypeName());
+ OUString typeName( pTypes[i].getTypeName() );
+ pClasses[i] = reflection->forName( typeName );
+ if( !bHasPropertySet && typeName == "com.sun.star.beans.XPropertySet" )
+ bHasPropertySet = true;
}
// TODO: Caching!
}
@@ -1651,7 +1780,8 @@ css::uno::Reference<css::beans::XIntrospectionAccess> Implementation::inspect(
SupportedClassSeq[0] = xImplClass;
}
- xPropSet = Reference<XPropertySet>::query( x );
+ if ( bHasPropertySet )
+ xPropSet = Reference<XPropertySet>::query( x );
// Jetzt versuchen, das PropertySetInfo zu bekommen
if( xPropSet.is() )
xPropSetInfo = xPropSet->getPropertySetInfo();
@@ -1660,7 +1790,7 @@ css::uno::Reference<css::beans::XIntrospectionAccess> Implementation::inspect(
}
if (xTypeProvider.is()) {
- TypeKey key(xPropSetInfo, xTypeProvider->getTypes());
+ TypeKey key(xPropSetInfo, SupportedTypesSeq);
osl::MutexGuard g(m_aMutex);
if (rBHelper.bDisposed || rBHelper.bInDispose) {
@@ -1700,6 +1830,8 @@ css::uno::Reference<css::beans::XIntrospectionAccess> Implementation::inspect(
if( !pAccess.is() )
pAccess = new IntrospectionAccessStatic_Impl( reflection );
+ pAccess->mbPropertySet = bHasPropertySet;
+
// Referenzen auf wichtige Daten von pAccess
sal_Int32& rPropCount = pAccess->mnPropCount;
IntrospectionNameMap& rPropNameMap = pAccess->maPropertyNameMap;
@@ -1949,22 +2081,43 @@ css::uno::Reference<css::beans::XIntrospectionAccess> Implementation::inspect(
rMethodConcept_i |= ( NAMECONTAINER |
INDEXCONTAINER |
ENUMERATION );
+ pAccess->mbElementAccess = true;
} else if ((className
- == "com.sun.star.container.XNameContainer")
- || (className
- == "com.sun.star.container.XNameAccess"))
+ == "com.sun.star.container.XNameContainer"))
{
rMethodConcept_i |= NAMECONTAINER;
+ pAccess->mbNameContainer = true;
+ pAccess->mbNameAccess = true;
+ pAccess->mbElementAccess = true;
} else if ((className
- == "com.sun.star.container.XIndexContainer")
- || (className
- == "com.sun.star.container.XIndexAccess"))
+ == "com.sun.star.container.XNameAccess"))
+ {
+ rMethodConcept_i |= NAMECONTAINER;
+ pAccess->mbNameAccess = true;
+ pAccess->mbElementAccess = true;
+ } else if ((className
+ == "com.sun.star.container.XIndexContainer"))
{
rMethodConcept_i |= INDEXCONTAINER;
+ pAccess->mbIndexContainer = true;
+ pAccess->mbIndexAccess = true;
+ pAccess->mbElementAccess = true;
+ } else if ((className
+ == "com.sun.star.container.XIndexAccess"))
+ {
+ rMethodConcept_i |= INDEXCONTAINER;
+ pAccess->mbIndexAccess = true;
+ pAccess->mbElementAccess = true;
} else if (className
== "com.sun.star.container.XEnumerationAccess")
{
rMethodConcept_i |= ENUMERATION;
+ pAccess->mbEnumerationAccess = true;
+ pAccess->mbElementAccess = true;
+ } else if (className
+ == "com.sun.star.reflection.XIdlArray")
+ {
+ pAccess->mbIdlArray = true;
}
// Wenn der Name zu kurz ist, wird's sowieso nichts
More information about the Libreoffice-commits
mailing list