Title: [139469] trunk/Source/WebCore
Revision
139469
Author
[email protected]
Date
2013-01-11 11:27:39 -0800 (Fri, 11 Jan 2013)

Log Message

[V8] Do not create a local handle for a cached v8 string that is returned to V8 immediately
https://bugs.webkit.org/show_bug.cgi?id=106557

Reviewed by Adam Barth.

Currently we are always creating a local handle for a cached
V8 string returned to V8:

  Handle<Value> v8String(StringImpl* impl, Isolate* isolate) {
    ...;
    return Local<String>::New(isolate, m_cachedString);
  }

However, we don't need to create a local handle in a case
where it is guaranteed that no V8 object allocation is conducted
before a control flow returns back to V8. In particular, in a case
where a cached V8 string is immediately returned to V8, we don't
need to create a local handle:

  Handle<Value> xxxxAttrGetter() {
    ...;
    return v8String(imp->xxxx(), isolate);  // This can return a persistent handle safely.
  }

This patch improves performance of div.id by 9.2%.

No tests. No change in behavior.

* bindings/scripts/CodeGeneratorV8.pm:
(GenerateNormalAttrGetter):
(GenerateCallbackImplementation):
(GenerateFunctionCallString):
(NativeToJSValue):
* bindings/scripts/test/V8/V8TestEventConstructor.cpp:
(WebCore::TestEventConstructorV8Internal::attr1AttrGetter):
(WebCore::TestEventConstructorV8Internal::attr2AttrGetter):
* bindings/scripts/test/V8/V8TestException.cpp:
(WebCore::TestExceptionV8Internal::nameAttrGetter):
* bindings/scripts/test/V8/V8TestInterface.cpp:
(WebCore::TestInterfaceV8Internal::supplementalStaticAttrAttrGetter):
(WebCore::TestInterfaceV8Internal::supplementalStr1AttrGetter):
(WebCore::TestInterfaceV8Internal::supplementalStr2AttrGetter):
* bindings/scripts/test/V8/V8TestObj.cpp:
(WebCore::TestObjV8Internal::readOnlyStringAttrAttrGetter):
(WebCore::TestObjV8Internal::staticStringAttrAttrGetter):
(WebCore::TestObjV8Internal::stringAttrAttrGetter):
(WebCore::TestObjV8Internal::reflectedStringAttrAttrGetter):
(WebCore::TestObjV8Internal::reflectedURLAttrAttrGetter):
(WebCore::TestObjV8Internal::reflectedCustomURLAttrAttrGetter):
(WebCore::TestObjV8Internal::stringAttrWithGetterExceptionAttrGetter):
(WebCore::TestObjV8Internal::stringAttrWithSetterExceptionAttrGetter):
(WebCore::TestObjV8Internal::hashAttrGetter):
(WebCore::TestObjV8Internal::conditionalMethod1Callback):
* bindings/v8/V8Binding.h:
(WebCore::v8String):
(WebCore::v8StringOrNull):
(WebCore::v8StringOrUndefined):
* bindings/v8/V8ValueCache.cpp:
(WebCore::StringCache::v8ExternalStringSlow):
* bindings/v8/V8ValueCache.h:
(WebCore::StringCache::v8ExternalString):
(StringCache):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (139468 => 139469)


