2009-01-09 David Levin <levin@chromium.org>
authoroliver@apple.com <oliver@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 9 Jan 2009 17:53:36 +0000 (17:53 +0000)
committeroliver@apple.com <oliver@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 9 Jan 2009 17:53:36 +0000 (17:53 +0000)
        Reviewed by Oliver Hunt.

        https://bugs.webkit.org/show_bug.cgi?id=23175

        Added a template to make the pointer and flags combination
        in UString more readable and less error prone.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@39747 268f45cc-cd09-0410-ab3c-d52691b4dbfc

13 files changed:
JavaScriptCore/ChangeLog
JavaScriptCore/GNUmakefile.am
JavaScriptCore/JavaScriptCore.exp
JavaScriptCore/JavaScriptCore.vcproj/WTF/WTF.vcproj
JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
JavaScriptCore/runtime/Identifier.cpp
JavaScriptCore/runtime/InitializeThreading.cpp
JavaScriptCore/runtime/JSGlobalData.cpp
JavaScriptCore/runtime/PropertyNameArray.cpp
JavaScriptCore/runtime/UString.cpp
JavaScriptCore/runtime/UString.h
JavaScriptGlue/ChangeLog
WebCore/ChangeLog

index f79493f..6f8da9f 100644 (file)
@@ -1,3 +1,64 @@
+2009-01-09  David Levin  <levin@chromium.org>
+
+        Reviewed by Oliver Hunt.
+
+        https://bugs.webkit.org/show_bug.cgi?id=23175
+
+        Added a template to make the pointer and flags combination
+        in UString more readable and less error prone.
+
+        * GNUmakefile.am:
+        * JavaScriptCore.exp:
+        * JavaScriptCore.vcproj/WTF/WTF.vcproj:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        Added PtrAndFlags.h (and sorted the xcode project file).
+
+        * runtime/Identifier.cpp:
+        (JSC::Identifier::add):
+        (JSC::Identifier::addSlowCase):
+        * runtime/InitializeThreading.cpp:
+        (JSC::initializeThreadingOnce):
+        Made the init threading initialize the UString globals.  Before
+        these were initilized using {} but that became harder due to the
+        addition of this tempalte class.
+
+        * runtime/JSGlobalData.cpp:
+        (JSC::JSGlobalData::create):
+        * runtime/PropertyNameArray.cpp:
+        (JSC::PropertyNameArray::add):
+        * runtime/UString.cpp:
+        (JSC::initializeStaticBaseString):
+        (JSC::initializeUString):
+        (JSC::UString::Rep::create):
+        (JSC::UString::Rep::createFromUTF8):
+        (JSC::createRep):
+        (JSC::UString::UString):
+        (JSC::concatenate):
+        (JSC::UString::operator=):
+        (JSC::UString::makeNull):
+        (JSC::UString::nullRep):
+        * runtime/UString.h:
+        (JSC::UString::Rep::identifierTable):
+        (JSC::UString::Rep::setIdentifierTable):
+        (JSC::UString::Rep::isStatic):
+        (JSC::UString::Rep::setStatic):
+        (JSC::UString::Rep::):
+        (JSC::UString::Rep::null):
+        (JSC::UString::Rep::empty):
+        (JSC::UString::isNull):
+        (JSC::UString::null):
+        (JSC::UString::UString):
+
+        * wtf/PtrAndFlags.h: Added.
+        (WTF::PtrAndFlags::PtrAndFlags):
+        (WTF::PtrAndFlags::isFlagSet):
+        (WTF::PtrAndFlags::setFlag):
+        (WTF::PtrAndFlags::clearFlag):
+        (WTF::PtrAndFlags::get):
+        (WTF::PtrAndFlags::set):
+        A simple way to layer together a pointer and 2 flags.  It relies on the pointer being 4 byte aligned,
+        which should happen for all allocators (due to aligning pointers, int's, etc. on 4 byte boundaries).
+
 2009-01-08  Gavin Barraclough  <barraclough@apple.com>
 
         Reviewed by Oliver Hunt.
index 9f993aa..1e7d383 100644 (file)
@@ -219,6 +219,7 @@ javascriptcore_sources += \
        JavaScriptCore/wtf/OwnPtr.h \
        JavaScriptCore/wtf/PassRefPtr.h \
        JavaScriptCore/wtf/Platform.h \
+       JavaScriptCore/wtf/PtrAndFlags.h \
        JavaScriptCore/wtf/RandomNumber.cpp \
        JavaScriptCore/wtf/RandomNumber.h \
        JavaScriptCore/wtf/RandomNumberSeed.h \
index d65a977..92801b6 100644 (file)
@@ -210,7 +210,7 @@ __ZN3JSC7Profile5focusEPKNS_11ProfileNodeE
 __ZN3JSC7Profile7excludeEPKNS_11ProfileNodeE
 __ZN3JSC7Profile7forEachEMNS_11ProfileNodeEFvvE
 __ZN3JSC7UString3Rep11computeHashEPKti
-__ZN3JSC7UString3Rep4nullE
+__ZN3JSC7UString3Rep14nullBaseStringE
 __ZN3JSC7UString3Rep7destroyEv
 __ZN3JSC7UString4fromEi
 __ZN3JSC7UString4fromEj
index 9c6e3e0..eadcd13 100644 (file)
                        >\r
                </File>\r
                <File\r
+                       RelativePath="..\..\wtf\PtrAndFlags.h"\r
+                       >\r
+               </File>\r
+               <File\r
                        RelativePath="..\..\wtf\RandomNumber.cpp"\r
                        >\r
                </File>\r
index 717aea9..1468c3b 100644 (file)
@@ -39,6 +39,7 @@
                088FA5BB0EF76D4300578E6F /* RandomNumber.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 088FA5B90EF76D4300578E6F /* RandomNumber.cpp */; };
                088FA5BC0EF76D4300578E6F /* RandomNumber.h in Headers */ = {isa = PBXBuildFile; fileRef = 088FA5BA0EF76D4300578E6F /* RandomNumber.h */; settings = {ATTRIBUTES = (Private, ); }; };
                08E279E90EF83B10007DB523 /* RandomNumberSeed.h in Headers */ = {isa = PBXBuildFile; fileRef = 08E279E80EF83B10007DB523 /* RandomNumberSeed.h */; };
