source: webkit/trunk/JavaScriptCore/runtime/JSGlobalData.cpp@ 58114

Last change on this file since 58114 was 58114, checked in by [email protected], 15 years ago

https://bugs.webkit.org/show_bug.cgi?id=37978
Unify JSC::IdentifierTable and WebCore::AtomicStringTable implementations.

Reviewed by Geoff Garen.

These two classes both implement a HashSet of uniqued StringImpls, with
translator classes to avoid unnecessary object creation. The only difference
between the classes is which flag (isIdentifier or inTable) is set.
Combine the two classes using a template predicated on which flag to use.

New class AtomicStringTable created, containing all the goodness from
IdentifierTable & AtomicStringTable, expect for Identifier's literalTable,
which has been moved onto JSGlobalData. Removed duplicate string translator
classes. Renamed StringImpl's inTable flag to more explicit 'isAtomic',
and set this on the empty string (which matches Identifier behaviour, and
removes a redundant check for zero-length).

(JSC::createLiteralTable):
(JSC::deleteLiteralTable):
(JSC::Identifier::add):
(JSC::Identifier::addSlowCase):

  • runtime/Identifier.h:
  • runtime/JSGlobalData.cpp:

(JSC::JSGlobalData::JSGlobalData):
(JSC::JSGlobalData::~JSGlobalData):

  • runtime/JSGlobalData.h:
  • wtf/WTFThreadData.cpp:

(WTF::WTFThreadData::WTFThreadData):
(WTF::WTFThreadData::~WTFThreadData):

  • wtf/WTFThreadData.h:

(WTF::WTFThreadData::atomicStringTable):

  • wtf/text/AtomicString.cpp:

(WebCore::table):
(WebCore::operator==):
(WebCore::AtomicString::add):
(WebCore::AtomicString::find):
(WebCore::AtomicString::remove):

  • wtf/text/AtomicStringTable.h: Added.

(WTF::CStringTranslator::hash):
(WTF::CStringTranslator::equal):
(WTF::CStringTranslator::translate):
(WTF::UCharBufferTranslator::hash):
(WTF::UCharBufferTranslator::equal):
(WTF::UCharBufferTranslator::translate):
(WTF::HashAndCharactersTranslator::hash):
(WTF::HashAndCharactersTranslator::equal):
(WTF::HashAndCharactersTranslator::translate):
(WTF::IdentifierOrAtomicStringTable::remove):
(WTF::::~IdentifierOrAtomicStringTable):
(WTF::::add):
(WTF::::find):

  • wtf/text/StringImpl.cpp:

(WebCore::StringImpl::~StringImpl):

  • wtf/text/StringImpl.h:

(WebCore::StringImpl::isAtomic):
(WebCore::StringImpl::setIsAtomic):
(WebCore::equal):

  • wtf/text/StringImplBase.h:

(WTF::StringImplBase::StringImplBase):

  • Property svn:eol-style set to native