--- trunk/Source/WebCore/ChangeLog	2013-01-11 19:21:55 UTC (rev 139468)
+++ trunk/Source/WebCore/ChangeLog	2013-01-11 19:27:39 UTC (rev 139469)
@@ -1,3 +1,68 @@
+2013-01-11  Kentaro Hara  <[email protected]>
+
+        [V8] Do not create a local handle for a cached v8 string that is returned to V8 immediately
+        https://bugs.webkit.org/show_bug.cgi?id=106557
+
+        Reviewed by Adam Barth.
+
+        Currently we are always creating a local handle for a cached
+        V8 string returned to V8:
+
+          Handle<Value> v8String(StringImpl* impl, Isolate* isolate) {
+            ...;
+            return Local<String>::New(isolate, m_cachedString);
+          }
+
+        However, we don't need to create a local handle in a case
+        where it is guaranteed that no V8 object allocation is conducted
+        before a control flow returns back to V8. In particular, in a case
+        where a cached V8 string is immediately returned to V8, we don't
+        need to create a local handle:
+
+          Handle<Value> xxxxAttrGetter() {
+            ...;
+            return v8String(imp->xxxx(), isolate);  // This can return a persistent handle safely.
+          }
+
+        This patch improves performance of div.id by 9.2%.
+
+        No tests. No change in behavior.
+
+        * bindings/scripts/CodeGeneratorV8.pm:
+        (GenerateNormalAttrGetter):
+        (GenerateCallbackImplementation):
+        (GenerateFunctionCallString):
+        (NativeToJSValue):
+        * bindings/scripts/test/V8/V8TestEventConstructor.cpp:
+        (WebCore::TestEventConstructorV8Internal::attr1AttrGetter):
+        (WebCore::TestEventConstructorV8Internal::attr2AttrGetter):
+        * bindings/scripts/test/V8/V8TestException.cpp:
+        (WebCore::TestExceptionV8Internal::nameAttrGetter):
+        * bindings/scripts/test/V8/V8TestInterface.cpp:
+        (WebCore::TestInterfaceV8Internal::supplementalStaticAttrAttrGetter):
+        (WebCore::TestInterfaceV8Internal::supplementalStr1AttrGetter):
+        (WebCore::TestInterfaceV8Internal::supplementalStr2AttrGetter):
+        * bindings/scripts/test/V8/V8TestObj.cpp:
+        (WebCore::TestObjV8Internal::readOnlyStringAttrAttrGetter):
+        (WebCore::TestObjV8Internal::staticStringAttrAttrGetter):
+        (WebCore::TestObjV8Internal::stringAttrAttrGetter):
+        (WebCore::TestObjV8Internal::reflectedStringAttrAttrGetter):
+        (WebCore::TestObjV8Internal::reflectedURLAttrAttrGetter):
+        (WebCore::TestObjV8Internal::reflectedCustomURLAttrAttrGetter):
+        (WebCore::TestObjV8Internal::stringAttrWithGetterExceptionAttrGetter):
+        (WebCore::TestObjV8Internal::stringAttrWithSetterExceptionAttrGetter):
+        (WebCore::TestObjV8Internal::hashAttrGetter):
+        (WebCore::TestObjV8Internal::conditionalMethod1Callback):
+        * bindings/v8/V8Binding.h:
+        (WebCore::v8String):
+        (WebCore::v8StringOrNull):
+        (WebCore::v8StringOrUndefined):
+        * bindings/v8/V8ValueCache.cpp:
+        (WebCore::StringCache::v8ExternalStringSlow):
+        * bindings/v8/V8ValueCache.h:
+        (WebCore::StringCache::v8ExternalString):
+        (StringCache):
+
 2013-01-11  Carlos Garcia Campos  <[email protected]>
 
         Unreviewed. Fix make distcheck.

Modified: trunk/Source/WebCore/bindings/scripts/CodeGeneratorV8.pm (139468 => 139469)


--- trunk/Source/WebCore/bindings/scripts/CodeGeneratorV8.pm	2013-01-11 19:21:55 UTC (rev 139468)
+++ trunk/Source/WebCore/bindings/scripts/CodeGeneratorV8.pm	2013-01-11 19:27:39 UTC (rev 139469)
@@ -929,7 +929,7 @@
             # Generate super-compact call for regular attribute getter:
             my ($functionName, @arguments) = $codeGenerator->GetterExpression(\%implIncludes, $interfaceName, $attribute);
             push(@implContentDecls, "    Element* imp = V8Element::toNative(info.Holder());\n");
