Commit 8027278e authored by ap@webkit.org's avatar ap@webkit.org

Reviewed by Sam Weinig.

        Fix a dtoa thread safety issue.

        WebCore can call kjs_strtod without holding JS lock, but we didn't have thread safety
        compiled in for dtoa.

        This is a 0.5% regression on SunSpider, which Sam Weinig has volunteered to cover with
        his recent improvement.

        * kjs/dtoa.cpp:
        (Bigint::Balloc):
        (Bigint::Bfree):
        Changed to use fastMalloc/fastDelete - they are much faster than the dtoa custom version was
        in the presence of locking (but somewhat slower in single-threaded case).
        (Bigint::pow5mult): Got rid of the dreaded double-checked locking anti-pattern (had to
        restructure the code to avoid significant performance implications).
        (Bigint::lshift): Rewrote to avoid an allocation, if possible.

        (Bigint::rv_alloc):
        (Bigint::kjs_freedtoa):
        (Bigint::kjs_dtoa):
        Check for USE(MULTIPLE_THREADS), not dtoa legacy MULTIPLE_THREADS.

        * kjs/InitializeThreading.cpp: Added.
        (KJS::initializeThreading):
        * kjs/InitializeThreading.h: Added.
        Initialize threading at KJS level, if enabled.

        * kjs/dtoa.h: Expose dtoa mutex for KJS::initializeThreading.

        * kjs/testkjs.cpp: (kjsmain): Call initializeThreading.

        * JavaScriptCore.exp: Export KJS::initializeThreading.

        * GNUmakefile.am:
        * JavaScriptCore.exp:
        * JavaScriptCore.pri:
        * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
        * JavaScriptCoreSources.bkl:
        * JavaScriptCore.xcodeproj/project.pbxproj:
        Added InitializeThreading.{h,cpp}.

        * wtf/Threading.h: Removed a using directive for WTF::initializeThreading - it is only
        to be called from KJS::initializeThreading, and having it in the global namespace is useless.