+               0B1F921D0F1753500036468E /* PtrAndFlags.h in Headers */ = {isa = PBXBuildFile; fileRef = 0B1F921B0F17502D0036468E /* PtrAndFlags.h */; settings = {ATTRIBUTES = (Private, ); }; };
                140B7D1D0DC69AF7009C42B8 /* JSActivation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 14DA818F0D99FD2000B0A4FB /* JSActivation.cpp */; };
                140D17D70E8AD4A9000CD17D /* JSBasePrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 140D17D60E8AD4A9000CD17D /* JSBasePrivate.h */; settings = {ATTRIBUTES = (Private, ); }; };
                141211310A48794D00480255 /* JavaScriptCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 932F5BD90822A1C700736975 /* JavaScriptCore.framework */; };
                088FA5B90EF76D4300578E6F /* RandomNumber.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RandomNumber.cpp; sourceTree = "<group>"; };
                088FA5BA0EF76D4300578E6F /* RandomNumber.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RandomNumber.h; sourceTree = "<group>"; };
                08E279E80EF83B10007DB523 /* RandomNumberSeed.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RandomNumberSeed.h; sourceTree = "<group>"; };
+               0B1F921B0F17502D0036468E /* PtrAndFlags.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PtrAndFlags.h; sourceTree = "<group>"; };
                140D17D60E8AD4A9000CD17D /* JSBasePrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSBasePrivate.h; sourceTree = "<group>"; };
                141211020A48780900480255 /* minidom.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = minidom.c; path = tests/minidom.c; sourceTree = "<group>"; };
                1412110D0A48788700480255 /* minidom.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = minidom.js; path = tests/minidom.js; sourceTree = "<group>"; };
                                9303F567099118FA00AD71B8 /* OwnPtr.h */,
                                6580F795094070560082C219 /* PassRefPtr.h */,
                                65D6D87E09B5A32E0002E4D7 /* Platform.h */,
+                               0B1F921B0F17502D0036468E /* PtrAndFlags.h */,
                                088FA5B90EF76D4300578E6F /* RandomNumber.cpp */,
                                088FA5BA0EF76D4300578E6F /* RandomNumber.h */,
                                08E279E80EF83B10007DB523 /* RandomNumberSeed.h */,
                                6541BD7008E80A17002CBEE7 /* TCSystemAlloc.cpp */,
                                6541BD7108E80A17002CBEE7 /* TCSystemAlloc.h */,
                                E1B7C8BD0DA3A3360074B0DC /* ThreadSpecific.h */,
