From 9dc87323d695f17c94ca98f72d5946e7f7d2ac0b Mon Sep 17 00:00:00 2001 From: "haraken@chromium.org" Date: Thu, 28 Jun 2012 08:51:58 +0000 Subject: [PATCH] [V8] Optimize Integer::New() by caching persistent handles for small integers https://bugs.webkit.org/show_bug.cgi?id=90043 Reviewed by Adam Barth. The patch improves performance of Dromaeo/dom-query.html by 3.6%, and Bindings/scroll-top.html by 17.3%. The performance results in my Chromium/Linux: [Dromaeo/dom-query.html] 796310.4 runs/s => 824745.4 runs/s (+3.6%) [Bindings/scroll-top.html] 204.68 runs/s => 240.15 runs/s (+17.3%) This patch introduces V8BindingPerIsolateData::IntegerCache (just like V8BindingPerIsolateData::StringCache) to cache persistent handles for small integers. No new tests. No change in behavior. * bindings/v8/V8Binding.h: Implemented v8Integer() and v8UnsignedInteger(), which returns cached persistent handles for integers smaller than 64. (WebCore): (IntegerCache): (WebCore::IntegerCache::IntegerCache): (WebCore::IntegerCache::v8Integer): (WebCore::IntegerCache::v8UnsignedInteger): (WebCore::V8BindingPerIsolateData::integerCache): (V8BindingPerIsolateData): (WebCore::v8Integer): (WebCore::v8UnsignedInteger): * bindings/v8/V8Binding.cpp: (WebCore): (WebCore::IntegerCache::createSmallIntegers): * bindings/v8/WorkerScriptController.cpp: (~WorkerScriptController): ~V8BindingPerIsolateData() should be called before isolate->Exit(), since ~V8BindingPerIsolateData() calls V8 APIs that requires the current isolate. * bindings/scripts/CodeGeneratorV8.pm: Replaced Integer::New() and Integer::NewFromUnsigned() with v8Integer() and v8UnsignedInteger(). (GenerateNormalAttrGetter): (NativeToJSValue): * bindings/scripts/test/V8/V8TestActiveDOMObject.cpp: Updated run-bindings-tests results. (WebCore::TestActiveDOMObjectV8Internal::excitingAttrAttrGetter): * bindings/scripts/test/V8/V8TestObj.cpp: Ditto. (WebCore::TestObjV8Internal::readOnlyIntAttrAttrGetter): (WebCore::TestObjV8Internal::shortAttrAttrGetter): (WebCore::TestObjV8Internal::unsignedShortAttrAttrGetter): (WebCore::TestObjV8Internal::intAttrAttrGetter): (WebCore::TestObjV8Internal::reflectedIntegralAttrAttrGetter): (WebCore::TestObjV8Internal::reflectedUnsignedIntegralAttrAttrGetter): (WebCore::TestObjV8Internal::reflectedCustomIntegralAttrAttrGetter): (WebCore::TestObjV8Internal::attrWithGetterExceptionAttrGetter): (WebCore::TestObjV8Internal::attrWithSetterExceptionAttrGetter): (WebCore::TestObjV8Internal::withScriptStateAttributeAttrGetter): (WebCore::TestObjV8Internal::conditionalAttr1AttrGetter): (WebCore::TestObjV8Internal::conditionalAttr2AttrGetter): (WebCore::TestObjV8Internal::conditionalAttr3AttrGetter): (WebCore::TestObjV8Internal::enabledAtRuntimeAttr1AttrGetter): (WebCore::TestObjV8Internal::enabledAtRuntimeAttr2AttrGetter): (WebCore::TestObjV8Internal::enabledAtContextAttr1AttrGetter): (WebCore::TestObjV8Internal::enabledAtContextAttr2AttrGetter): (WebCore::TestObjV8Internal::strawberryAttrGetter): (WebCore::TestObjV8Internal::descriptionAttrGetter): (WebCore::TestObjV8Internal::idAttrGetter): (WebCore::TestObjV8Internal::intMethodCallback): (WebCore::TestObjV8Internal::intMethodWithArgsCallback): (WebCore::TestObjV8Internal::classMethodWithOptionalCallback): * bindings/scripts/test/V8/V8TestSerializedScriptValueInterface.cpp: Ditto. (WebCore::TestSerializedScriptValueInterfaceV8Internal::portsAttrGetter): git-svn-id: http://svn.webkit.org/repository/webkit/trunk@121421 268f45cc-cd09-0410-ab3c-d52691b4dbfc --- Source/WebCore/ChangeLog | 77 ++++++++++++++++++++++ Source/WebCore/bindings/scripts/CodeGeneratorV8.pm | 10 +-- .../scripts/test/V8/V8TestActiveDOMObject.cpp | 2 +- .../WebCore/bindings/scripts/test/V8/V8TestObj.cpp | 48 +++++++------- .../V8/V8TestSerializedScriptValueInterface.cpp | 2 +- Source/WebCore/bindings/v8/V8Binding.cpp | 22 ++++++- Source/WebCore/bindings/v8/V8Binding.h | 47 +++++++++++++ .../WebCore/bindings/v8/WorkerScriptController.cpp | 2 +- 8 files changed, 177 insertions(+), 33 deletions(-) diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog index c74a474..7b39d85 100644 --- a/Source/WebCore/ChangeLog +++ b/Source/WebCore/ChangeLog @@ -1,3 +1,80 @@ +2012-06-28 Kentaro Hara + + [V8] Optimize Integer::New() by caching persistent handles for small integers + https://bugs.webkit.org/show_bug.cgi?id=90043 + + Reviewed by Adam Barth. + + The patch improves performance of Dromaeo/dom-query.html by 3.6%, + and Bindings/scroll-top.html by 17.3%. + + The performance results in my Chromium/Linux: + + [Dromaeo/dom-query.html] + 796310.4 runs/s => 824745.4 runs/s (+3.6%) + + [Bindings/scroll-top.html] + 204.68 runs/s => 240.15 runs/s (+17.3%) + + This patch introduces V8BindingPerIsolateData::IntegerCache (just like + V8BindingPerIsolateData::StringCache) to cache persistent handles + for small integers. + + No new tests. No change in behavior. + + * bindings/v8/V8Binding.h: Implemented v8Integer() and v8UnsignedInteger(), + which returns cached persistent handles for integers smaller than 64. + (WebCore): + (IntegerCache): + (WebCore::IntegerCache::IntegerCache): + (WebCore::IntegerCache::v8Integer): + (WebCore::IntegerCache::v8UnsignedInteger): + (WebCore::V8BindingPerIsolateData::integerCache): + (V8BindingPerIsolateData): + (WebCore::v8Integer): + (WebCore::v8UnsignedInteger): + * bindings/v8/V8Binding.cpp: + (WebCore): + (WebCore::IntegerCache::createSmallIntegers): + * bindings/v8/WorkerScriptController.cpp: + (~WorkerScriptController): ~V8BindingPerIsolateData() should be called before + isolate->Exit(), since ~V8BindingPerIsolateData() calls V8 APIs that requires + the current isolate. + + * bindings/scripts/CodeGeneratorV8.pm: Replaced Integer::New() and Integer::NewFromUnsigned() + with v8Integer() and v8UnsignedInteger(). + (GenerateNormalAttrGetter): + (NativeToJSValue): + + * bindings/scripts/test/V8/V8TestActiveDOMObject.cpp: Updated run-bindings-tests results. + (WebCore::TestActiveDOMObjectV8Internal::excitingAttrAttrGetter): + * bindings/scripts/test/V8/V8TestObj.cpp: Ditto. + (WebCore::TestObjV8Internal::readOnlyIntAttrAttrGetter): + (WebCore::TestObjV8Internal::shortAttrAttrGetter): + (WebCore::TestObjV8Internal::unsignedShortAttrAttrGetter): + (WebCore::TestObjV8Internal::intAttrAttrGetter): + (WebCore::TestObjV8Internal::reflectedIntegralAttrAttrGetter): + (WebCore::TestObjV8Internal::reflectedUnsignedIntegralAttrAttrGetter): + (WebCore::TestObjV8Internal::reflectedCustomIntegralAttrAttrGetter): + (WebCore::TestObjV8Internal::attrWithGetterExceptionAttrGetter): + (WebCore::TestObjV8Internal::attrWithSetterExceptionAttrGetter): + (WebCore::TestObjV8Internal::withScriptStateAttributeAttrGetter): + (WebCore::TestObjV8Internal::conditionalAttr1AttrGetter): + (WebCore::TestObjV8Internal::conditionalAttr2AttrGetter): + (WebCore::TestObjV8Internal::conditionalAttr3AttrGetter): + (WebCore::TestObjV8Internal::enabledAtRuntimeAttr1AttrGetter): + (WebCore::TestObjV8Internal::enabledAtRuntimeAttr2AttrGetter): + (WebCore::TestObjV8Internal::enabledAtContextAttr1AttrGetter): + (WebCore::TestObjV8Internal::enabledAtContextAttr2AttrGetter): + (WebCore::TestObjV8Internal::strawberryAttrGetter): + (WebCore::TestObjV8Internal::descriptionAttrGetter): + (WebCore::TestObjV8Internal::idAttrGetter): + (WebCore::TestObjV8Internal::intMethodCallback): + (WebCore::TestObjV8Internal::intMethodWithArgsCallback): + (WebCore::TestObjV8Internal::classMethodWithOptionalCallback): + * bindings/scripts/test/V8/V8TestSerializedScriptValueInterface.cpp: Ditto. + (WebCore::TestSerializedScriptValueInterfaceV8Internal::portsAttrGetter): + 2012-06-28 Kent Tamura Classify form control states by their owner forms diff --git a/Source/WebCore/bindings/scripts/CodeGeneratorV8.pm b/Source/WebCore/bindings/scripts/CodeGeneratorV8.pm index 254ec93..b36da40 100644 --- a/Source/WebCore/bindings/scripts/CodeGeneratorV8.pm +++ b/Source/WebCore/bindings/scripts/CodeGeneratorV8.pm @@ -1060,7 +1060,7 @@ END MessagePortArray portsCopy(*ports); v8::Local portArray = v8::Array::New(portsCopy.size()); for (size_t i = 0; i < portsCopy.size(); ++i) - portArray->Set(v8::Integer::New(i), toV8(portsCopy[i].get(), info.GetIsolate())); + portArray->Set(v8Integer(i, info.GetIsolate()), toV8(portsCopy[i].get(), info.GetIsolate())); return portArray; END } else { @@ -3892,14 +3892,14 @@ sub NativeToJSValue # should be returned instead. if ($signature->extendedAttributes->{"Reflect"} and ($type eq "unsigned long" or $type eq "unsigned short")) { $value =~ s/getUnsignedIntegralAttribute/getIntegralAttribute/g; - return "v8::Integer::NewFromUnsigned(std::max(0, " . $value . "))"; + return "v8UnsignedInteger(std::max(0, " . $value . ")$getIsolateArg)"; } # For all the types where we use 'int' as the representation type, - # we use Integer::New which has a fast Smi conversion check. + # we use v8Integer() which has a fast small integer conversion check. my $nativeType = GetNativeType($type); - return "v8::Integer::New($value)" if $nativeType eq "int"; - return "v8::Integer::NewFromUnsigned($value)" if $nativeType eq "unsigned"; + return "v8Integer($value$getIsolateArg)" if $nativeType eq "int"; + return "v8UnsignedInteger($value$getIsolateArg)" if $nativeType eq "unsigned"; return "v8DateOrNull($value$getIsolateArg)" if $type eq "Date"; # long long and unsigned long long are not representable in ECMAScript. diff --git a/Source/WebCore/bindings/scripts/test/V8/V8TestActiveDOMObject.cpp b/Source/WebCore/bindings/scripts/test/V8/V8TestActiveDOMObject.cpp index 37817d5..0a9b88a 100644 --- a/Source/WebCore/bindings/scripts/test/V8/V8TestActiveDOMObject.cpp +++ b/Source/WebCore/bindings/scripts/test/V8/V8TestActiveDOMObject.cpp @@ -45,7 +45,7 @@ static v8::Handle excitingAttrAttrGetter(v8::Local name, { INC_STATS("DOM.TestActiveDOMObject.excitingAttr._get"); TestActiveDOMObject* imp = V8TestActiveDOMObject::toNative(info.Holder()); - return v8::Integer::New(imp->excitingAttr()); + return v8Integer(imp->excitingAttr(), info.GetIsolate()); } static v8::Handle excitingFunctionCallback(const v8::Arguments& args) diff --git a/Source/WebCore/bindings/scripts/test/V8/V8TestObj.cpp b/Source/WebCore/bindings/scripts/test/V8/V8TestObj.cpp index 40b8d9d..372eadf 100644 --- a/Source/WebCore/bindings/scripts/test/V8/V8TestObj.cpp +++ b/Source/WebCore/bindings/scripts/test/V8/V8TestObj.cpp @@ -86,7 +86,7 @@ static v8::Handle readOnlyIntAttrAttrGetter(v8::Local nam { INC_STATS("DOM.TestObj.readOnlyIntAttr._get"); TestObj* imp = V8TestObj::toNative(info.Holder()); - return v8::Integer::New(imp->readOnlyIntAttr()); + return v8Integer(imp->readOnlyIntAttr(), info.GetIsolate()); } static v8::Handle readOnlyStringAttrAttrGetter(v8::Local name, const v8::AccessorInfo& info) @@ -114,7 +114,7 @@ static v8::Handle shortAttrAttrGetter(v8::Local name, con { INC_STATS("DOM.TestObj.shortAttr._get"); TestObj* imp = V8TestObj::toNative(info.Holder()); - return v8::Integer::New(imp->shortAttr()); + return v8Integer(imp->shortAttr(), info.GetIsolate()); } static void shortAttrAttrSetter(v8::Local name, v8::Local value, const v8::AccessorInfo& info) @@ -130,7 +130,7 @@ static v8::Handle unsignedShortAttrAttrGetter(v8::Local n { INC_STATS("DOM.TestObj.unsignedShortAttr._get"); TestObj* imp = V8TestObj::toNative(info.Holder()); - return v8::Integer::New(imp->unsignedShortAttr()); + return v8Integer(imp->unsignedShortAttr(), info.GetIsolate()); } static void unsignedShortAttrAttrSetter(v8::Local name, v8::Local value, const v8::AccessorInfo& info) @@ -146,7 +146,7 @@ static v8::Handle intAttrAttrGetter(v8::Local name, const { INC_STATS("DOM.TestObj.intAttr._get"); TestObj* imp = V8TestObj::toNative(info.Holder()); - return v8::Integer::New(imp->intAttr()); + return v8Integer(imp->intAttr(), info.GetIsolate()); } static void intAttrAttrSetter(v8::Local name, v8::Local value, const v8::AccessorInfo& info) @@ -274,7 +274,7 @@ static v8::Handle reflectedIntegralAttrAttrGetter(v8::LocalgetIntegralAttribute(WebCore::HTMLNames::reflectedintegralattrAttr)); + return v8Integer(imp->getIntegralAttribute(WebCore::HTMLNames::reflectedintegralattrAttr), info.GetIsolate()); } static void reflectedIntegralAttrAttrSetter(v8::Local name, v8::Local value, const v8::AccessorInfo& info) @@ -290,7 +290,7 @@ static v8::Handle reflectedUnsignedIntegralAttrAttrGetter(v8::LocalgetIntegralAttribute(WebCore::HTMLNames::reflectedunsignedintegralattrAttr))); + return v8UnsignedInteger(std::max(0, imp->getIntegralAttribute(WebCore::HTMLNames::reflectedunsignedintegralattrAttr)), info.GetIsolate()); } static void reflectedUnsignedIntegralAttrAttrSetter(v8::Local name, v8::Local value, const v8::AccessorInfo& info) @@ -354,7 +354,7 @@ static v8::Handle reflectedCustomIntegralAttrAttrGetter(v8::LocalgetIntegralAttribute(WebCore::HTMLNames::customContentIntegralAttrAttr)); + return v8Integer(imp->getIntegralAttribute(WebCore::HTMLNames::customContentIntegralAttrAttr), info.GetIsolate()); } static void reflectedCustomIntegralAttrAttrSetter(v8::Local name, v8::Local value, const v8::AccessorInfo& info) @@ -406,7 +406,7 @@ static v8::Handle attrWithGetterExceptionAttrGetter(v8::LocalattrWithGetterException(ec); if (UNLIKELY(ec)) return V8Proxy::setDOMException(ec, info.GetIsolate()); - return v8::Integer::New(v); + return v8Integer(v, info.GetIsolate()); } static void attrWithGetterExceptionAttrSetter(v8::Local name, v8::Local value, const v8::AccessorInfo& info) @@ -425,7 +425,7 @@ static v8::Handle attrWithSetterExceptionAttrGetter(v8::LocalattrWithSetterException()); + return v8Integer(imp->attrWithSetterException(), info.GetIsolate()); } static void attrWithSetterExceptionAttrSetter(v8::Local name, v8::Local value, const v8::AccessorInfo& info) @@ -489,7 +489,7 @@ static v8::Handle withScriptStateAttributeAttrGetter(v8::LocalwithScriptStateAttribute(state)); + return v8Integer(imp->withScriptStateAttribute(state), info.GetIsolate()); } static void withScriptStateAttributeAttrSetter(v8::Local name, v8::Local value, const v8::AccessorInfo& info) @@ -717,7 +717,7 @@ static v8::Handle conditionalAttr1AttrGetter(v8::Local na { INC_STATS("DOM.TestObj.conditionalAttr1._get"); TestObj* imp = V8TestObj::toNative(info.Holder()); - return v8::Integer::New(imp->conditionalAttr1()); + return v8Integer(imp->conditionalAttr1(), info.GetIsolate()); } #endif // ENABLE(Condition1) @@ -741,7 +741,7 @@ static v8::Handle conditionalAttr2AttrGetter(v8::Local na { INC_STATS("DOM.TestObj.conditionalAttr2._get"); TestObj* imp = V8TestObj::toNative(info.Holder()); - return v8::Integer::New(imp->conditionalAttr2()); + return v8Integer(imp->conditionalAttr2(), info.GetIsolate()); } #endif // ENABLE(Condition1) && ENABLE(Condition2) @@ -765,7 +765,7 @@ static v8::Handle conditionalAttr3AttrGetter(v8::Local na { INC_STATS("DOM.TestObj.conditionalAttr3._get"); TestObj* imp = V8TestObj::toNative(info.Holder()); - return v8::Integer::New(imp->conditionalAttr3()); + return v8Integer(imp->conditionalAttr3(), info.GetIsolate()); } #endif // ENABLE(Condition1) || ENABLE(Condition2) @@ -815,7 +815,7 @@ static v8::Handle enabledAtRuntimeAttr1AttrGetter(v8::LocalenabledAtRuntimeAttr1()); + return v8Integer(imp->enabledAtRuntimeAttr1(), info.GetIsolate()); } static void enabledAtRuntimeAttr1AttrSetter(v8::Local name, v8::Local value, const v8::AccessorInfo& info) @@ -831,7 +831,7 @@ static v8::Handle enabledAtRuntimeAttr2AttrGetter(v8::LocalenabledAtRuntimeAttr2()); + return v8Integer(imp->enabledAtRuntimeAttr2(), info.GetIsolate()); } static void enabledAtRuntimeAttr2AttrSetter(v8::Local name, v8::Local value, const v8::AccessorInfo& info) @@ -847,7 +847,7 @@ static v8::Handle enabledAtContextAttr1AttrGetter(v8::LocalenabledAtContextAttr1()); + return v8Integer(imp->enabledAtContextAttr1(), info.GetIsolate()); } static void enabledAtContextAttr1AttrSetter(v8::Local name, v8::Local value, const v8::AccessorInfo& info) @@ -863,7 +863,7 @@ static v8::Handle enabledAtContextAttr2AttrGetter(v8::LocalenabledAtContextAttr2()); + return v8Integer(imp->enabledAtContextAttr2(), info.GetIsolate()); } static void enabledAtContextAttr2AttrSetter(v8::Local name, v8::Local value, const v8::AccessorInfo& info) @@ -953,7 +953,7 @@ static v8::Handle strawberryAttrGetter(v8::Local name, co { INC_STATS("DOM.TestObj.strawberry._get"); TestObj* imp = V8TestObj::toNative(info.Holder()); - return v8::Integer::New(imp->blueberry()); + return v8Integer(imp->blueberry(), info.GetIsolate()); } static void strawberryAttrSetter(v8::Local name, v8::Local value, const v8::AccessorInfo& info) @@ -985,14 +985,14 @@ static v8::Handle descriptionAttrGetter(v8::Local name, c { INC_STATS("DOM.TestObj.description._get"); TestObj* imp = V8TestObj::toNative(info.Holder()); - return v8::Integer::New(imp->description()); + return v8Integer(imp->description(), info.GetIsolate()); } static v8::Handle idAttrGetter(v8::Local name, const v8::AccessorInfo& info) { INC_STATS("DOM.TestObj.id._get"); TestObj* imp = V8TestObj::toNative(info.Holder()); - return v8::Integer::New(imp->id()); + return v8Integer(imp->id(), info.GetIsolate()); } static void idAttrSetter(v8::Local name, v8::Local value, const v8::AccessorInfo& info) @@ -1044,7 +1044,7 @@ static v8::Handle intMethodCallback(const v8::Arguments& args) { INC_STATS("DOM.TestObj.intMethod"); TestObj* imp = V8TestObj::toNative(args.Holder()); - return v8::Integer::New(imp->intMethod()); + return v8Integer(imp->intMethod(), args.GetIsolate()); } static v8::Handle intMethodWithArgsCallback(const v8::Arguments& args) @@ -1056,7 +1056,7 @@ static v8::Handle intMethodWithArgsCallback(const v8::Arguments& args EXCEPTION_BLOCK(int, intArg, toInt32(MAYBE_MISSING_PARAMETER(args, 0, DefaultIsUndefined))); STRING_TO_V8PARAMETER_EXCEPTION_BLOCK(V8Parameter<>, strArg, MAYBE_MISSING_PARAMETER(args, 1, DefaultIsUndefined)); EXCEPTION_BLOCK(TestObj*, objArg, V8TestObj::HasInstance(MAYBE_MISSING_PARAMETER(args, 2, DefaultIsUndefined)) ? V8TestObj::toNative(v8::Handle::Cast(MAYBE_MISSING_PARAMETER(args, 2, DefaultIsUndefined))) : 0); - return v8::Integer::New(imp->intMethodWithArgs(intArg, strArg, objArg)); + return v8Integer(imp->intMethodWithArgs(intArg, strArg, objArg), args.GetIsolate()); } static v8::Handle objMethodCallback(const v8::Arguments& args) @@ -1603,10 +1603,10 @@ static v8::Handle classMethodWithOptionalCallback(const v8::Arguments { INC_STATS("DOM.TestObj.classMethodWithOptional"); if (args.Length() <= 0) { - return v8::Integer::New(TestObj::classMethodWithOptional()); + return v8Integer(TestObj::classMethodWithOptional(), args.GetIsolate()); } EXCEPTION_BLOCK(int, arg, toInt32(MAYBE_MISSING_PARAMETER(args, 0, DefaultIsUndefined))); - return v8::Integer::New(TestObj::classMethodWithOptional(arg)); + return v8Integer(TestObj::classMethodWithOptional(arg), args.GetIsolate()); } #if ENABLE(Condition1) diff --git a/Source/WebCore/bindings/scripts/test/V8/V8TestSerializedScriptValueInterface.cpp b/Source/WebCore/bindings/scripts/test/V8/V8TestSerializedScriptValueInterface.cpp index 28ecd94..3b0f2f6 100644 --- a/Source/WebCore/bindings/scripts/test/V8/V8TestSerializedScriptValueInterface.cpp +++ b/Source/WebCore/bindings/scripts/test/V8/V8TestSerializedScriptValueInterface.cpp @@ -103,7 +103,7 @@ static v8::Handle portsAttrGetter(v8::Local name, const v MessagePortArray portsCopy(*ports); v8::Local portArray = v8::Array::New(portsCopy.size()); for (size_t i = 0; i < portsCopy.size(); ++i) - portArray->Set(v8::Integer::New(i), toV8(portsCopy[i].get(), info.GetIsolate())); + portArray->Set(v8Integer(i, info.GetIsolate()), toV8(portsCopy[i].get(), info.GetIsolate())); return portArray; } diff --git a/Source/WebCore/bindings/v8/V8Binding.cpp b/Source/WebCore/bindings/v8/V8Binding.cpp index 6990186..d8836c7 100644 --- a/Source/WebCore/bindings/v8/V8Binding.cpp +++ b/Source/WebCore/bindings/v8/V8Binding.cpp @@ -490,7 +490,27 @@ v8::Local StringCache::v8ExternalStringSlow(StringImpl* stringImpl, return newString; } - + +void IntegerCache::createSmallIntegers() +{ + ASSERT(!m_initialized); + // We initialize m_smallIntegers not in a constructor but in v8Integer(), + // because Integer::New() requires a HandleScope. At the point where + // IntegerCache is constructed, a HandleScope might not exist. + for (int value = 0; value < numberOfCachedSmallIntegers; value++) + m_smallIntegers[value] = v8::Persistent::New(v8::Integer::New(value)); + m_initialized = true; +} + +IntegerCache::~IntegerCache() +{ + if (m_initialized) { + for (int value = 0; value < numberOfCachedSmallIntegers; value++) + m_smallIntegers[value].Dispose(); + m_initialized = false; + } +} + v8::Persistent createRawTemplate() { v8::HandleScope scope; diff --git a/Source/WebCore/bindings/v8/V8Binding.h b/Source/WebCore/bindings/v8/V8Binding.h index 9e9c5bb..5d0dbe2 100644 --- a/Source/WebCore/bindings/v8/V8Binding.h +++ b/Source/WebCore/bindings/v8/V8Binding.h @@ -89,6 +89,38 @@ namespace WebCore { RefPtr m_lastStringImpl; }; + const int numberOfCachedSmallIntegers = 64; + + class IntegerCache { + public: + IntegerCache() : m_initialized(false) { }; + ~IntegerCache(); + + v8::Handle v8Integer(int value) + { + if (!m_initialized) + createSmallIntegers(); + if (0 <= value && value < numberOfCachedSmallIntegers) + return m_smallIntegers[value]; + return v8::Integer::New(value); + } + + v8::Handle v8UnsignedInteger(unsigned value) + { + if (!m_initialized) + createSmallIntegers(); + if (value < static_cast(numberOfCachedSmallIntegers)) + return m_smallIntegers[value]; + return v8::Integer::NewFromUnsigned(value); + } + + private: + void createSmallIntegers(); + + v8::Persistent m_smallIntegers[numberOfCachedSmallIntegers]; + bool m_initialized; + }; + class ScriptGCEventListener; class GCEventData { @@ -142,6 +174,8 @@ namespace WebCore { } StringCache* stringCache() { return &m_stringCache; } + IntegerCache* integerCache() { return &m_integerCache; } + #if ENABLE(INSPECTOR) void visitExternalStrings(ExternalStringVisitor*); #endif @@ -190,6 +224,7 @@ namespace WebCore { v8::Persistent m_toStringTemplate; v8::Persistent m_lazyEventListenerToStringTemplate; StringCache m_stringCache; + IntegerCache m_integerCache; DOMDataList m_domDataList; DOMDataStore* m_domDataStore; @@ -290,6 +325,18 @@ namespace WebCore { return v8ExternalString(string, isolate); } + inline v8::Handle v8Integer(int value, v8::Isolate* isolate = 0) + { + V8BindingPerIsolateData* data = V8BindingPerIsolateData::current(isolate); + return data->integerCache()->v8Integer(value); + } + + inline v8::Handle v8UnsignedInteger(unsigned value, v8::Isolate* isolate = 0) + { + V8BindingPerIsolateData* data = V8BindingPerIsolateData::current(isolate); + return data->integerCache()->v8UnsignedInteger(value); + } + template v8::Handle v8Array(const Vector& iterator, v8::Isolate* isolate) { diff --git a/Source/WebCore/bindings/v8/WorkerScriptController.cpp b/Source/WebCore/bindings/v8/WorkerScriptController.cpp index cf19e0e..79c8810 100644 --- a/Source/WebCore/bindings/v8/WorkerScriptController.cpp +++ b/Source/WebCore/bindings/v8/WorkerScriptController.cpp @@ -77,8 +77,8 @@ WorkerScriptController::~WorkerScriptController() WebKit::Platform::current()->didStopWorkerRunLoop(WebKit::WebWorkerRunLoop(&m_workerContext->thread()->runLoop())); #endif m_proxy.clear(); - m_isolate->Exit(); V8BindingPerIsolateData::dispose(m_isolate); + m_isolate->Exit(); m_isolate->Dispose(); } -- 2.7.4