-            push(@implContentDecls, "    return v8String(imp->${functionName}(" . join(", ", @arguments) . "), info.GetIsolate());\n");
+            push(@implContentDecls, "    return v8String(imp->${functionName}(" . join(", ", @arguments) . "), info.GetIsolate(), ReturnUnsafeHandle);\n");
             push(@implContentDecls, "}\n\n");
             push(@implContentDecls, "#endif // ${conditionalString}\n\n") if $conditionalString;
             return;
@@ -1114,7 +1114,7 @@
     return value;
 END
     } else {
-        push(@implContentDecls, "    return " . NativeToJSValue($attribute->signature, $result, "info.Holder()", "info.GetIsolate()", "info", "imp").";\n");
+        push(@implContentDecls, "    return " . NativeToJSValue($attribute->signature, $result, "info.Holder()", "info.GetIsolate()", "info", "imp", "ReturnUnsafeHandle").";\n");
     }
 
     push(@implContentDecls, "}\n\n");  # end of getter
@@ -3618,9 +3618,9 @@
     my $nativeValue;
     # FIXME: Update for all ScriptWrappables.
     if (IsDOMNodeType($interfaceName)) {
-        $nativeValue = NativeToJSValue($function->signature, $return, "args.Holder()", "args.GetIsolate()", "args", "imp");
+        $nativeValue = NativeToJSValue($function->signature, $return, "args.Holder()", "args.GetIsolate()", "args", "imp", "ReturnUnsafeHandle");
     } else {
-        $nativeValue = NativeToJSValue($function->signature, $return, "args.Holder()", "args.GetIsolate()");
+        $nativeValue = NativeToJSValue($function->signature, $return, "args.Holder()", "args.GetIsolate()", 0, 0, "ReturnUnsafeHandle");
     }
 
     $result .= $indent . "return " . $nativeValue . ";\n";
@@ -4030,6 +4030,8 @@
     my $getHolderContainerArg = $getHolderContainer ? ", $getHolderContainer" : "";
     my $getScriptWrappable = shift;
     my $getScriptWrappableArg = $getScriptWrappable ? ", $getScriptWrappable" : "";
+    my $returnHandleType = shift;
+
     my $type = $signature->type;
 
     return ($getIsolate ? "v8Boolean($value, $getIsolate)" : "v8Boolean($value)") if $type eq "boolean";
@@ -4058,12 +4060,12 @@
     if ($codeGenerator->IsStringType($type)) {
         my $conv = $signature->extendedAttributes->{"TreatReturnedNullStringAs"};
         if (defined $conv) {
-            return "v8StringOrNull($value$getIsolateArg)" if $conv eq "Null";
-            return "v8StringOrUndefined($value$getIsolateArg)" if $conv eq "Undefined";
+            return "v8StringOrNull($value$getIsolateArg, $returnHandleType)" if $conv eq "Null";
+            return "v8StringOrUndefined($value$getIsolateArg, $returnHandleType)" if $conv eq "Undefined";
 
             die "Unknown value for TreatReturnedNullStringAs extended attribute";
         }
-        return $getIsolate ? "v8String($value, $getIsolate)" : "deprecatedV8String($value)";
+        return $getIsolate ? "v8String($value$getIsolateArg, $returnHandleType)" : "deprecatedV8String($value)";
     }
 
     my $arrayType = $codeGenerator->GetArrayType($type);

Modified: trunk/Source/WebCore/bindings/scripts/test/V8/V8TestEventConstructor.cpp (139468 => 139469)


--- trunk/Source/WebCore/bindings/scripts/test/V8/V8TestEventConstructor.cpp	2013-01-11 19:21:55 UTC (rev 139468)
+++ trunk/Source/WebCore/bindings/scripts/test/V8/V8TestEventConstructor.cpp	2013-01-11 19:27:39 UTC (rev 139469)
@@ -41,13 +41,13 @@
 static v8::Handle<v8::Value> attr1AttrGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info)
 {
     TestEventConstructor* imp = V8TestEventConstructor::toNative(info.Holder());
-    return v8String(imp->attr1(), info.GetIsolate());
+    return v8String(imp->attr1(), info.GetIsolate(), ReturnPersistentHandle);
 }
 
 static v8::Handle<v8::Value> attr2AttrGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info)
 {
     TestEventConstructor* imp = V8TestEventConstructor::toNative(info.Holder());
-    return v8String(imp->attr2(), info.GetIsolate());
+    return v8String(imp->attr2(), info.GetIsolate(), ReturnPersistentHandle);
 }
 
 } // namespace TestEventConstructorV8Internal

