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

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

2010-09-09 Michael Saboff <[email protected]>

Reviewed by Gavin Barraclough.

Added a regular expression tracing facility. This tracing is connected
to jsc. Every compiled regular expression object is added to a list.
When the process exits, each regular expression dumps its pattern,
JIT address, number of times it was executed and the number of matches.
This tracing is controlled by the macro ENABLE_REGEXP_TRACING in
wtf/Platform.h.
https://bugs.webkit.org/show_bug.cgi?id=45401

  • JavaScriptCore.exp:
  • jsc.cpp: (runWithScripts):
  • runtime/JSGlobalData.cpp: (JSC::JSGlobalData::JSGlobalData): (JSC::JSGlobalData::~JSGlobalData): (JSC::JSGlobalData::addRegExpToTrace): (JSC::JSGlobalData::dumpRegExpTrace):
  • runtime/JSGlobalData.h:
  • runtime/RegExp.cpp: (JSC::RegExp::RegExp): (JSC::RegExp::create): (JSC::RegExp::match):
  • runtime/RegExp.h:
  • wtf/Platform.h:
  • yarr/RegexJIT.h: (JSC::Yarr::RegexCodeBlock::getAddr):

2010-09-09 Michael Saboff <[email protected]>

Reviewed by Gavin Barraclough.

Added ListHashSet.h as an exported header in support of RegExp tracing.
https://bugs.webkit.org/show_bug.cgi?id=45401

  • ForwardingHeaders/wtf/ListHashSet.h: Added.
  • Property svn:eol-style set to native