git-svn-id: http://svn.webkit.org/repository/webkit/trunk@31404 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent e852058d
2008-03-28 Alexey Proskuryakov <ap@webkit.org>
Reviewed by Sam Weinig.
Fix a dtoa thread safety issue.
WebCore can call kjs_strtod without holding JS lock, but we didn't have thread safety
compiled in for dtoa.
This is a 0.5% regression on SunSpider, which Sam Weinig has volunteered to cover with
his recent improvement.
* kjs/dtoa.cpp:
(Bigint::Balloc):
(Bigint::Bfree):
Changed to use fastMalloc/fastDelete - they are much faster than the dtoa custom version was
in the presence of locking (but somewhat slower in single-threaded case).
(Bigint::pow5mult): Got rid of the dreaded double-checked locking anti-pattern (had to
restructure the code to avoid significant performance implications).
(Bigint::lshift): Rewrote to avoid an allocation, if possible.
(Bigint::rv_alloc):
(Bigint::kjs_freedtoa):
(Bigint::kjs_dtoa):
Check for USE(MULTIPLE_THREADS), not dtoa legacy MULTIPLE_THREADS.
* kjs/InitializeThreading.cpp: Added.
(KJS::initializeThreading):
* kjs/InitializeThreading.h: Added.
Initialize threading at KJS level, if enabled.
* kjs/dtoa.h: Expose dtoa mutex for KJS::initializeThreading.
* kjs/testkjs.cpp: (kjsmain): Call initializeThreading.
* JavaScriptCore.exp: Export KJS::initializeThreading.
* GNUmakefile.am:
* JavaScriptCore.exp:
* JavaScriptCore.pri:
* JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
* JavaScriptCoreSources.bkl:
* JavaScriptCore.xcodeproj/project.pbxproj:
Added InitializeThreading.{h,cpp}.
* wtf/Threading.h: Removed a using directive for WTF::initializeThreading - it is only
to be called from KJS::initializeThreading, and having it in the global namespace is useless.
2008-03-28 Brady Eidson <beidson@apple.com>
Reviewed by Darin
......
......@@ -39,6 +39,7 @@ javascriptcore_sources += \
JavaScriptCore/API/JSObjectRef.cpp \
JavaScriptCore/API/JSStringRef.cpp \
JavaScriptCore/API/JSValueRef.cpp \
JavaScriptCore/kjs/InitializeThreading.cpp \
JavaScriptCore/kjs/JSGlobalObject.cpp \
JavaScriptCore/kjs/JSVariableObject.cpp \
JavaScriptCore/pcre/pcre_compile.cpp \
......
_JSCheckScriptSyntax
_JSClassCreate
_JSClassRelease
_JSClassRetain
_JSContextGetGlobalObject
_JSEvaluateScript
_JSGarbageCollect
_JSGlobalContextCreate
_JSGlobalContextRelease
_JSGlobalContextRetain
_JSObjectCallAsConstructor
_JSObjectCallAsFunction
_JSObjectCopyPropertyNames
_JSObjectDeleteProperty
_JSObjectGetPrivate
_JSObjectGetProperty
_JSObjectGetPropertyAtIndex
_JSObjectGetPrototype
_JSObjectHasProperty
_JSObjectIsConstructor
_JSObjectIsFunction
_JSObjectMake
_JSObjectMakeConstructor
_JSObjectMakeFunction
_JSObjectMakeFunctionWithCallback
_JSObjectSetPrivate
_JSObjectSetProperty
_JSObjectSetPropertyAtIndex
_JSObjectSetPrototype
_JSPropertyNameAccumulatorAddName
_JSPropertyNameArrayGetCount
_JSPropertyNameArrayGetNameAtIndex
_JSPropertyNameArrayRelease
_JSPropertyNameArrayRetain
_JSStringCopyCFString
_JSStringCreateWithCFString
_JSStringCreateWithCharacters
_JSStringCreateWithUTF8CString
_JSStringGetCharactersPtr
_JSStringGetLength
_JSStringGetMaximumUTF8CStringSize
_JSStringGetUTF8CString
_JSStringIsEqual
_JSStringIsEqualToUTF8CString
_JSStringRelease
_JSStringRetain
_JSValueGetType
_JSValueIsBoolean
_JSValueIsEqual
_JSValueIsInstanceOfConstructor
_JSValueIsNull
_JSValueIsNumber
_JSValueIsObject
_JSValueIsObjectOfClass
_JSValueIsStrictEqual
_JSValueIsString
_JSValueIsUndefined
_JSValueMakeBoolean
_JSValueMakeNull
_JSValueMakeNumber
_JSValueMakeString
_JSValueMakeUndefined
_JSValueProtect
_JSValueToBoolean
_JSValueToNumber
_JSValueToObject
_JSValueToStringCopy
_JSValueUnprotect
_WTFLog
_WTFLogVerbose
_WTFReportArgumentAssertionFailure
_WTFReportAssertionFailure
_WTFReportAssertionFailureWithMessage
_WTFReportError
_WTFReportFatalError
__Z12jsRegExpFreeP8JSRegExp
__Z15jsRegExpCompilePKti24JSRegExpIgnoreCaseOption23JSRegExpMultilineOptionPjPPKc
__Z15jsRegExpExecutePK8JSRegExpPKtiiPii
......@@ -97,11 +22,11 @@ __ZN3KJS11PropertyMap5clearEv
__ZN3KJS11PropertyMap7restoreERKNS_15SavedPropertiesE
__ZN3KJS11PropertyMapD1Ev
__ZN3KJS12DateInstance4infoE
__ZN3KJS12PropertySlot15undefinedGetterEPNS_9ExecStateEPNS_8JSObjectERKNS_10IdentifierERKS0_
__ZN3KJS12jsNumberCellEd
__ZN3KJS12PropertySlot15undefinedGetterEPNS_9ExecStateEPNS_8JSObjectERKNS_10IdentifierERKS0_
__ZN3KJS13ArrayInstance4infoE
__ZN3KJS13StatementNode6setLocEii
__ZN3KJS13jsOwnedStringERKNS_7UStringE
__ZN3KJS13StatementNode6setLocEii
__ZN3KJS14JSGlobalObject10globalExecEv
__ZN3KJS14JSGlobalObject15restoreBuiltinsERKNS_13SavedBuiltinsE
__ZN3KJS14JSGlobalObject16stopTimeoutCheckEv
......@@ -115,8 +40,8 @@ __ZN3KJS14JSGlobalObject5resetEPNS_7JSValueE
__ZN3KJS14JSGlobalObjectD2Ev
__ZN3KJS14StringInstance14deletePropertyEPNS_9ExecStateERKNS_10IdentifierE
__ZN3KJS14StringInstance16getPropertyNamesEPNS_9ExecStateERNS_17PropertyNameArrayE
__ZN3KJS14StringInstance18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
__ZN3KJS14StringInstance18getOwnPropertySlotEPNS_9ExecStateEjRNS_12PropertySlotE
__ZN3KJS14StringInstance18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
__ZN3KJS14StringInstance3putEPNS_9ExecStateERKNS_10IdentifierEPNS_7JSValueE
__ZN3KJS14StringInstance4infoE
__ZN3KJS14StringInstanceC1EPNS_8JSObjectERKNS_7UStringE
......@@ -131,8 +56,9 @@ __ZN3KJS16JSVariableObject19restoreLocalStorageERKNS_15SavedPropertiesE
__ZN3KJS16ParserRefCounted3refEv
__ZN3KJS16ParserRefCounted5derefEv
__ZN3KJS17PropertyNameArray3addERKNS_10IdentifierE
__ZN3KJS17PrototypeFunctionC1EPNS_9ExecStateEPNS_17FunctionPrototypeEiRKNS_10IdentifierEPFPNS_7JSValueES2_PNS_8JSObjectERKNS_4ListEE
__ZN3KJS17PrototypeFunctionC1EPNS_9ExecStateEiRKNS_10IdentifierEPFPNS_7JSValueES2_PNS_8JSObjectERKNS_4ListEE
__ZN3KJS17PrototypeFunctionC1EPNS_9ExecStateEPNS_17FunctionPrototypeEiRKNS_10IdentifierEPFPNS_7JSValueES2_PNS_8JSObjectERKNS_4ListEE
__ZN3KJS19initializeThreadingEv
__ZN3KJS19InternalFunctionImp4infoE
__ZN3KJS19InternalFunctionImpC2EPNS_17FunctionPrototypeERKNS_10IdentifierE
__ZN3KJS23objectProtoFuncToStringEPNS_9ExecStateEPNS_8JSObjectERKNS_4ListE
......@@ -148,18 +74,18 @@ __ZN3KJS6JSLock6unlockEv
__ZN3KJS6JSLock9lockCountEv
__ZN3KJS6Parser5parseEiPKtjPiS3_PNS_7UStringE
__ZN3KJS6parserEv
__ZN3KJS7CStringD1Ev
__ZN3KJS7CStringaSERKS0_
__ZN3KJS7CStringD1Ev
__ZN3KJS7UString3Rep11computeHashEPKti
__ZN3KJS7UString3Rep4nullE
__ZN3KJS7UString3Rep7destroyEv
__ZN3KJS7UString4fromEj
__ZN3KJS7UString6appendEPKc
__ZN3KJS7UString6appendERKS0_
__ZN3KJS7UStringaSEPKc
__ZN3KJS7UStringC1EPKc
__ZN3KJS7UStringC1EPKti
__ZN3KJS7UStringC1ERKS0_S2_
__ZN3KJS7UStringaSEPKc
__ZN3KJS8Debugger12sourceUnusedEPNS_9ExecStateEi
__ZN3KJS8Debugger6attachEPNS_14JSGlobalObjectE
__ZN3KJS8Debugger6detachEPNS_14JSGlobalObjectE
......@@ -169,21 +95,21 @@ __ZN3KJS8DebuggerD2Ev
__ZN3KJS8JSObject11hasInstanceEPNS_9ExecStateEPNS_7JSValueE
__ZN3KJS8JSObject12removeDirectERKNS_10IdentifierE
__ZN3KJS8JSObject14callAsFunctionEPNS_9ExecStateEPS0_RKNS_4ListE
__ZN3KJS8JSObject14deletePropertyEPNS_9ExecStateERKNS_10IdentifierE
__ZN3KJS8JSObject14deletePropertyEPNS_9ExecStateEj
__ZN3KJS8JSObject14deletePropertyEPNS_9ExecStateERKNS_10IdentifierE
__ZN3KJS8JSObject16getPropertyNamesEPNS_9ExecStateERNS_17PropertyNameArrayE
__ZN3KJS8JSObject17putDirectFunctionEPNS_19InternalFunctionImpEi
__ZN3KJS8JSObject18getOwnPropertySlotEPNS_9ExecStateEjRNS_12PropertySlotE
__ZN3KJS8JSObject18getPrimitiveNumberEPNS_9ExecStateERdRPNS_7JSValueE
__ZN3KJS8JSObject22fillGetterPropertySlotERNS_12PropertySlotEPPNS_7JSValueE
__ZN3KJS8JSObject3putEPNS_9ExecStateERKNS_10IdentifierEPNS_7JSValueE
__ZN3KJS8JSObject3putEPNS_9ExecStateEjPNS_7JSValueE
__ZN3KJS8JSObject3putEPNS_9ExecStateERKNS_10IdentifierEPNS_7JSValueE
__ZN3KJS8JSObject4callEPNS_9ExecStateEPS0_RKNS_4ListE
__ZN3KJS8JSObject4markEv
__ZN3KJS8JSObject9constructEPNS_9ExecStateERKNS_4ListE
__ZN3KJS8JSObject9constructEPNS_9ExecStateERKNS_4ListERKNS_10IdentifierERKNS_7UStringEi
__ZN3KJS8JSObject9putDirectERKNS_10IdentifierEPNS_7JSValueEi
__ZN3KJS8JSObject9putDirectERKNS_10IdentifierEii
__ZN3KJS8JSObject9putDirectERKNS_10IdentifierEPNS_7JSValueEi
__ZN3KJS8jsStringEPKc
__ZN3KJS8jsStringERKNS_7UStringE
__ZN3KJS9Collector15recordExtraCostEm
......@@ -252,15 +178,15 @@ __ZNK3KJS7UString5asciiEv
__ZNK3KJS7UString6is8BitEv
__ZNK3KJS7UString8toUInt32EPb
__ZNK3KJS7UString8toUInt32EPbb
__ZNK3KJS8JSObject11hasPropertyEPNS_9ExecStateERKNS_10IdentifierE
__ZNK3KJS8JSObject11hasPropertyEPNS_9ExecStateEj
__ZNK3KJS8JSObject11hasPropertyEPNS_9ExecStateERKNS_10IdentifierE
__ZNK3KJS8JSObject12defaultValueEPNS_9ExecStateENS_6JSTypeE
__ZNK3KJS8JSObject14implementsCallEv
__ZNK3KJS8JSObject19implementsConstructEv
__ZNK3KJS8JSObject21getPropertyAttributesERKNS_10IdentifierERj
__ZNK3KJS8JSObject21implementsHasInstanceEv
__ZNK3KJS8JSObject3getEPNS_9ExecStateERKNS_10IdentifierE
__ZNK3KJS8JSObject3getEPNS_9ExecStateEj
__ZNK3KJS8JSObject3getEPNS_9ExecStateERKNS_10IdentifierE
__ZNK3KJS8JSObject4typeEv
__ZNK3KJS8JSObject8toNumberEPNS_9ExecStateE
__ZNK3KJS8JSObject8toObjectEPNS_9ExecStateE
......@@ -277,7 +203,82 @@ __ZTVN3KJS15JSWrapperObjectE
__ZTVN3KJS16JSVariableObjectE
__ZTVN3KJS19InternalFunctionImpE
__ZTVN3KJS8JSObjectE
_JSCheckScriptSyntax
_JSClassCreate
_JSClassRelease
_JSClassRetain
_JSContextGetGlobalObject
_jscore_collector_introspection
_jscore_fastmalloc_introspection
_kJSClassDefinitionEmpty
_JSEvaluateScript
_JSGarbageCollect
_JSGlobalContextCreate
_JSGlobalContextRelease
_JSGlobalContextRetain
_JSObjectCallAsConstructor
_JSObjectCallAsFunction
_JSObjectCopyPropertyNames
_JSObjectDeleteProperty
_JSObjectGetPrivate
_JSObjectGetProperty
_JSObjectGetPropertyAtIndex
_JSObjectGetPrototype
_JSObjectHasProperty
_JSObjectIsConstructor
_JSObjectIsFunction
_JSObjectMake
_JSObjectMakeConstructor
_JSObjectMakeFunction
_JSObjectMakeFunctionWithCallback
_JSObjectSetPrivate
_JSObjectSetProperty
_JSObjectSetPropertyAtIndex
_JSObjectSetPrototype
_JSPropertyNameAccumulatorAddName
_JSPropertyNameArrayGetCount
_JSPropertyNameArrayGetNameAtIndex
_JSPropertyNameArrayRelease
_JSPropertyNameArrayRetain
_JSStringCopyCFString
_JSStringCreateWithCFString
_JSStringCreateWithCharacters
_JSStringCreateWithUTF8CString
_JSStringGetCharactersPtr
_JSStringGetLength
_JSStringGetMaximumUTF8CStringSize
_JSStringGetUTF8CString
_JSStringIsEqual
_JSStringIsEqualToUTF8CString
_JSStringRelease
_JSStringRetain
_JSValueGetType
_JSValueIsBoolean
_JSValueIsEqual
_JSValueIsInstanceOfConstructor
_JSValueIsNull
_JSValueIsNumber
_JSValueIsObject
_JSValueIsObjectOfClass
_JSValueIsStrictEqual
_JSValueIsString
_JSValueIsUndefined
_JSValueMakeBoolean
_JSValueMakeNull
_JSValueMakeNumber
_JSValueMakeString
_JSValueMakeUndefined
_JSValueProtect
_JSValueToBoolean
_JSValueToNumber
_JSValueToObject
_JSValueToStringCopy
_JSValueUnprotect
_kjs_strtod
_kJSClassDefinitionEmpty
_WTFLog
_WTFLogVerbose
_WTFReportArgumentAssertionFailure
_WTFReportAssertionFailure
_WTFReportAssertionFailureWithMessage
_WTFReportError
_WTFReportFatalError
......@@ -47,6 +47,7 @@ SOURCES += \
API/JSObjectRef.cpp \
API/JSStringRef.cpp \
API/JSValueRef.cpp \
kjs/InitializeThreading.cpp \
kjs/JSGlobalObject.cpp \
kjs/JSVariableObject.cpp
......
......@@ -396,6 +396,14 @@
RelativePath="..\..\kjs\identifier.h"
>
</File>
<File
RelativePath="..\..\kjs\InitializeThreading.cpp"
>
</File>
<File
RelativePath="..\..\kjs\InitializeThreading.h"
>
</File>
<File
RelativePath="..\..\kjs\internal.cpp"
>
......
......@@ -189,6 +189,8 @@
BCF655590A2049710038A194 /* MathExtras.h in Headers */ = {isa = PBXBuildFile; fileRef = BCF6553B0A2048DE0038A194 /* MathExtras.h */; settings = {ATTRIBUTES = (Private, ); }; };
D212022B0AD4310D00ED79B6 /* DateMath.h in Headers */ = {isa = PBXBuildFile; fileRef = D21202290AD4310C00ED79B6 /* DateMath.h */; };
E11D51760B2E798D0056C188 /* StringExtras.h in Headers */ = {isa = PBXBuildFile; fileRef = E11D51750B2E798D0056C188 /* StringExtras.h */; settings = {ATTRIBUTES = (Private, ); }; };
E17863400D9BEC0000D74E75 /* InitializeThreading.h in Headers */ = {isa = PBXBuildFile; fileRef = E178633F0D9BEC0000D74E75 /* InitializeThreading.h */; settings = {ATTRIBUTES = (Private, ); }; };
E178636D0D9BEEC300D74E75 /* InitializeThreading.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E178636C0D9BEEC300D74E75 /* InitializeThreading.cpp */; };
E195679609E7CF1200B89D13 /* UnicodeIcu.h in Headers */ = {isa = PBXBuildFile; fileRef = E195678F09E7CF1200B89D13 /* UnicodeIcu.h */; settings = {ATTRIBUTES = (Private, ); }; };
E195679809E7CF1200B89D13 /* Unicode.h in Headers */ = {isa = PBXBuildFile; fileRef = E195679409E7CF1200B89D13 /* Unicode.h */; settings = {ATTRIBUTES = (Private, ); }; };
E1A862A90D7EBB76001EC6AA /* CollatorICU.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E1A862A80D7EBB76001EC6AA /* CollatorICU.cpp */; };
......@@ -489,6 +491,8 @@
D21202280AD4310C00ED79B6 /* DateMath.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = DateMath.cpp; sourceTree = "<group>"; };
D21202290AD4310C00ED79B6 /* DateMath.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = DateMath.h; sourceTree = "<group>"; };
E11D51750B2E798D0056C188 /* StringExtras.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StringExtras.h; sourceTree = "<group>"; };
E178633F0D9BEC0000D74E75 /* InitializeThreading.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InitializeThreading.h; sourceTree = "<group>"; };
E178636C0D9BEEC300D74E75 /* InitializeThreading.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InitializeThreading.cpp; sourceTree = "<group>"; };
E195678F09E7CF1200B89D13 /* UnicodeIcu.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UnicodeIcu.h; sourceTree = "<group>"; };
E195679409E7CF1200B89D13 /* Unicode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Unicode.h; sourceTree = "<group>"; };
E1A862A80D7EBB76001EC6AA /* CollatorICU.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CollatorICU.cpp; sourceTree = "<group>"; };
......@@ -835,6 +839,8 @@
933A3499038AE7C6008635CE /* grammar.y */,
933A349D038AE80F008635CE /* identifier.cpp */,
933A349A038AE7C6008635CE /* identifier.h */,
E178636C0D9BEEC300D74E75 /* InitializeThreading.cpp */,
E178633F0D9BEC0000D74E75 /* InitializeThreading.h */,
F692A8610255597D01FF60F7 /* internal.cpp */,
F692A8620255597D01FF60F7 /* internal.h */,
F692A8630255597D01FF60F7 /* interpreter.cpp */,
......@@ -1093,6 +1099,7 @@
14ABB36F099C076400E2A24F /* value.h in Headers */,
E1EE79280D6C964500FEA3BA /* Locker.h in Headers */,
E1A862AB0D7EBB7D001EC6AA /* Collator.h in Headers */,
E17863400D9BEC0000D74E75 /* InitializeThreading.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
......@@ -1345,6 +1352,7 @@
E1EE793D0D6C9B9200FEA3BA /* ThreadingPthreads.cpp in Sources */,
E1A862A90D7EBB76001EC6AA /* CollatorICU.cpp in Sources */,
E1A862D60D7F2B5C001EC6AA /* CollatorDefault.cpp in Sources */,
E178636D0D9BEEC300D74E75 /* InitializeThreading.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
......
......@@ -57,6 +57,7 @@ Source files for JSCore.
kjs/function.cpp
kjs/function_object.cpp
kjs/identifier.cpp
kjs/InitializeThreading.cpp
kjs/internal.cpp
kjs/interpreter.cpp
kjs/JSGlobalObject.cpp
......
/*
* Copyright (C) 2008 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
#include "InitializeThreading.h"
#include "dtoa.h"
#include <wtf/Threading.h>
namespace KJS {
void initializeThreading()
{
WTF::initializeThreading();
#if USE(MULTIPLE_THREADS)
s_dtoaP5Mutex = new Mutex;
#endif
}
}
/*
* Copyright (C) 2008 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef KJS_InitializeThreading_h
#define KJS_InitializeThreading_h
namespace KJS {
void initializeThreading();
}
#endif
......@@ -97,17 +97,6 @@
* #define Bad_float_h if your system lacks a float.h or if it does not
* define some or all of DBL_DIG, DBL_MAX_10_EXP, DBL_MAX_EXP,
* FLT_RADIX, FLT_ROUNDS, and DBL_MAX.
* #define Omit_Private_Memory to omit logic (added Jan. 1998) for making
* memory allocations from a private pool of memory when possible.
* When used, the private pool is PRIVATE_MEM bytes long: 2304 bytes,
* unless #defined to be a different length. This default length
* suffices to get rid of MALLOC calls except for unusual cases,
* such as decimal-to-binary conversion of a very long string of
* digits. The longest string dtoa can return is about 751 bytes
* long. For conversions by strtod of strings of 800 digits and
* all dtoa conversions in single-threaded executions with 8-byte
* pointers, PRIVATE_MEM >= 7400 appears to suffice; with 4-byte
* pointers, PRIVATE_MEM >= 7112 appears adequate.
* #define INFNAN_CHECK on IEEE systems to cause strtod to check for
* Infinity and NaN (case insensitively). On some systems (e.g.,
* some HP systems), it may be necessary to #define NAN_WORD0
......@@ -123,15 +112,6 @@
* white space ignored; but if this results in none of the 52
* fraction bits being on (an IEEE Infinity symbol), then NAN_WORD0
* and NAN_WORD1 are used instead.
* #define MULTIPLE_THREADS if the system offers preemptively scheduled
* multiple threads. In this case, you must provide (or suitably
* #define) two locks, acquired by ACQUIRE_DTOA_LOCK(n) and freed
* by FREE_DTOA_LOCK(n) for n = 0 or 1. (The second lock, accessed
* in pow5mult, ensures lazy evaluation of only one copy of high
* powers of 5; omitting this lock would introduce a small
* probability of wasting memory, but would otherwise be harmless.)
* You must also invoke freedtoa(s) to free the value s returned by
* dtoa. You may do so whether or not MULTIPLE_THREADS is #defined.
* #define NO_IEEE_Scale to disable new (Feb. 1997) logic in strtod that
* avoids underflows on inputs whose result does not underflow.
* If you #define NO_IEEE_Scale on a machine that uses IEEE-format
......@@ -186,15 +166,7 @@
#include <string.h>
#include <wtf/Assertions.h>
#include <wtf/FastMalloc.h>
#ifndef Omit_Private_Memory
#ifndef PRIVATE_MEM
#define PRIVATE_MEM 2304
#endif
#define PRIVATE_mem ((PRIVATE_MEM + sizeof(double) - 1) / sizeof(double))
static double private_mem[PRIVATE_mem];
static double* pmem_next = private_mem;
#endif
#include <wtf/Threading.h>
#undef IEEE_Arith
#undef Avoid_Underflow
......@@ -247,6 +219,12 @@ static double* pmem_next = private_mem;
#include <math.h>
#endif
using namespace KJS;
#if USE(MULTIPLE_THREADS)
Mutex* KJS::s_dtoaP5Mutex;
#endif
#ifdef __cplusplus
extern "C" {
#endif
......@@ -429,11 +407,6 @@ extern double rnd_prod(double, double), rnd_quot(double, double);
#endif
#endif
#ifndef MULTIPLE_THREADS
#define ACQUIRE_DTOA_LOCK(n) /*nothing*/
#define FREE_DTOA_LOCK(n) /*nothing*/
#endif
#define Kmax 15
struct Bigint {
......@@ -442,43 +415,21 @@ struct Bigint {
uint32_t x[1];
};
static Bigint* freelist[Kmax + 1];
static Bigint* Balloc(int k)
{
Bigint* rv;
ACQUIRE_DTOA_LOCK(0);
if ((rv = freelist[k])) {
freelist[k] = rv->next;
} else {
int x = 1 << k;
#ifdef Omit_Private_Memory
rv = (Bigint*)fastMalloc(sizeof(Bigint) + (x - 1)*sizeof(uint32_t));
#else
unsigned int len = (sizeof(Bigint) + (x - 1) * sizeof(uint32_t) + sizeof(double) - 1) / sizeof(double);
if (pmem_next - private_mem + len <= (unsigned)PRIVATE_mem) {
rv = (Bigint*)pmem_next;
pmem_next += len;
} else
rv = (Bigint*)fastMalloc(len * sizeof(double));
#endif
rv->k = k;
rv->maxwds = x;
}
FREE_DTOA_LOCK(0);
int x = 1 << k;
Bigint* rv = (Bigint*)fastMalloc(sizeof(Bigint) + (x - 1)*sizeof(uint32_t));
rv->k = k;
rv->maxwds = x;
rv->next = 0;
rv->sign = rv->wds = 0;
return rv;
}
static void Bfree(Bigint* v)
{
if (v) {
ACQUIRE_DTOA_LOCK(0);
v->next = freelist[v->k];
freelist[v->k] = v;
FREE_DTOA_LOCK(0);
}
fastFree(v);
}
#define Bcopy(x, y) memcpy((char*)&x->sign, (char*)&y->sign, y->wds * sizeof(int32_t) + 2 * sizeof(int))
......@@ -737,108 +688,121 @@ static Bigint* mult(Bigint* a, Bigint* b)
}
static Bigint* p5s;
static int p5s_count;
static Bigint* pow5mult(Bigint* b, int k)
{
Bigint *b1, *p5, *p51;
int i;
static int p05[3] = { 5, 25, 125 };
if ((i = k & 3))
if (int i = k & 3)
b = multadd(b, p05[i - 1], 0);
if (!(k >>= 2))
return b;
if (!(p5 = p5s)) {
#if USE(MULTIPLE_THREADS)
s_dtoaP5Mutex->lock();
#endif
Bigint* p5 = p5s;
if (!p5) {
/* first time */
#ifdef MULTIPLE_THREADS
ACQUIRE_DTOA_LOCK(1);
if (!(p5 = p5s)) {
p5 = p5s = i2b(625);
p5->next = 0;
}
FREE_DTOA_LOCK(1);
#else
p5 = p5s = i2b(625);
p5->next = 0;
#endif
p5s_count = 1;
}
int p5s_count_local = p5s_count;
#if USE(MULTIPLE_THREADS)
s_dtoaP5Mutex->unlock();
#endif