Modified: trunk/Source/WebCore/bindings/scripts/test/V8/V8TestException.cpp (139468 => 139469)


--- trunk/Source/WebCore/bindings/scripts/test/V8/V8TestException.cpp	2013-01-11 19:21:55 UTC (rev 139468)
+++ trunk/Source/WebCore/bindings/scripts/test/V8/V8TestException.cpp	2013-01-11 19:27:39 UTC (rev 139469)
@@ -40,7 +40,7 @@
 static v8::Handle<v8::Value> nameAttrGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info)
 {
     TestException* imp = V8TestException::toNative(info.Holder());
-    return v8String(imp->name(), info.GetIsolate());
+    return v8String(imp->name(), info.GetIsolate(), ReturnPersistentHandle);
 }
 
 } // namespace TestExceptionV8Internal

Modified: trunk/Source/WebCore/bindings/scripts/test/V8/V8TestInterface.cpp (139468 => 139469)


--- trunk/Source/WebCore/bindings/scripts/test/V8/V8TestInterface.cpp	2013-01-11 19:21:55 UTC (rev 139468)
+++ trunk/Source/WebCore/bindings/scripts/test/V8/V8TestInterface.cpp	2013-01-11 19:27:39 UTC (rev 139469)
@@ -59,7 +59,7 @@
 
 static v8::Handle<v8::Value> supplementalStaticAttrAttrGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info)
 {
-    return v8String(TestSupplemental::supplementalStaticAttr(), info.GetIsolate());
+    return v8String(TestSupplemental::supplementalStaticAttr(), info.GetIsolate(), ReturnPersistentHandle);
 }
 
 #endif // ENABLE(Condition11) || ENABLE(Condition12)
@@ -80,7 +80,7 @@
 static v8::Handle<v8::Value> supplementalStr1AttrGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info)
 {
     TestInterface* imp = V8TestInterface::toNative(info.Holder());
-    return v8String(TestSupplemental::supplementalStr1(imp), info.GetIsolate());
+    return v8String(TestSupplemental::supplementalStr1(imp), info.GetIsolate(), ReturnPersistentHandle);
 }
 
 #endif // ENABLE(Condition11) || ENABLE(Condition12)
@@ -90,7 +90,7 @@
 static v8::Handle<v8::Value> supplementalStr2AttrGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info)
 {
     TestInterface* imp = V8TestInterface::toNative(info.Holder());
-    return v8String(TestSupplemental::supplementalStr2(imp), info.GetIsolate());
+    return v8String(TestSupplemental::supplementalStr2(imp), info.GetIsolate(), ReturnPersistentHandle);
 }
 
 #endif // ENABLE(Condition11) || ENABLE(Condition12)

Modified: trunk/Source/WebCore/bindings/scripts/test/V8/V8TestObj.cpp (139468 => 139469)


--- trunk/Source/WebCore/bindings/scripts/test/V8/V8TestObj.cpp	2013-01-11 19:21:55 UTC (rev 139468)
+++ trunk/Source/WebCore/bindings/scripts/test/V8/V8TestObj.cpp	2013-01-11 19:27:39 UTC (rev 139469)
@@ -90,7 +90,7 @@
 static v8::Handle<v8::Value> readOnlyStringAttrAttrGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info)
 {
     TestObj* imp = V8TestObj::toNative(info.Holder());
-    return v8String(imp->readOnlyStringAttr(), info.GetIsolate());
+    return v8String(imp->readOnlyStringAttr(), info.GetIsolate(), ReturnPersistentHandle);
 }
 
 static v8::Handle<v8::Value> readOnlyTestObjAttrAttrGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info)