-                               E1EE79220D6C95CD00FEA3BA /* Threading.h */,
                                5D6A566A0F05995500266145 /* Threading.cpp */,
+                               E1EE79220D6C95CD00FEA3BA /* Threading.h */,
                                E1EE793C0D6C9B9200FEA3BA /* ThreadingPthreads.cpp */,
                                935AF46B09E9D9DB00ACD1D8 /* UnusedParam.h */,
                                6592C316098B7DE10003D4F6 /* Vector.h */,
                                704FD35305697E6D003DBED9 /* BooleanObject.h */,
                                BC7952340E15EB5600A898AB /* BooleanPrototype.cpp */,
                                BC7952350E15EB5600A898AB /* BooleanPrototype.h */,
+                               A791EE5A0F11D90C00AE1F68 /* ByteArray.cpp */,
+                               A791EE590F11D90C00AE1F68 /* ByteArray.h */,
                                BCA62DFE0E2826230004F30D /* CallData.cpp */,
                                145C507F0D9DF63B0088F6B9 /* CallData.h */,
                                BC6AAAE40E1F426500AD87D8 /* ClassInfo.h */,
                                14DA818E0D99FD2000B0A4FB /* JSActivation.h */,
                                93ADFCE60CCBD7AC00D30B08 /* JSArray.cpp */,
                                938772E5038BFE19008635CE /* JSArray.h */,
+                               A791EF270F11E07900AE1F68 /* JSByteArray.cpp */,
+                               A791EF260F11E07900AE1F68 /* JSByteArray.h */,
                                BC7F8FBA0E19D1EF008632C0 /* JSCell.cpp */,
                                BC1167D80E19BCC9008066DD /* JSCell.h */,
                                F692A85E0255597D01FF60F7 /* JSFunction.cpp */,
                                6507D2970E871E4A00D7D896 /* TypeInfo.h */,
                                F692A8850255597D01FF60F7 /* UString.cpp */,
                                F692A8860255597D01FF60F7 /* UString.h */,
-                               A791EE590F11D90C00AE1F68 /* ByteArray.h */,
-                               A791EE5A0F11D90C00AE1F68 /* ByteArray.cpp */,
-                               A791EF260F11E07900AE1F68 /* JSByteArray.h */,
-                               A791EF270F11E07900AE1F68 /* JSByteArray.cpp */,
                        );
                        path = runtime;
                        sourceTree = "<group>";
                                BC18C3EA0E16F5CD00B34460 /* Assertions.h in Headers */,
                                147B83AC0E6DB8C9004775A4 /* BatchedTransitionOptimizer.h in Headers */,
                                BC18C3EC0E16F5CD00B34460 /* BooleanObject.h in Headers */,
+                               A791EE5B0F11D90C00AE1F68 /* ByteArray.h in Headers */,
                                969A07230ED1CE3300F1F681 /* BytecodeGenerator.h in Headers */,
                                BC18C3ED0E16F5CD00B34460 /* CallData.h in Headers */,
                                1429D8DE0ED2205B00B89619 /* CallFrame.h in Headers */,
                                BC18C4170E16F5CD00B34460 /* JSArray.h in Headers */,
                                BC18C4180E16F5CD00B34460 /* JSBase.h in Headers */,
                                140D17D70E8AD4A9000CD17D /* JSBasePrivate.h in Headers */,
+                               A791EF280F11E07900AE1F68 /* JSByteArray.h in Headers */,
                                BC18C4190E16F5CD00B34460 /* JSCallbackConstructor.h in Headers */,
                                BC18C41A0E16F5CD00B34460 /* JSCallbackFunction.h in Headers */,
                                BC18C41B0E16F5CD00B34460 /* JSCallbackObject.h in Headers */,
                                BC18C4550E16F5CD00B34460 /* PropertySlot.h in Headers */,
                                BC18C4560E16F5CD00B34460 /* Protect.h in Headers */,
                                BC257DF40E1F53740016B6C9 /* PrototypeFunction.h in Headers */,
