Modified: trunk/Source/WebCore/ChangeLog (115391 => 115392)
--- trunk/Source/WebCore/ChangeLog 2012-04-27 00:51:47 UTC (rev 115391)
+++ trunk/Source/WebCore/ChangeLog 2012-04-27 01:03:26 UTC (rev 115392)
@@ -1,3 +1,25 @@
+2012-04-26 Benjamin Poulain <[email protected]>
+
+ Use WebKit types for the cache of ObjcClass::methodsNamed()
+ https://bugs.webkit.org/show_bug.cgi?id=85012
+
+ Reviewed by Geoffrey Garen.
+
+ This patch redefines the method cache ObjcClass to avoid memory allocations in the case of positive match.
+
+ Instead of using the converted name as the key, the original identifier string is used. This shortcuts
+ all the other operations when there is a match.
+
+ A side effect is a method can appear multiple times in the cache if it is invoked with different names using
+ the escape character "$". An attaquer could bloat the cache with a few hundreds strings.
+ In the common case, having each name mapped is an improvment.
+
+ * bridge/objc/objc_class.h:
+ (ObjcClass):
+ * bridge/objc/objc_class.mm:
+ (JSC::Bindings::ObjcClass::ObjcClass):
+ (JSC::Bindings::ObjcClass::methodsNamed):
+
2012-04-26 Ojan Vafai <[email protected]>
Delete dead code in Arena.h/cpp
Modified: trunk/Source/WebCore/bridge/objc/objc_class.h (115391 => 115392)
--- trunk/Source/WebCore/bridge/objc/objc_class.h 2012-04-27 00:51:47 UTC (rev 115391)
+++ trunk/Source/WebCore/bridge/objc/objc_class.h 2012-04-27 01:03:26 UTC (rev 115392)
@@ -50,7 +50,7 @@
private:
ClassStructPtr _isa;
- RetainPtr<CFMutableDictionaryRef> _methods;
+ mutable HashMap<String, OwnPtr<Method> > m_methodCache;
mutable HashMap<String, OwnPtr<Field> > m_fieldCache;
};
Modified: trunk/Source/WebCore/bridge/objc/objc_class.mm (115391 => 115392)
--- trunk/Source/WebCore/bridge/objc/objc_class.mm 2012-04-27 00:51:47 UTC (rev 115391)
+++ trunk/Source/WebCore/bridge/objc/objc_class.mm 2012-04-27 01:03:26 UTC (rev 115392)
@@ -31,17 +31,9 @@
namespace JSC {
namespace Bindings {
-
-static void deleteMethod(CFAllocatorRef, const void* value)
-{
- delete static_cast<const Method*>(value);
-}
-const CFDictionaryValueCallBacks MethodDictionaryValueCallBacks = { 0, 0, &deleteMethod, 0 , 0 };
-
ObjcClass::ObjcClass(ClassStructPtr aClass)
: _isa(aClass)
- , _methods(AdoptCF, CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &MethodDictionaryValueCallBacks))
{
}
@@ -105,18 +97,17 @@
MethodList ObjcClass::methodsNamed(const Identifier& identifier, Instance*) const
{
- CString jsName = identifier.ascii();
- JSNameConversionBuffer buffer;
- convertJSMethodNameToObjc(jsName, buffer);
-
MethodList methodList;
- RetainPtr<CFStringRef> methodName(AdoptCF, CFStringCreateWithCString(NULL, buffer.data(), kCFStringEncodingASCII));
- Method* method = (Method*)CFDictionaryGetValue(_methods.get(), methodName.get());
- if (method) {
+ if (Method* method = m_methodCache.get(identifier.impl())) {
methodList.append(method);
return methodList;
}
+ CString jsName = identifier.ascii();
+ JSNameConversionBuffer buffer;
+ convertJSMethodNameToObjc(jsName, buffer);
+ RetainPtr<CFStringRef> methodName(AdoptCF, CFStringCreateWithCString(NULL, buffer.data(), kCFStringEncodingASCII));
+
ClassStructPtr thisClass = _isa;
while (thisClass && methodList.isEmpty()) {
unsigned numMethodsInClass = 0;
@@ -139,9 +130,9 @@
mappedName = [thisClass webScriptNameForSelector:objcMethodSelector];
if ((mappedName && [mappedName isEqual:(NSString*)methodName.get()]) || strcmp(objcMethodSelectorName, buffer.data()) == 0) {
- Method* aMethod = new ObjcMethod(thisClass, objcMethodSelector); // deleted when the dictionary is destroyed
- CFDictionaryAddValue(_methods.get(), methodName.get(), aMethod);
- methodList.append(aMethod);
+ OwnPtr<Method> method = adoptPtr(new ObjcMethod(thisClass, objcMethodSelector));
+ methodList.append(method.get());
+ m_methodCache.add(identifier.impl(), method.release());
break;
}
}