@@ -113,7 +113,7 @@
 
 static v8::Handle<v8::Value> staticStringAttrAttrGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info)
 {
-    return v8String(TestObj::staticStringAttr(), info.GetIsolate());
+    return v8String(TestObj::staticStringAttr(), info.GetIsolate(), ReturnPersistentHandle);
 }
 
 static void staticStringAttrAttrSetter(v8::Local<v8::String> name, v8::Local<v8::Value> value, const v8::AccessorInfo& info)
@@ -196,7 +196,7 @@
 static v8::Handle<v8::Value> stringAttrAttrGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info)
 {
     TestObj* imp = V8TestObj::toNative(info.Holder());
-    return v8String(imp->stringAttr(), info.GetIsolate());
+    return v8String(imp->stringAttr(), info.GetIsolate(), ReturnPersistentHandle);
 }
 
 static void stringAttrAttrSetter(v8::Local<v8::String> name, v8::Local<v8::Value> value, const v8::AccessorInfo& info)
@@ -254,7 +254,7 @@
 static v8::Handle<v8::Value> reflectedStringAttrAttrGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info)
 {
     TestObj* imp = V8TestObj::toNative(info.Holder());
-    return v8String(imp->fastGetAttribute(WebCore::HTMLNames::reflectedstringattrAttr), info.GetIsolate());
+    return v8String(imp->fastGetAttribute(WebCore::HTMLNames::reflectedstringattrAttr), info.GetIsolate(), ReturnPersistentHandle);
 }
 
 static void reflectedStringAttrAttrSetter(v8::Local<v8::String> name, v8::Local<v8::Value> value, const v8::AccessorInfo& info)
@@ -310,7 +310,7 @@
 static v8::Handle<v8::Value> reflectedURLAttrAttrGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info)
 {
     TestObj* imp = V8TestObj::toNative(info.Holder());
-    return v8String(imp->getURLAttribute(WebCore::HTMLNames::reflectedurlattrAttr), info.GetIsolate());
+    return v8String(imp->getURLAttribute(WebCore::HTMLNames::reflectedurlattrAttr), info.GetIsolate(), ReturnPersistentHandle);
 }
 
 static void reflectedURLAttrAttrSetter(v8::Local<v8::String> name, v8::Local<v8::Value> value, const v8::AccessorInfo& info)
@@ -324,7 +324,7 @@
 static v8::Handle<v8::Value> reflectedStringAttrAttrGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info)
 {
     TestObj* imp = V8TestObj::toNative(info.Holder());
-    return v8String(imp->fastGetAttribute(WebCore::HTMLNames::customContentStringAttrAttr), info.GetIsolate());
+    return v8String(imp->fastGetAttribute(WebCore::HTMLNames::customContentStringAttrAttr), info.GetIsolate(), ReturnPersistentHandle);
 }
 
 static void reflectedStringAttrAttrSetter(v8::Local<v8::String> name, v8::Local<v8::Value> value, const v8::AccessorInfo& info)
@@ -366,7 +366,7 @@
 static v8::Handle<v8::Value> reflectedCustomURLAttrAttrGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info)
 {
     TestObj* imp = V8TestObj::toNative(info.Holder());
-    return v8String(imp->getURLAttribute(WebCore::HTMLNames::customContentURLAttrAttr), info.GetIsolate());
+    return v8String(imp->getURLAttribute(WebCore::HTMLNames::customContentURLAttrAttr), info.GetIsolate(), ReturnPersistentHandle);
 }
 
 static void reflectedCustomURLAttrAttrSetter(v8::Local<v8::String> name, v8::Local<v8::Value> value, const v8::AccessorInfo& info)
@@ -433,7 +433,7 @@
     String v = imp->stringAttrWithGetterException(ec);
     if (UNLIKELY(ec))
         return setDOMException(ec, info.GetIsolate());