File size: 9.7 KB
Line 
1/*
2 * Copyright (C) 2008 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 *
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
14 * its contributors may be used to endorse or promote products derived
15 * from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
18 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
21 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29#include "config.h"
30#include "JSGlobalData.h"
31
32#include "ArgList.h"
33#include "Collector.h"
34#include "CommonIdentifiers.h"
35#include "FunctionConstructor.h"
36#include "GetterSetter.h"
37#include "Interpreter.h"
38#include "JSActivation.h"
39#include "JSAPIValueWrapper.h"
40#include "JSArray.h"
41#include "JSByteArray.h"
42#include "JSClassRef.h"
43#include "JSFunction.h"
44#include "JSLock.h"
45#include "JSNotAnObject.h"
46#include "JSPropertyNameIterator.h"
47#include "JSStaticScopeObject.h"
48#include "Lexer.h"
49#include "Lookup.h"
50#include "Nodes.h"
51#include "Parser.h"
52#include <wtf/WTFThreadData.h>
53
54#if ENABLE(JSC_MULTIPLE_THREADS)
55#include <wtf/Threading.h>
56#endif
57
58#if PLATFORM(MAC)
59#include "ProfilerServer.h"
60#endif
61
62using namespace WTF;
63
64namespace JSC {
65
66extern JSC_CONST_HASHTABLE HashTable arrayTable;
67extern JSC_CONST_HASHTABLE HashTable jsonTable;
68extern JSC_CONST_HASHTABLE HashTable dateTable;
69extern JSC_CONST_HASHTABLE HashTable mathTable;
70extern JSC_CONST_HASHTABLE HashTable numberTable;
71extern JSC_CONST_HASHTABLE HashTable regExpTable;
72extern JSC_CONST_HASHTABLE HashTable regExpConstructorTable;
73extern JSC_CONST_HASHTABLE HashTable stringTable;
74
75void* JSGlobalData::jsArrayVPtr;
76void* JSGlobalData::jsByteArrayVPtr;
77void* JSGlobalData::jsStringVPtr;
78void* JSGlobalData::jsFunctionVPtr;
79
80void JSGlobalData::storeVPtrs()
81{
82 CollectorCell cell;
83 void* storage = &cell;
84
85 COMPILE_ASSERT(sizeof(JSArray) <= sizeof(CollectorCell), sizeof_JSArray_must_be_less_than_CollectorCell);
86 JSCell* jsArray = new (storage) JSArray(JSArray::createStructure(jsNull()));
87 JSGlobalData::jsArrayVPtr = jsArray->vptr();
88 jsArray->~JSCell();
89
90 COMPILE_ASSERT(sizeof(JSByteArray) <= sizeof(CollectorCell), sizeof_JSByteArray_must_be_less_than_CollectorCell);
91 JSCell* jsByteArray = new (storage) JSByteArray(JSByteArray::VPtrStealingHack);
92 JSGlobalData::jsByteArrayVPtr = jsByteArray->vptr();
93 jsByteArray->~JSCell();
94
95 COMPILE_ASSERT(sizeof(JSString) <= sizeof(CollectorCell), sizeof_JSString_must_be_less_than_CollectorCell);
96 JSCell* jsString = new (storage) JSString(JSString::VPtrStealingHack);
97 JSGlobalData::jsStringVPtr = jsString->vptr();
98 jsString->~JSCell();
99
100 COMPILE_ASSERT(sizeof(JSFunction) <= sizeof(CollectorCell), sizeof_JSFunction_must_be_less_than_CollectorCell);
101 JSCell* jsFunction = new (storage) JSFunction(JSFunction::createStructure(jsNull()));
102 JSGlobalData::jsFunctionVPtr = jsFunction->vptr();
103 jsFunction->~JSCell();
104}
105
106JSGlobalData::JSGlobalData(bool isShared, ThreadStackType threadStackType)
107 : isSharedInstance(isShared)
108 , clientData(0)
109 , arrayTable(fastNew<HashTable>(JSC::arrayTable))
110 , dateTable(fastNew<HashTable>(JSC::dateTable))
111 , jsonTable(fastNew<HashTable>(JSC::jsonTable))
112 , mathTable(fastNew<HashTable>(JSC::mathTable))
113 , numberTable(fastNew<HashTable>(JSC::numberTable))
114 , regExpTable(fastNew<HashTable>(JSC::regExpTable))
115 , regExpConstructorTable(fastNew<HashTable>(JSC::regExpConstructorTable))
116 , stringTable(fastNew<HashTable>(JSC::stringTable))
117 , activationStructure(JSActivation::createStructure(jsNull()))
118 , interruptedExecutionErrorStructure(JSObject::createStructure(jsNull()))
119 , terminatedExecutionErrorStructure(JSObject::createStructure(jsNull()))
120 , staticScopeStructure(JSStaticScopeObject::createStructure(jsNull()))
121 , stringStructure(JSString::createStructure(jsNull()))
122 , notAnObjectErrorStubStructure(JSNotAnObjectErrorStub::createStructure(jsNull()))
123 , notAnObjectStructure(JSNotAnObject::createStructure(jsNull()))
124 , propertyNameIteratorStructure(JSPropertyNameIterator::createStructure(jsNull()))
125 , getterSetterStructure(GetterSetter::createStructure(jsNull()))
126 , apiWrapperStructure(JSAPIValueWrapper::createStructure(jsNull()))
127 , dummyMarkableCellStructure(JSCell::createDummyStructure())
128#if USE(JSVALUE32)
129 , numberStructure(JSNumberCell::createStructure(jsNull()))
130#endif
131 , identifierTable(createIdentifierTable())
132 , literalTable(createLiteralTable())
133 , propertyNames(new CommonIdentifiers(this))
134 , emptyList(new MarkedArgumentBuffer)
135 , lexer(new Lexer(this))
136 , parser(new Parser)
137 , interpreter(new Interpreter)
138#if ENABLE(JIT)
139 , jitStubs(this)
140#endif
141 , heap(this)
142 , initializingLazyNumericCompareFunction(false)
143 , head(0)
144 , dynamicGlobalObject(0)
145 , functionCodeBlockBeingReparsed(0)
146 , firstStringifierToMark(0)
147 , markStack(jsArrayVPtr)
148 , cachedUTCOffset(NaN)
149 , weakRandom(static_cast<int>(currentTime()))
150 , maxReentryDepth(threadStackType == ThreadStackTypeSmall ? MaxSmallThreadReentryDepth : MaxLargeThreadReentryDepth)
151#ifndef NDEBUG
152 , exclusiveThread(0)
153#endif
154{
155#if PLATFORM(MAC)
156 startProfilerServerIfNeeded();
157#endif
158}
159
160JSGlobalData::~JSGlobalData()
161{
162 // By the time this is destroyed, heap.destroy() must already have been called.
163
164 delete interpreter;
165#ifndef NDEBUG
166 // Zeroing out to make the behavior more predictable when someone attempts to use a deleted instance.
167 interpreter = 0;
168#endif
169
170 arrayTable->deleteTable();
171 dateTable->deleteTable();
172 jsonTable->deleteTable();
173 mathTable->deleteTable();
174 numberTable->deleteTable();
175 regExpTable->deleteTable();
176 regExpConstructorTable->deleteTable();
177 stringTable->deleteTable();
178
179 fastDelete(const_cast<HashTable*>(arrayTable));
180 fastDelete(const_cast<HashTable*>(dateTable));
181 fastDelete(const_cast<HashTable*>(jsonTable));
182 fastDelete(const_cast<HashTable*>(mathTable));
183 fastDelete(const_cast<HashTable*>(numberTable));
184 fastDelete(const_cast<HashTable*>(regExpTable));
185 fastDelete(const_cast<HashTable*>(regExpConstructorTable));
186 fastDelete(const_cast<HashTable*>(stringTable));
187
188 delete parser;
189 delete lexer;
190
191 deleteAllValues(opaqueJSClassData);
192
193 delete emptyList;
194
195 delete propertyNames;
196 deleteIdentifierTable(identifierTable);
197 deleteLiteralTable(literalTable);
198
199 delete clientData;
200}
201
202PassRefPtr<JSGlobalData> JSGlobalData::createNonDefault(ThreadStackType type)
203{
204 return adoptRef(new JSGlobalData(false, type));
205}
206
207PassRefPtr<JSGlobalData> JSGlobalData::create(ThreadStackType type)
208{
209 JSGlobalData* globalData = new JSGlobalData(false, type);
210 wtfThreadData().initializeIdentifierTable(globalData->identifierTable);
211 return adoptRef(globalData);
212}
213
214PassRefPtr<JSGlobalData> JSGlobalData::createLeaked(ThreadStackType type)
215{
216 Structure::startIgnoringLeaks();
217 RefPtr<JSGlobalData> data = create(type);
218 Structure::stopIgnoringLeaks();
219 return data.release();
220}
221
222bool JSGlobalData::sharedInstanceExists()
223{
224 return sharedInstanceInternal();
225}
226
227JSGlobalData& JSGlobalData::sharedInstance()
228{
229 JSGlobalData*& instance = sharedInstanceInternal();
230 if (!instance) {
231 instance = new JSGlobalData(true, ThreadStackTypeSmall);
232#if ENABLE(JSC_MULTIPLE_THREADS)
233 instance->makeUsableFromMultipleThreads();
234#endif
235 }
236 return *instance;
237}
238
239JSGlobalData*& JSGlobalData::sharedInstanceInternal()
240{
241 ASSERT(JSLock::currentThreadIsHoldingLock());
242 static JSGlobalData* sharedInstance;
243 return sharedInstance;
244}
245
246// FIXME: We can also detect forms like v1 < v2 ? -1 : 0, reverse comparison, etc.
247const Vector<Instruction>& JSGlobalData::numericCompareFunction(ExecState* exec)
248{
249 if (!lazyNumericCompareFunction.size() && !initializingLazyNumericCompareFunction) {
250 initializingLazyNumericCompareFunction = true;
251 RefPtr<FunctionExecutable> function = FunctionExecutable::fromGlobalCode(Identifier(exec, "numericCompare"), exec, 0, makeSource(UString("(function (v1, v2) { return v1 - v2; })")), 0, 0);
252 lazyNumericCompareFunction = function->bytecode(exec, exec->scopeChain()).instructions();
253 initializingLazyNumericCompareFunction = false;
254 }
255
256 return lazyNumericCompareFunction;
257}
258
259JSGlobalData::ClientData::~ClientData()
260{
261}
262
263void JSGlobalData::resetDateCache()
264{
265 cachedUTCOffset = NaN;
266 dstOffsetCache.reset();
267 cachedDateString = UString();
268 dateInstanceCache.reset();
269}
270
271void JSGlobalData::startSampling()
272{
273 interpreter->startSampling();
274}
275
276void JSGlobalData::stopSampling()
277{
278 interpreter->stopSampling();
279}
280
281void JSGlobalData::dumpSampleData(ExecState* exec)
282{
283 interpreter->dumpSampleData(exec);
284}
285
286} // namespace JSC
Note: See TracBrowser for help on using the repository browser.