+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.
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 \
__ZN3JSC7Profile7excludeEPKNS_11ProfileNodeE
__ZN3JSC7Profile7forEachEMNS_11ProfileNodeEFvvE
__ZN3JSC7UString3Rep11computeHashEPKti
-__ZN3JSC7UString3Rep4nullE
+__ZN3JSC7UString3Rep14nullBaseStringE
__ZN3JSC7UString3Rep7destroyEv
__ZN3JSC7UString4fromEi
__ZN3JSC7UString4fromEj
>\r
</File>\r
<File\r
+ RelativePath="..\..\wtf\PtrAndFlags.h"\r
+ >\r
+ </File>\r
+ <File\r
RelativePath="..\..\wtf\RandomNumber.cpp"\r
>\r
</File>\r
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;
};
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])));
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);
}
}
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;
}
static void initializeThreadingOnce()
{
WTF::initializeThreading();
+ initializeUString();
#if ENABLE(JSC_MULTIPLE_THREADS)
s_dtoaP5Mutex = new Mutex;
- UString::null();
initDateMath();
#endif
}
#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"
PassRefPtr<JSGlobalData> JSGlobalData::create()
{
+ initializeThreading();
return adoptRef(new JSGlobalData);
}
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) {
* 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
// 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().
r->len = l;
r->rc = 1;
r->_hash = 0;
- r->m_identifierTable = 0;
r->baseString = r;
r->reportedCost = 0;
r->buf = d;
r->len = length;
r->rc = 1;
r->_hash = 0;
- r->m_identifierTable = 0;
r->baseString = base.releaseRef();
r->reportedCost = 0;
r->buf = 0;
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());
}
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
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);
}
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
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());
}
} 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;
} 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);
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);
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)
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];
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;
}
// 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
/*
* 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
#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>
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;
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:
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;
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();
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
};
#endif
inline UString::UString()
- : m_rep(&Rep::null)
+ : m_rep(&Rep::null())
{
}
static unsigned hash(JSC::UString::Rep* key) { return key->computedHash(); }
};
+ void initializeUString();
} // namespace JSC
namespace WTF {
+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.
+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.