-    return v8String(v, info.GetIsolate());
+    return v8String(v, info.GetIsolate(), ReturnPersistentHandle);
 }
 
 static void stringAttrWithGetterExceptionAttrSetter(v8::Local<v8::String> name, v8::Local<v8::Value> value, const v8::AccessorInfo& info)
@@ -447,7 +447,7 @@
 static v8::Handle<v8::Value> stringAttrWithSetterExceptionAttrGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info)
 {
     TestObj* imp = V8TestObj::toNative(info.Holder());
-    return v8String(imp->stringAttrWithSetterException(), info.GetIsolate());
+    return v8String(imp->stringAttrWithSetterException(), info.GetIsolate(), ReturnPersistentHandle);
 }
 
 static void stringAttrWithSetterExceptionAttrSetter(v8::Local<v8::String> name, v8::Local<v8::Value> value, const v8::AccessorInfo& info)
@@ -913,7 +913,7 @@
 static v8::Handle<v8::Value> hashAttrGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info)
 {
     TestObj* imp = V8TestObj::toNative(info.Holder());
-    return v8String(imp->hash(), info.GetIsolate());
+    return v8String(imp->hash(), info.GetIsolate(), ReturnPersistentHandle);
 }
 
 static v8::Handle<v8::Value> replaceableAttributeAttrGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info)
@@ -1371,7 +1371,7 @@
 static v8::Handle<v8::Value> conditionalMethod1Callback(const v8::Arguments& args)
 {
     TestObj* imp = V8TestObj::toNative(args.Holder());
-    return v8String(imp->conditionalMethod1(), args.GetIsolate());
+    return v8String(imp->conditionalMethod1(), args.GetIsolate(), ReturnPersistentHandle);
 }
 
 #endif // ENABLE(Condition1)

Modified: trunk/Source/WebCore/bindings/v8/V8Binding.h (139468 => 139469)


--- trunk/Source/WebCore/bindings/v8/V8Binding.h	2013-01-11 19:21:55 UTC (rev 139468)
+++ trunk/Source/WebCore/bindings/v8/V8Binding.h	2013-01-11 19:27:39 UTC (rev 139469)
@@ -145,13 +145,13 @@
     // Return a V8 external string that shares the underlying buffer with the given
     // WebCore string. The reference counting mechanism is used to keep the
     // underlying buffer alive while the string is still live in the V8 engine.
-    inline v8::Handle<v8::String> v8String(const String& string, v8::Isolate* isolate = 0)
+    inline v8::Handle<v8::String> v8String(const String& string, v8::Isolate* isolate = 0, ReturnHandleType handleType = ReturnLocalHandle)
     {
         if (UNLIKELY(!isolate))
             isolate = v8::Isolate::GetCurrent();
         if (string.isNull())
             return v8::String::Empty(isolate);
-        return V8PerIsolateData::from(isolate)->stringCache()->v8ExternalString(string.impl(), isolate);
+        return V8PerIsolateData::from(isolate)->stringCache()->v8ExternalString(string.impl(), handleType, isolate);
     }
 
     // FIXME: All call sites of this method should use v8String().
@@ -160,20 +160,20 @@
         return v8String(string, v8::Isolate::GetCurrent());
     }
 
-    inline v8::Handle<v8::Value> v8StringOrNull(const String& string, v8::Isolate* isolate)
+    inline v8::Handle<v8::Value> v8StringOrNull(const String& string, v8::Isolate* isolate, ReturnHandleType handleType = ReturnLocalHandle)
     {
         ASSERT(isolate);
         if (string.isNull())
             return v8Null(isolate);
-        return V8PerIsolateData::from(isolate)->stringCache()->v8ExternalString(string.impl(), isolate);
+        return V8PerIsolateData::from(isolate)->stringCache()->v8ExternalString(string.impl(), handleType, isolate);
     }
 
