Title: [115392] trunk/Source/WebCore
Revision
115392
Author
[email protected]
Date
2012-04-26 18:03:26 -0700 (Thu, 26 Apr 2012)

Log Message

Use WebKit types for the cache of ObjcClass::methodsNamed()
https://bugs.webkit.org/show_bug.cgi?id=85012

Patch by Benjamin Poulain <[email protected]> on 2012-04-26
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):

Modified Paths

Diff

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;
             }
         }
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to