1/*
2 * Copyright (C) 2010 Apple Inc. All Rights Reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 *    notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 *    notice, this list of conditions and the following disclaimer in the
11 *    documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#include "config.h"
27
28#ifdef SKIP_STATIC_CONSTRUCTORS_ON_GCC
29#define ATOMICSTRING_HIDE_GLOBALS 1
30#endif
31
32#include "AtomicString.h"
33#include "MainThread.h"
34#include "NeverDestroyed.h"
35#include "StaticConstructors.h"
36#include "StringImpl.h"
37
38#if USE(WEB_THREAD)
39#include <pthread.h>
40#endif
41
42namespace WTF {
43
44StringImpl* StringImpl::empty()
45{
46    static NeverDestroyed<StringImpl> emptyString(ConstructEmptyString);
47    return &emptyString.get();
48}
49
50// Set the hash early, so that all empty unique StringImpls have a hash,
51// and don't use the normal hashing algorithm - the unique nature of these
52// keys means that we don't need them to match any other string (in fact,
53// that's exactly the oposite of what we want!), and the normal hash would
54// lead to lots of conflicts.
55unsigned StringImpl::hashAndFlagsForEmptyUnique()
56{
57    static unsigned s_nextHashAndFlagsForEmptyUnique = BufferInternal | s_hashFlag8BitBuffer | s_hashFlagIsAtomic;
58    s_nextHashAndFlagsForEmptyUnique += 1 << s_flagCount;
59    s_nextHashAndFlagsForEmptyUnique |= 1 << 31;
60    return s_nextHashAndFlagsForEmptyUnique;
61}
62
63WTF_EXPORTDATA DEFINE_GLOBAL(AtomicString, nullAtom)
64WTF_EXPORTDATA DEFINE_GLOBAL(AtomicString, emptyAtom)
65WTF_EXPORTDATA DEFINE_GLOBAL(AtomicString, textAtom)
66WTF_EXPORTDATA DEFINE_GLOBAL(AtomicString, commentAtom)
67WTF_EXPORTDATA DEFINE_GLOBAL(AtomicString, starAtom)
68WTF_EXPORTDATA DEFINE_GLOBAL(AtomicString, xmlAtom)
69WTF_EXPORTDATA DEFINE_GLOBAL(AtomicString, xmlnsAtom)
70WTF_EXPORTDATA DEFINE_GLOBAL(AtomicString, xlinkAtom)
71
72NEVER_INLINE unsigned StringImpl::hashSlowCase() const
73{
74    if (is8Bit())
75        setHash(StringHasher::computeHashAndMaskTop8Bits(m_data8, m_length));
76    else
77        setHash(StringHasher::computeHashAndMaskTop8Bits(m_data16, m_length));
78    return existingHash();
79}
80
81void AtomicString::init()
82{
83    static bool initialized;
84    if (!initialized) {
85        // Initialization is not thread safe, so this function must be called from the main thread first.
86        ASSERT(isUIThread());
87
88        // Use placement new to initialize the globals.
89        new (NotNull, (void*)&nullAtom) AtomicString;
90        new (NotNull, (void*)&emptyAtom) AtomicString("");
91        new (NotNull, (void*)&textAtom) AtomicString("#text", AtomicString::ConstructFromLiteral);
92        new (NotNull, (void*)&commentAtom) AtomicString("#comment", AtomicString::ConstructFromLiteral);
93        new (NotNull, (void*)&starAtom) AtomicString("*", AtomicString::ConstructFromLiteral);
94        new (NotNull, (void*)&xmlAtom) AtomicString("xml", AtomicString::ConstructFromLiteral);
95        new (NotNull, (void*)&xmlnsAtom) AtomicString("xmlns", AtomicString::ConstructFromLiteral);
96        new (NotNull, (void*)&xlinkAtom) AtomicString("xlink", AtomicString::ConstructFromLiteral);
97
98        initialized = true;
99    }
100}
101
102}
103