-    inline v8::Handle<v8::Value> v8StringOrUndefined(const String& string, v8::Isolate* isolate)
+    inline v8::Handle<v8::Value> v8StringOrUndefined(const String& string, v8::Isolate* isolate, ReturnHandleType handleType = ReturnLocalHandle)
     {
         ASSERT(isolate);
         if (string.isNull())
             return v8::Undefined(isolate);
-        return V8PerIsolateData::from(isolate)->stringCache()->v8ExternalString(string.impl(), isolate);
+        return V8PerIsolateData::from(isolate)->stringCache()->v8ExternalString(string.impl(), handleType, isolate);
     }
 
     inline v8::Handle<v8::Integer> v8Integer(int value, v8::Isolate* isolate = 0)

Modified: trunk/Source/WebCore/bindings/v8/V8ValueCache.cpp (139468 => 139469)


--- trunk/Source/WebCore/bindings/v8/V8ValueCache.cpp	2013-01-11 19:21:55 UTC (rev 139468)
+++ trunk/Source/WebCore/bindings/v8/V8ValueCache.cpp	2013-01-11 19:27:39 UTC (rev 139469)
@@ -76,7 +76,7 @@
     clearOnGC();
 }
 
-v8::Local<v8::String> StringCache::v8ExternalStringSlow(StringImpl* stringImpl, v8::Isolate* isolate)
+v8::Handle<v8::String> StringCache::v8ExternalStringSlow(StringImpl* stringImpl, ReturnHandleType handleType, v8::Isolate* isolate)
 {
     if (!stringImpl->length())
         return v8::String::Empty(isolate);
@@ -87,6 +87,8 @@
         if (handle.IsWeak()) {
             m_lastStringImpl = stringImpl;
             m_lastV8String = handle;
+            if (handleType == ReturnUnsafeHandle)
+                return handle;
             return v8::Local<v8::String>::New(handle);
         }
     }

Modified: trunk/Source/WebCore/bindings/v8/V8ValueCache.h (139468 => 139469)


--- trunk/Source/WebCore/bindings/v8/V8ValueCache.h	2013-01-11 19:21:55 UTC (rev 139468)
+++ trunk/Source/WebCore/bindings/v8/V8ValueCache.h	2013-01-11 19:27:39 UTC (rev 139469)
@@ -35,16 +35,28 @@
 
 namespace WebCore {
 
+// ReturnUnsafeHandle can be used only when it is guaranteed
+// that no V8 object allocation is conducted before the handle
+// is returned to V8. For safety, ReturnUnsafeHandle should be
+// used by auto-generated code.
+enum ReturnHandleType {
+    ReturnLocalHandle,
+    ReturnUnsafeHandle
+};
+
 class StringCache {
 public:
     StringCache() { }
 
-    v8::Local<v8::String> v8ExternalString(StringImpl* stringImpl, v8::Isolate* isolate)
+    v8::Handle<v8::String> v8ExternalString(StringImpl* stringImpl, ReturnHandleType handleType, v8::Isolate* isolate)
     {
-        if (m_lastStringImpl.get() == stringImpl && m_lastV8String.IsWeak(isolate))
+        if (m_lastStringImpl.get() == stringImpl && m_lastV8String.IsWeak(isolate)) {
+            if (handleType == ReturnUnsafeHandle)
+                return m_lastV8String;
             return v8::Local<v8::String>::New(isolate, m_lastV8String);
+        }
 
-        return v8ExternalStringSlow(stringImpl, isolate);
+        return v8ExternalStringSlow(stringImpl, handleType, isolate);
     }
 
     void clearOnGC() 
@@ -57,7 +69,7 @@
     void reportMemoryUsage(MemoryObjectInfo*) const;
 
 private:
-    v8::Local<v8::String> v8ExternalStringSlow(StringImpl*, v8::Isolate*);
+    v8::Handle<v8::String> v8ExternalStringSlow(StringImpl*, ReturnHandleType, v8::Isolate*);
 
     HashMap<StringImpl*, v8::String*> m_stringCache;
     v8::Persistent<v8::String> m_lastV8String;
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to