+                               0B1F921D0F1753500036468E /* PtrAndFlags.h in Headers */,
                                147B84630E6DE6B1004775A4 /* PutPropertySlot.h in Headers */,
                                1429DA4A0ED245EC00B89619 /* Quantifier.h in Headers */,
                                088FA5BC0EF76D4300578E6F /* RandomNumber.h in Headers */,
                                BC18C44D0E16F5CD00B34460 /* pcre.h in Headers */,
                                BC18C44E0E16F5CD00B34460 /* pcre_internal.h in Headers */,
                                BC18C4720E16F5CD00B34460 /* ucpinternal.h in Headers */,
-                               A791EE5B0F11D90C00AE1F68 /* ByteArray.h in Headers */,
-                               A791EF280F11E07900AE1F68 /* JSByteArray.h in Headers */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                        files = (
                                659126BD0BDD1728001921FB /* AllInOneFile.cpp in Sources */,
                                65FDE49C0BDD1D4A00E80111 /* Assertions.cpp in Sources */,
+                               A791EE5C0F11D90C00AE1F68 /* ByteArray.cpp in Sources */,
                                1429D8DD0ED2205B00B89619 /* CallFrame.cpp in Sources */,
                                1429D9C40ED23C3900B89619 /* CharacterClass.cpp in Sources */,
                                7E2ADD900E79AC1100D50C51 /* CharacterClassConstructor.cpp in Sources */,
                                86CC85C40EE7A89400288682 /* JITPropertyAccess.cpp in Sources */,
                                140B7D1D0DC69AF7009C42B8 /* JSActivation.cpp in Sources */,
                                1421359B0A677F4F00A8195E /* JSBase.cpp in Sources */,
+                               A791EF290F11E07900AE1F68 /* JSByteArray.cpp in Sources */,
                                1440F8AF0A508D200005F061 /* JSCallbackConstructor.cpp in Sources */,
                                1440F8920A508B100005F061 /* JSCallbackFunction.cpp in Sources */,
                                14ABDF600A437FEF00ECCA01 /* JSCallbackObject.cpp in Sources */,
                                BCDE3B430E6C832D001453A7 /* Structure.cpp in Sources */,
                                7E4EE70F0EBB7A5B005934AA /* StructureChain.cpp in Sources */,
                                BCCF0D0C0EF0B8A500413C8F /* StructureStubInfo.cpp in Sources */,
+                               5D6A566B0F05995500266145 /* Threading.cpp in Sources */,
                                E1EE793D0D6C9B9200FEA3BA /* ThreadingPthreads.cpp in Sources */,
                                95CD41B30E1BF6560085358E /* TreeProfile.cpp in Sources */,
                                E1EF79AA0CE97BA60088D500 /* UTF8.cpp in Sources */,
                                930754D008B0F74600AB3056 /* pcre_tables.cpp in Sources */,
                                937013480CA97E0E00FA14D3 /* pcre_ucp_searchfuncs.cpp in Sources */,
                                93E26BD408B1514100F85226 /* pcre_xclass.cpp in Sources */,
-                               5D6A566B0F05995500266145 /* Threading.cpp in Sources */,
-                               A791EE5C0F11D90C00AE1F68 /* ByteArray.cpp in Sources */,
-                               A791EF290F11E07900AE1F68 /* JSByteArray.cpp in Sources */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
index 8372010..040c123 100644 (file)
@@ -124,12 +124,12 @@ struct CStringTranslator {
 PassRefPtr<UString::Rep> Identifier::add(JSGlobalData* globalData, const char* c)
 {
     if (!c) {
-        UString::Rep::null.hash();
-        return &UString::Rep::null;
+        UString::Rep::null().hash();
+        return &UString::Rep::null();
     }
     if (!c[0]) {
-        UString::Rep::empty.hash();
-        return &UString::Rep::empty;
+        UString::Rep::empty().hash();
+        return &UString::Rep::empty();
     }
     if (!c[1])
         return add(globalData, globalData->smallStrings.singleCharacterStringRep(static_cast<unsigned char>(c[0])));
@@ -194,8 +194,8 @@ PassRefPtr<UString::Rep> Identifier::add(JSGlobalData* globalData, const UChar*
             return add(globalData, globalData->smallStrings.singleCharacterStringRep(c));
     }
     if (!length) {
-        UString::Rep::empty.hash();
-        return &UString::Rep::empty;
+        UString::Rep::empty().hash();
+        return &UString::Rep::empty();
     }
     UCharBuffer buf = {s, length}; 
     pair<HashSet<UString::Rep*>::iterator, bool> addResult = globalData->identifierTable->add<UCharBuffer, UCharBufferTranslator>(buf);
@@ -225,8 +225,8 @@ PassRefPtr<UString::Rep> Identifier::addSlowCase(JSGlobalData* globalData, UStri
             }
     }
     if (!r->len) {
-        UString::Rep::empty.hash();
-        return &UString::Rep::empty;
+        UString::Rep::empty().hash();
+        return &UString::Rep::empty();
     }
     return *globalData->identifierTable->add(r).first;
 }
index a17c386..cda9fb1 100644 (file)
@@ -49,9 +49,9 @@ static pthread_once_t initializeThreadingKeyOnce = PTHREAD_ONCE_INIT;
 static void initializeThreadingOnce()
 {
     WTF::initializeThreading();
+    initializeUString();
 #if ENABLE(JSC_MULTIPLE_THREADS)
     s_dtoaP5Mutex = new Mutex;
-    UString::null();
     initDateMath();
 #endif
 }
index 62df65e..d671a69 100644 (file)
 #include "JSGlobalData.h"
 
 #include "ArgList.h"
+#include "Collector.h"
 #include "CommonIdentifiers.h"
+#include "InitializeThreading.h"
+#include "Interpreter.h"
 #include "JSActivation.h"
 #include "JSClassRef.h"
 #include "JSLock.h"
 #include "JSNotAnObject.h"
 #include "JSStaticScopeObject.h"
-#include "Interpreter.h"
 #include "Parser.h"
-#include "Collector.h"
 #include "Lexer.h"
 #include "Lookup.h"
 #include "Nodes.h"
@@ -142,6 +143,7 @@ JSGlobalData::~JSGlobalData()
 
 PassRefPtr<JSGlobalData> JSGlobalData::create()
 {
+    initializeThreading();
     return adoptRef(new JSGlobalData);
 }
 
index 47e9d84..0878e73 100644 (file)
@@ -27,7 +27,7 @@ static const size_t setThreshold = 20;
 
 void PropertyNameArray::add(UString::Rep* identifier)
 {
-    ASSERT(identifier == &UString::Rep::null || identifier == &UString::Rep::empty || identifier->identifierTable());
+    ASSERT(identifier == &UString::Rep::null() || identifier == &UString::Rep::empty() || identifier->identifierTable());
 
     size_t size = m_data->propertyNameVector().size();
     if (size < setThreshold) {
index 45df248..46dbd09 100644 (file)
@@ -2,6 +2,7 @@
  *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
  *  Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
  *  Copyright (C) 2007 Cameron Zwarich (cwzwarich@uwaterloo.ca)
+ *  Copyright (c) 2009, Google Inc. All rights reserved.
  *
  *  This library is free software; you can redistribute it and/or
  *  modify it under the terms of the GNU Library General Public
@@ -186,8 +187,36 @@ bool operator==(const CString& c1, const CString& c2)
 // These static strings are immutable, except for rc, whose initial value is chosen to 
 // reduce the possibility of it becoming zero due to ref/deref not being thread-safe.
 static UChar sharedEmptyChar;
-UString::Rep UString::Rep::null = { 0, 0, INT_MAX / 2, 0, 1, &UString::Rep::null, 0, 0, 0, 0, 0, 0 };
-UString::Rep UString::Rep::empty = { 0, 0, INT_MAX / 2, 0, 1, &UString::Rep::empty, 0, &sharedEmptyChar, 0, 0, 0, 0 };
+UString::Rep* UString::Rep::nullBaseString;
+UString::Rep* UString::Rep::emptyBaseString;
+UString* UString::nullUString;
+
+void initializeStaticBaseString(int len, UChar* buf, UString::Rep& base)
+{
+    base.offset = 0;
+    base.len = len;
+    base.rc = INT_MAX / 2;
+    base._hash = 0;
+    base.m_identifierTableAndFlags.setFlag(UString::Rep::StaticFlag);
+    base.baseString = &base;
+    base.buf = buf;
+    base.preCapacity = 0;
+    base.usedPreCapacity = 0;
+    base.capacity = 0;
+    base.usedCapacity = 0;
+    base.reportedCost = 0;
+}
+
+void initializeUString()
+{
+    UString::Rep::nullBaseString = new UString::Rep;
+    initializeStaticBaseString(0, 0, *UString::Rep::nullBaseString);
+
+    UString::Rep::emptyBaseString = new UString::Rep;
+    initializeStaticBaseString(0, &sharedEmptyChar, *UString::Rep::emptyBaseString);
+
+    UString::nullUString = new UString;
+}
 
 static char* statBuffer = 0; // Only used for debugging via UString::ascii().
 
@@ -205,7 +234,6 @@ PassRefPtr<UString::Rep> UString::Rep::create(UChar* d, int l)
     r->len = l;
     r->rc = 1;
     r->_hash = 0;
-    r->m_identifierTable = 0;
     r->baseString = r;
     r->reportedCost = 0;
     r->buf = d;
@@ -237,7 +265,6 @@ PassRefPtr<UString::Rep> UString::Rep::create(PassRefPtr<Rep> base, int offset,
     r->len = length;
     r->rc = 1;
     r->_hash = 0;
-    r->m_identifierTable = 0;
     r->baseString = base.releaseRef();
     r->reportedCost = 0;
     r->buf = 0;
@@ -255,13 +282,13 @@ PassRefPtr<UString::Rep> UString::Rep::create(PassRefPtr<Rep> base, int offset,
 PassRefPtr<UString::Rep> UString::Rep::createFromUTF8(const char* string)
 {
     if (!string)
-        return &UString::Rep::null;
+        return &UString::Rep::null();
 
     size_t length = strlen(string);
     Vector<UChar, 1024> buffer(length);
     UChar* p = buffer.data();
     if (conversionOK != convertUTF8ToUTF16(&string, string + length, &p, p + length))
-        return &UString::Rep::null;
+        return &UString::Rep::null();
 
     return UString::Rep::createCopying(buffer.data(), p - buffer.data());
 }
@@ -494,15 +521,15 @@ void UString::expandPreCapacity(int requiredPreCap)
 PassRefPtr<UString::Rep> createRep(const char* c)
 {
     if (!c)
-        return &UString::Rep::null;
+        return &UString::Rep::null();
 
     if (!c[0])
-        return &UString::Rep::empty;
+        return &UString::Rep::empty();
 
     size_t length = strlen(c);
     UChar* d = allocChars(length);
     if (!d)
-        return &UString::Rep::null;
+        return &UString::Rep::null();
     else {
         for (size_t i = 0; i < length; i++)
             d[i] = static_cast<unsigned char>(c[i]); // use unsigned char to zero-extend instead of sign-extend
@@ -519,7 +546,7 @@ UString::UString(const char* c)
 UString::UString(const UChar* c, int length)
 {
     if (length == 0) 
-        m_rep = &Rep::empty;
+        m_rep = &Rep::empty();
     else
         m_rep = Rep::createCopying(c, length);
 }
@@ -527,7 +554,7 @@ UString::UString(const UChar* c, int length)
 UString::UString(UChar* c, int length, bool copy)
 {
     if (length == 0)
-        m_rep = &Rep::empty;
+        m_rep = &Rep::empty();
     else if (copy)
         m_rep = Rep::createCopying(c, length);
     else
@@ -537,7 +564,7 @@ UString::UString(UChar* c, int length, bool copy)
 UString::UString(const Vector<UChar>& buffer)
 {
     if (!buffer.size())
-        m_rep = &Rep::empty;
+        m_rep = &Rep::empty();
     else
         m_rep = Rep::createCopying(buffer.data(), buffer.size());
 }
@@ -561,7 +588,7 @@ static ALWAYS_INLINE PassRefPtr<UString::Rep> concatenate(PassRefPtr<UString::Re
     } else if (rep->baseIsSelf() && rep->rc == 1) {
         // this is direct and has refcount of 1 (so we can just alter it directly)
         if (!expandCapacity(rep.get(), thisOffset + length))
-            rep = &UString::Rep::null;
+            rep = &UString::Rep::null();
         if (rep->data()) {
             copyChars(rep->data() + thisSize, tData, tSize);
             rep->len = length;
@@ -570,7 +597,7 @@ static ALWAYS_INLINE PassRefPtr<UString::Rep> concatenate(PassRefPtr<UString::Re
     } else if (thisOffset + thisSize == rep->baseString->usedCapacity && thisSize >= minShareSize) {
         // this reaches the end of the buffer - extend it if it's long enough to append to
         if (!expandCapacity(rep.get(), thisOffset + length))
-            rep = &UString::Rep::null;
+            rep = &UString::Rep::null();
         if (rep->data()) {
             copyChars(rep->data() + thisSize, tData, tSize);
             rep = UString::Rep::create(rep, 0, length);
@@ -580,7 +607,7 @@ static ALWAYS_INLINE PassRefPtr<UString::Rep> concatenate(PassRefPtr<UString::Re
         size_t newCapacity = expandedSize(length, 0);
         UChar* d = allocChars(newCapacity);
         if (!d)
-            rep = &UString::Rep::null;
+            rep = &UString::Rep::null();
         else {
             copyChars(d, rep->data(), thisSize);
             copyChars(d + thisSize, tData, tSize);
@@ -635,7 +662,7 @@ static ALWAYS_INLINE PassRefPtr<UString::Rep> concatenate(PassRefPtr<UString::Re
         size_t newCapacity = expandedSize(length, 0);
         UChar* d = allocChars(newCapacity);
         if (!d)
-            rep = &UString::Rep::null;
+            rep = &UString::Rep::null();
         else {
             copyChars(d, rep->data(), thisSize);
             for (int i = 0; i < tSize; ++i)
@@ -831,12 +858,6 @@ PassRefPtr<UString::Rep> concatenate(UString::Rep* rep, double d)
   return concatenate(rep, buf);
 }
 
-const UString& UString::null()
-{
-    static UString* n = new UString; // Should be called from main thread at least once to be safely initialized.
-    return *n;
-}
-
 UString UString::from(int i)
 {
     UChar buf[1 + sizeof(i) * 3];
@@ -1185,12 +1206,12 @@ char* UString::ascii() const
 UString& UString::operator=(const char* c)
 {
     if (!c) {
-        m_rep = &Rep::null;
+        m_rep = &Rep::null();
         return *this;
     }
 
     if (!c[0]) {
-        m_rep = &Rep::empty;
+        m_rep = &Rep::empty();
         return *this;
     }
 
@@ -1626,13 +1647,13 @@ CString UString::UTF8String(bool strict) const
 // For use in error handling code paths -- having this not be inlined helps avoid PIC branches to fetch the global on Mac OS X.
 NEVER_INLINE void UString::makeNull()
 {
-    m_rep = &Rep::null;
+    m_rep = &Rep::null();
 }
 
 // For use in error handling code paths -- having this not be inlined helps avoid PIC branches to fetch the global on Mac OS X.
 NEVER_INLINE UString::Rep* UString::nullRep()
 {
-    return &Rep::null;
+    return &Rep::null();
 }
 
 } // namespace JSC
index 75403c0..b6cd158 100644 (file)
@@ -1,6 +1,7 @@
 /*
  *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
  *  Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
+ *  Copyright (c) 2009, Google Inc. All rights reserved.
  *
  *  This library is free software; you can redistribute it and/or
  *  modify it under the terms of the GNU Library General Public
@@ -28,6 +29,7 @@
 #include <wtf/Assertions.h>
 #include <wtf/FastMalloc.h>
 #include <wtf/PassRefPtr.h>
+#include <wtf/PtrAndFlags.h>
 #include <wtf/RefPtr.h>
 #include <wtf/Vector.h>
 #include <wtf/unicode/Unicode.h>
@@ -98,23 +100,26 @@ namespace JSC {
             static unsigned computeHash(const char*, int length);
             static unsigned computeHash(const char* s) { return computeHash(s, strlen(s)); }
 
-            IdentifierTable* identifierTable() const { return reinterpret_cast<IdentifierTable*>(m_identifierTable & ~static_cast<uintptr_t>(1)); }
-            void setIdentifierTable(IdentifierTable* table) { ASSERT(!isStatic()); m_identifierTable = reinterpret_cast<intptr_t>(table); }
+            IdentifierTable* identifierTable() const { return m_identifierTableAndFlags.get(); }
+            void setIdentifierTable(IdentifierTable* table) { ASSERT(!isStatic()); m_identifierTableAndFlags.set(table); }
 
-            bool isStatic() const { return m_identifierTable & 1; }
-            void setStatic(bool v) { ASSERT(!identifierTable()); m_identifierTable = v; }
+            bool isStatic() const { return m_identifierTableAndFlags.isFlagSet(StaticFlag); }
+            void setStatic(bool v) { ASSERT(!identifierTable()); if (v) m_identifierTableAndFlags.setFlag(StaticFlag); else m_identifierTableAndFlags.clearFlag(StaticFlag); }
 
             Rep* ref() { ++rc; return this; }
             ALWAYS_INLINE void deref() { if (--rc == 0) destroy(); }
 
             void checkConsistency() const;
+            enum UStringFlags {
+                StaticFlag
+            };
 
             // unshared data
             int offset;
             int len;
             int rc; // For null and empty static strings, this field does not reflect a correct count, because ref/deref are not thread-safe. A special case in destroy() guarantees that these do not get deleted.
             mutable unsigned _hash;
-            intptr_t m_identifierTable; // A pointer to identifier table. The lowest bit is used to indicate whether the string is static (null or empty).
+            PtrAndFlags<IdentifierTable, UStringFlags> m_identifierTableAndFlags;
             UString::Rep* baseString;
             size_t reportedCost;
 
@@ -125,8 +130,12 @@ namespace JSC {
             int usedPreCapacity;
             int preCapacity;
 
-            static Rep null;
-            static Rep empty;
+            static Rep& null() { return *nullBaseString; }
+            static Rep& empty() { return *emptyBaseString; }
+        private:
+            friend void initializeUString();
+            static Rep* nullBaseString;
+            static Rep* emptyBaseString;
         };
 
     public:
@@ -204,7 +213,7 @@ namespace JSC {
 
         const UChar* data() const { return m_rep->data(); }
 
-        bool isNull() const { return (m_rep == &Rep::null); }
+        bool isNull() const { return (m_rep == &Rep::null()); }
         bool isEmpty() const { return (!m_rep->len); }
 
         bool is8Bit() const;
@@ -230,7 +239,7 @@ namespace JSC {
 
         UString substr(int pos = 0, int len = -1) const;
 
-        static const UString& null();
+        static const UString& null() { return *nullUString; }
 
         Rep* rep() const { return m_rep.get(); }
         static Rep* nullRep();
@@ -251,7 +260,9 @@ namespace JSC {
         void makeNull();
 
         RefPtr<Rep> m_rep;
+        static UString* nullUString;
 
+        friend void initializeUString();
         friend bool operator==(const UString&, const UString&);
         friend PassRefPtr<Rep> concatenate(Rep*, Rep*); // returns 0 if out of memory
     };
@@ -305,7 +316,7 @@ namespace JSC {
 #endif
 
     inline UString::UString()
-        : m_rep(&Rep::null)
+        : m_rep(&Rep::null())
     {
     }
 
@@ -347,6 +358,7 @@ namespace JSC {
         static unsigned hash(JSC::UString::Rep* key) { return key->computedHash(); }
     };
 
+    void initializeUString();
 } // namespace JSC
 
 namespace WTF {
index bd0fe5d..28bb610 100644 (file)
@@ -1,3 +1,13 @@
+2009-01-09  David Levin  <levin@chromium.org>
+
+        Reviewed by Oliver Hunt.
+
+        https://bugs.webkit.org/show_bug.cgi?id=23175
+
+        Added forwarding header.
+
+        * ForwardingHeaders/wtf/PtrAndFlags.h: Added.
+
 2009-01-05  Gavin Barraclough  <baraclough@apple.com>
 
         Rubber Stamped by Oliver Hunt.
index 6dc408b..d6f2e23 100644 (file)
@@ -1,3 +1,13 @@
+2009-01-09  David Levin  <levin@chromium.org>
+
+        Reviewed by Oliver Hunt.
+
+        https://bugs.webkit.org/show_bug.cgi?id=23175
+
+        Added forwarding header.
+
+        * ForwardingHeaders/wtf/PtrAndFlags.h: Added.
+
 2009-01-09  Tor Arne Vestbø  <tavestbo@trolltech.com>
 
         Reviewed by Simon Hausmann.