File size: 11.2 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 "RegExpCache.h"
53#include <wtf/WTFThreadData.h>
54#if ENABLE(REGEXP_TRACING)
55#include "RegExp.h"
56#endif
57
58
59#if ENABLE(JSC_MULTIPLE_THREADS)
60#include <wtf/Threading.h>
61#endif
62
63#if PLATFORM(MAC)
64#include "ProfilerServer.h"
65#include <CoreFoundation/CoreFoundation.h>
66#endif
67
68using namespace WTF;
69
70namespace JSC {
71
72extern JSC_CONST_HASHTABLE HashTable arrayTable;
73extern JSC_CONST_HASHTABLE HashTable jsonTable;
74extern JSC_CONST_HASHTABLE HashTable dateTable;
75extern JSC_CONST_HASHTABLE HashTable mathTable;
76extern JSC_CONST_HASHTABLE HashTable numberTable;
77extern JSC_CONST_HASHTABLE HashTable regExpTable;
78extern JSC_CONST_HASHTABLE HashTable regExpConstructorTable;
79extern JSC_CONST_HASHTABLE HashTable stringTable;
80
81void* JSGlobalData::jsArrayVPtr;
82void* JSGlobalData::jsByteArrayVPtr;
83void* JSGlobalData::jsStringVPtr;
84void* JSGlobalData::jsFunctionVPtr;
85
86void JSGlobalData::storeVPtrs()
87{
88 CollectorCell cell;
89 void* storage = &cell;
90
91 COMPILE_ASSERT(sizeof(JSArray) <= sizeof(CollectorCell), sizeof_JSArray_must_be_less_than_CollectorCell);
92 JSCell* jsArray = new (storage) JSArray(JSArray::VPtrStealingHack);
93 JSGlobalData::jsArrayVPtr = jsArray->vptr();
94 jsArray->~JSCell();
95
96 COMPILE_ASSERT(sizeof(JSByteArray) <= sizeof(CollectorCell), sizeof_JSByteArray_must_be_less_than_CollectorCell);
97 JSCell* jsByteArray = new (storage) JSByteArray(JSByteArray::VPtrStealingHack);
98 JSGlobalData::jsByteArrayVPtr = jsByteArray->vptr();
99 jsByteArray->~JSCell();
100
101 COMPILE_ASSERT(sizeof(JSString) <= sizeof(CollectorCell), sizeof_JSString_must_be_less_than_CollectorCell);
102 JSCell* jsString = new (storage) JSString(JSString::VPtrStealingHack);
103 JSGlobalData::jsStringVPtr = jsString->vptr();
104 jsString->~JSCell();
105
106 COMPILE_ASSERT(sizeof(JSFunction) <= sizeof(CollectorCell), sizeof_JSFunction_must_be_less_than_CollectorCell);
107 JSCell* jsFunction = new (storage) JSFunction(JSFunction::createStructure(jsNull()));
108 JSGlobalData::jsFunctionVPtr = jsFunction->vptr();
109 jsFunction->~JSCell();
110}
111
112JSGlobalData::JSGlobalData(GlobalDataType globalDataType, ThreadStackType threadStackType)
113 : globalDataType(globalDataType)
114 , clientData(0)
115 , arrayTable(fastNew<HashTable>(JSC::arrayTable))
116 , dateTable(fastNew<HashTable>(JSC::dateTable))
117 , jsonTable(fastNew<HashTable>(JSC::jsonTable))
118 , mathTable(fastNew<HashTable>(JSC::mathTable))
119 , numberTable(fastNew<HashTable>(JSC::numberTable))
120 , regExpTable(fastNew<HashTable>(JSC::regExpTable))
121 , regExpConstructorTable(fastNew<HashTable>(JSC::regExpConstructorTable))
122 , stringTable(fastNew<HashTable>(JSC::stringTable))
123 , activationStructure(JSActivation::createStructure(jsNull()))
124 , interruptedExecutionErrorStructure(JSObject::createStructure(jsNull()))
125 , terminatedExecutionErrorStructure(JSObject::createStructure(jsNull()))
126 , staticScopeStructure(JSStaticScopeObject::createStructure(jsNull()))
127 , stringStructure(JSString::createStructure(jsNull()))
128 , notAnObjectErrorStubStructure(JSNotAnObjectErrorStub::createStructure(jsNull()))
129 , notAnObjectStructure(JSNotAnObject::createStructure(jsNull()))
130 , propertyNameIteratorStructure(JSPropertyNameIterator::createStructure(jsNull()))
131 , getterSetterStructure(GetterSetter::createStructure(jsNull()))
132 , apiWrapperStructure(JSAPIValueWrapper::createStructure(jsNull()))
133 , dummyMarkableCellStructure(JSCell::createDummyStructure())
134#if USE(JSVALUE32)
135 , numberStructure(JSNumberCell::createStructure(jsNull()))
136#endif
137 , identifierTable(globalDataType == Default ? wtfThreadData().currentIdentifierTable() : createIdentifierTable())
138 , propertyNames(new CommonIdentifiers(this))
139 , emptyList(new MarkedArgumentBuffer)
140 , lexer(new Lexer(this))
141 , parser(new Parser)
142 , interpreter(new Interpreter)
143 , heap(this)
144 , head(0)
145 , dynamicGlobalObject(0)
146 , functionCodeBlockBeingReparsed(0)
147 , firstStringifierToMark(0)
148 , markStack(jsArrayVPtr)
149 , cachedUTCOffset(NaN)
150 , maxReentryDepth(threadStackType == ThreadStackTypeSmall ? MaxSmallThreadReentryDepth : MaxLargeThreadReentryDepth)
151 , m_regExpCache(new RegExpCache(this))
152#if ENABLE(REGEXP_TRACING)
153 , m_rtTraceList(new RTTraceList())
154#endif
155#ifndef NDEBUG
156 , exclusiveThread(0)
157#endif
158{
159#if PLATFORM(MAC)
160 startProfilerServerIfNeeded();
161#endif
162#if ENABLE(JIT) && ENABLE(INTERPRETER)
163#if PLATFORM(CF)
164 CFStringRef canUseJITKey = CFStringCreateWithCString(0 , "JavaScriptCoreUseJIT", kCFStringEncodingMacRoman);
165 CFBooleanRef canUseJIT = (CFBooleanRef)CFPreferencesCopyAppValue(canUseJITKey, kCFPreferencesCurrentApplication);
166 if (canUseJIT) {
167 m_canUseJIT = kCFBooleanTrue == canUseJIT;
168 CFRelease(canUseJIT);
169 } else
170 m_canUseJIT = !getenv("JavaScriptCoreUseJIT");
171 CFRelease(canUseJITKey);
172#elif OS(UNIX)
173 m_canUseJIT = !getenv("JavaScriptCoreUseJIT");
174#else
175 m_canUseJIT = true;
176#endif
177#endif
178#if ENABLE(JIT)
179#if ENABLE(INTERPRETER)
180 if (m_canUseJIT)
181 m_canUseJIT = executableAllocator.isValid();
182#endif
183 jitStubs = new JITThunks(this);
184#endif
185}
186
187JSGlobalData::~JSGlobalData()
188{
189 // By the time this is destroyed, heap.destroy() must already have been called.
190
191 delete interpreter;
192#ifndef NDEBUG
193 // Zeroing out to make the behavior more predictable when someone attempts to use a deleted instance.
194 interpreter = 0;
195#endif
196
197 arrayTable->deleteTable();
198 dateTable->deleteTable();
199 jsonTable->deleteTable();
200 mathTable->deleteTable();
201 numberTable->deleteTable();
202 regExpTable->deleteTable();
203 regExpConstructorTable->deleteTable();
204 stringTable->deleteTable();
205
206 fastDelete(const_cast<HashTable*>(arrayTable));
207 fastDelete(const_cast<HashTable*>(dateTable));
208 fastDelete(const_cast<HashTable*>(jsonTable));
209 fastDelete(const_cast<HashTable*>(mathTable));
210 fastDelete(const_cast<HashTable*>(numberTable));
211 fastDelete(const_cast<HashTable*>(regExpTable));
212 fastDelete(const_cast<HashTable*>(regExpConstructorTable));
213 fastDelete(const_cast<HashTable*>(stringTable));
214
215 delete parser;
216 delete lexer;
217
218 deleteAllValues(opaqueJSClassData);
219
220 delete emptyList;
221
222 delete propertyNames;
223 if (globalDataType != Default)
224 deleteIdentifierTable(identifierTable);
225
226 delete clientData;
227 delete m_regExpCache;
228#if ENABLE(REGEXP_TRACING)
229 delete m_rtTraceList;
230#endif
231}
232
233PassRefPtr<JSGlobalData> JSGlobalData::createContextGroup(ThreadStackType type)
234{
235 return adoptRef(new JSGlobalData(APIContextGroup, type));
236}
237
238PassRefPtr<JSGlobalData> JSGlobalData::create(ThreadStackType type)
239{
240 return adoptRef(new JSGlobalData(Default, type));
241}
242
243PassRefPtr<JSGlobalData> JSGlobalData::createLeaked(ThreadStackType type)
244{
245 Structure::startIgnoringLeaks();
246 RefPtr<JSGlobalData> data = create(type);
247 Structure::stopIgnoringLeaks();
248 return data.release();
249}
250
251bool JSGlobalData::sharedInstanceExists()
252{
253 return sharedInstanceInternal();
254}
255
256JSGlobalData& JSGlobalData::sharedInstance()
257{
258 JSGlobalData*& instance = sharedInstanceInternal();
259 if (!instance) {
260 instance = adoptRef(new JSGlobalData(APIShared, ThreadStackTypeSmall)).leakRef();
261#if ENABLE(JSC_MULTIPLE_THREADS)
262 instance->makeUsableFromMultipleThreads();
263#endif
264 }
265 return *instance;
266}
267
268JSGlobalData*& JSGlobalData::sharedInstanceInternal()
269{
270 ASSERT(JSLock::currentThreadIsHoldingLock());
271 static JSGlobalData* sharedInstance;
272 return sharedInstance;
273}
274
275#if ENABLE(JIT)
276PassRefPtr<NativeExecutable> JSGlobalData::getHostFunction(NativeFunction function)
277{
278 return jitStubs->hostFunctionStub(this, function);
279}
280PassRefPtr<NativeExecutable> JSGlobalData::getHostFunction(NativeFunction function, ThunkGenerator generator)
281{
282 return jitStubs->hostFunctionStub(this, function, generator);
283}
284#endif
285
286JSGlobalData::ClientData::~ClientData()
287{
288}
289
290void JSGlobalData::resetDateCache()
291{
292 cachedUTCOffset = NaN;
293 dstOffsetCache.reset();
294 cachedDateString = UString();
295 cachedDateStringValue = NaN;
296 dateInstanceCache.reset();
297}
298
299void JSGlobalData::startSampling()
300{
301 interpreter->startSampling();
302}
303
304void JSGlobalData::stopSampling()
305{
306 interpreter->stopSampling();
307}
308
309void JSGlobalData::dumpSampleData(ExecState* exec)
310{
311 interpreter->dumpSampleData(exec);
312}
313
314
315#if ENABLE(REGEXP_TRACING)
316void JSGlobalData::addRegExpToTrace(PassRefPtr<RegExp> regExp)
317{
318 m_rtTraceList->add(regExp);
319}
320
321void JSGlobalData::dumpRegExpTrace()
322{
323 // The first RegExp object is ignored. It is create by the RegExpPrototype ctor and not used.
324 RTTraceList::iterator iter = ++m_rtTraceList->begin();
325
326 if (iter != m_rtTraceList->end()) {
327 printf("\nRegExp Tracing\n");
328 printf(" match() matches\n");
329 printf("Regular Expression JIT Address calls found\n");
330 printf("----------------------------------------+----------------+----------+----------\n");
331
332 unsigned reCount = 0;
333
334 for (; iter != m_rtTraceList->end(); ++iter, ++reCount)
335 (*iter)->printTraceData();
336
337 printf("%d Regular Expressions\n", reCount);
338 }
339
340 m_rtTraceList->clear();
341}
342#else
343void JSGlobalData::dumpRegExpTrace()
344{
345}
346#endif
347
348} // namespace JSC
Note: See TracBrowser for help on using the repository browser.