Kaydet (Commit) a37df351 authored tarafından Matthew J. Francis's avatar Matthew J. Francis Kaydeden (comit) Matthew Francis

Fix logic in the fast path of Implementation::inspect()

- Merge TypeCache and ClassCache
- Don't fill SupportedClassSeq before the fast exit for a
  cache hit
- Do query XPropertySet blind in the degenerate interface case

Change-Id: I3fd8ab4a215f4c217e1a687af679aef4a21b68b9
Reviewed-on: https://gerrit.libreoffice.org/16921Reviewed-by: 's avatarMatthew Francis <mjay.francis@gmail.com>
Tested-by: 's avatarMatthew Francis <mjay.francis@gmail.com>
üst a64c48f5
...@@ -197,7 +197,6 @@ class IntrospectionAccessStatic_Impl: public salhelper::SimpleReferenceObject ...@@ -197,7 +197,6 @@ class IntrospectionAccessStatic_Impl: public salhelper::SimpleReferenceObject
// Flags which indicate if various interfaces are present // Flags which indicate if various interfaces are present
bool mbFastPropSet; bool mbFastPropSet;
bool mbPropertySet;
bool mbElementAccess; bool mbElementAccess;
bool mbNameAccess; bool mbNameAccess;
bool mbNameContainer; bool mbNameContainer;
...@@ -270,7 +269,6 @@ IntrospectionAccessStatic_Impl::IntrospectionAccessStatic_Impl( Reference< XIdlR ...@@ -270,7 +269,6 @@ IntrospectionAccessStatic_Impl::IntrospectionAccessStatic_Impl( Reference< XIdlR
maPropertyConceptSeq.realloc( ARRAY_SIZE_STEP ); maPropertyConceptSeq.realloc( ARRAY_SIZE_STEP );
mbFastPropSet = false; mbFastPropSet = false;
mbPropertySet = false;
mbElementAccess = false; mbElementAccess = false;
mbNameAccess = false; mbNameAccess = false;
mbNameContainer = false; mbNameContainer = false;
...@@ -1499,55 +1497,6 @@ OUString ImplIntrospectionAccess::getExactName( const OUString& rApproximateName ...@@ -1499,55 +1497,6 @@ OUString ImplIntrospectionAccess::getExactName( const OUString& rApproximateName
return aRetStr; return aRetStr;
} }
struct ClassKey {
ClassKey(
css::uno::Reference<css::beans::XPropertySetInfo> const & theProperties,
css::uno::Reference<css::reflection::XIdlClass> const &
theImplementation,
css::uno::Sequence< css::uno::Reference<css::reflection::XIdlClass> >
const & theClasses):
properties(theProperties), implementation(theImplementation),
classes(theClasses)
{}
css::uno::Reference<css::beans::XPropertySetInfo> properties;
css::uno::Reference<css::reflection::XIdlClass> implementation;
css::uno::Sequence< css::uno::Reference<css::reflection::XIdlClass> >
classes;
};
struct ClassKeyLess {
bool operator ()(ClassKey const & key1, ClassKey const & key2) const {
if (key1.properties.get() < key2.properties.get()) {
return true;
}
if (key1.properties.get() > key2.properties.get()) {
return false;
}
if (key1.implementation.get() < key2.implementation.get()) {
return true;
}
if (key1.implementation.get() > key2.implementation.get()) {
return false;
}
if (key1.classes.getLength() < key2.classes.getLength()) {
return true;
}
if (key1.classes.getLength() > key2.classes.getLength()) {
return false;
}
for (sal_Int32 i = 0; i != key1.classes.getLength(); ++i) {
if (key1.classes[i].get() < key2.classes[i].get()) {
return true;
}
if (key1.classes[i].get() > key2.classes[i].get()) {
return false;
}
}
return false;
}
};
struct TypeKey { struct TypeKey {
TypeKey( TypeKey(
css::uno::Reference<css::beans::XPropertySetInfo> const & theProperties, css::uno::Reference<css::beans::XPropertySetInfo> const & theProperties,
...@@ -1653,7 +1602,6 @@ private: ...@@ -1653,7 +1602,6 @@ private:
virtual void SAL_CALL disposing() SAL_OVERRIDE { virtual void SAL_CALL disposing() SAL_OVERRIDE {
osl::MutexGuard g(m_aMutex); osl::MutexGuard g(m_aMutex);
reflection_.clear(); reflection_.clear();
classCache_.clear();
typeCache_.clear(); typeCache_.clear();
} }
...@@ -1679,7 +1627,6 @@ private: ...@@ -1679,7 +1627,6 @@ private:
throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE; throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
css::uno::Reference<css::reflection::XIdlReflection> reflection_; css::uno::Reference<css::reflection::XIdlReflection> reflection_;
Cache<ClassKey, ClassKeyLess> classCache_;
Cache<TypeKey, TypeKeyLess> typeCache_; Cache<TypeKey, TypeKeyLess> typeCache_;
}; };
...@@ -1731,10 +1678,8 @@ css::uno::Reference<css::beans::XIntrospectionAccess> Implementation::inspect( ...@@ -1731,10 +1678,8 @@ css::uno::Reference<css::beans::XIntrospectionAccess> Implementation::inspect(
Sequence< Reference<XIdlClass> > SupportedClassSeq; Sequence< Reference<XIdlClass> > SupportedClassSeq;
Sequence< Type > SupportedTypesSeq; Sequence< Type > SupportedTypesSeq;
Reference<XTypeProvider> xTypeProvider; Reference<XTypeProvider> xTypeProvider;
Reference<XIdlClass> xImplClass;
Reference<XPropertySetInfo> xPropSetInfo; Reference<XPropertySetInfo> xPropSetInfo;
Reference<XPropertySet> xPropSet; Reference<XPropertySet> xPropSet;
bool bHasPropertySet = false;
// Look for interfaces XTypeProvider and PropertySet // Look for interfaces XTypeProvider and PropertySet
if( eType == TypeClass_INTERFACE ) if( eType == TypeClass_INTERFACE )
...@@ -1746,66 +1691,46 @@ css::uno::Reference<css::beans::XIntrospectionAccess> Implementation::inspect( ...@@ -1746,66 +1691,46 @@ css::uno::Reference<css::beans::XIntrospectionAccess> Implementation::inspect(
sal_Int32 nTypeCount = SupportedTypesSeq.getLength(); sal_Int32 nTypeCount = SupportedTypesSeq.getLength();
if( nTypeCount ) if( nTypeCount )
{ {
SupportedClassSeq.realloc( nTypeCount );
Reference<XIdlClass>* pClasses = SupportedClassSeq.getArray();
const Type* pTypes = SupportedTypesSeq.getConstArray(); const Type* pTypes = SupportedTypesSeq.getConstArray();
for( sal_Int32 i = 0 ; i < nTypeCount ; i++ ) for( sal_Int32 i = 0 ; i < nTypeCount ; i++ )
{ {
OUString typeName( pTypes[i].getTypeName() ); if( pTypes[i].getTypeName() == "com.sun.star.beans.XPropertySet" )
pClasses[i] = reflection->forName( typeName ); {
if( !bHasPropertySet && typeName == "com.sun.star.beans.XPropertySet" ) xPropSet = Reference<XPropertySet>::query( x );
bHasPropertySet = true; break;
}
} }
// TODO: Caching!
} }
} else { } else {
SAL_WARN( SAL_WARN(
"stoc", "stoc",
"object of type \"" << aToInspectObj.getValueTypeName() "object of type \"" << aToInspectObj.getValueTypeName()
<< "\" lacks XTypeProvider"); << "\" lacks XTypeProvider");
xImplClass = reflection->forName(aToInspectObj.getValueTypeName()); SupportedTypesSeq = Sequence<Type>(&aToInspectObj.getValueType(), 1);
SupportedClassSeq.realloc(1); xPropSet = Reference<XPropertySet>::query( x );
SupportedClassSeq[0] = xImplClass;
} }
if ( bHasPropertySet )
xPropSet = Reference<XPropertySet>::query( x );
// Now try to get the PropertySetInfo // Now try to get the PropertySetInfo
if( xPropSet.is() ) if( xPropSet.is() )
xPropSetInfo = xPropSet->getPropertySetInfo(); xPropSetInfo = xPropSet->getPropertySetInfo();
} else { } else {
xImplClass = reflection->forName(aToInspectObj.getValueTypeName()); SupportedTypesSeq = Sequence<Type>(&aToInspectObj.getValueType(), 1);
} }
if (xTypeProvider.is()) { {
TypeKey key(xPropSetInfo, SupportedTypesSeq);
osl::MutexGuard g(m_aMutex); osl::MutexGuard g(m_aMutex);
if (rBHelper.bDisposed || rBHelper.bInDispose) { if (rBHelper.bDisposed || rBHelper.bInDispose) {
throw css::lang::DisposedException( throw css::lang::DisposedException(
getImplementationName(), static_cast<OWeakObject *>(this)); getImplementationName(), static_cast<OWeakObject *>(this));
} }
TypeKey key(xPropSetInfo, SupportedTypesSeq);
pAccess = typeCache_.find(key); pAccess = typeCache_.find(key);
if (pAccess.is()) { if (pAccess.is()) {
return new ImplIntrospectionAccess(aToInspectObj, pAccess); return new ImplIntrospectionAccess(aToInspectObj, pAccess);
} }
pAccess = new IntrospectionAccessStatic_Impl(reflection); pAccess = new IntrospectionAccessStatic_Impl(reflection);
typeCache_.insert(key, pAccess); typeCache_.insert(key, pAccess);
} else if (xImplClass.is()) {
ClassKey key(xPropSetInfo, xImplClass, SupportedClassSeq);
osl::MutexGuard g(m_aMutex);
if (rBHelper.bDisposed || rBHelper.bInDispose) {
throw css::lang::DisposedException(
getImplementationName(), static_cast<OWeakObject *>(this));
}
pAccess = classCache_.find(key);
if (pAccess.is()) {
return new ImplIntrospectionAccess(aToInspectObj, pAccess);
}
pAccess = new IntrospectionAccessStatic_Impl(reflection);
classCache_.insert(key, pAccess);
} }
// No access cached -> create new // No access cached -> create new
...@@ -1816,11 +1741,6 @@ css::uno::Reference<css::beans::XIntrospectionAccess> Implementation::inspect( ...@@ -1816,11 +1741,6 @@ css::uno::Reference<css::beans::XIntrospectionAccess> Implementation::inspect(
sal_Int32* pPropertyConceptArray; sal_Int32* pPropertyConceptArray;
sal_Int32 i; sal_Int32 i;
if( !pAccess.is() )
pAccess = new IntrospectionAccessStatic_Impl( reflection );
pAccess->mbPropertySet = bHasPropertySet;
// References to important data from pAccess // References to important data from pAccess
sal_Int32& rPropCount = pAccess->mnPropCount; sal_Int32& rPropCount = pAccess->mnPropCount;
IntrospectionNameMap& rPropNameMap = pAccess->maPropertyNameMap; IntrospectionNameMap& rPropNameMap = pAccess->maPropertyNameMap;
...@@ -1839,6 +1759,17 @@ css::uno::Reference<css::beans::XIntrospectionAccess> Implementation::inspect( ...@@ -1839,6 +1759,17 @@ css::uno::Reference<css::beans::XIntrospectionAccess> Implementation::inspect(
if( eType == TypeClass_INTERFACE ) if( eType == TypeClass_INTERFACE )
{ {
sal_Int32 nTypeCount = SupportedTypesSeq.getLength();
if( nTypeCount )
{
SupportedClassSeq.realloc( nTypeCount );
Reference<XIdlClass>* pClasses = SupportedClassSeq.getArray();
const Type* pTypes = SupportedTypesSeq.getConstArray();
for( i = 0 ; i < nTypeCount ; i++ )
pClasses[i] = reflection->forName( pTypes[i].getTypeName() );
}
// First look for particular interfaces that are of particular // First look for particular interfaces that are of particular
// importance to the introspection // importance to the introspection
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment