2 * Copyright (C) 2008 Apple Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
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.
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.
30 #include "JSGlobalData.h"
33 #include "Collector.h"
34 #include "CommonIdentifiers.h"
35 #include "FunctionConstructor.h"
36 #include "Interpreter.h"
37 #include "JSActivation.h"
39 #include "JSByteArray.h"
40 #include "JSClassRef.h"
41 #include "JSFunction.h"
43 #include "JSNotAnObject.h"
44 #include "JSStaticScopeObject.h"
50 #if ENABLE(JSC_MULTIPLE_THREADS)
51 #include <wtf/Threading.h>
55 #include "ProfilerServer.h"
62 extern JSC_CONST_HASHTABLE HashTable arrayTable
;
63 extern JSC_CONST_HASHTABLE HashTable jsonTable
;
64 extern JSC_CONST_HASHTABLE HashTable dateTable
;
65 extern JSC_CONST_HASHTABLE HashTable mathTable
;
66 extern JSC_CONST_HASHTABLE HashTable numberTable
;
67 extern JSC_CONST_HASHTABLE HashTable regExpTable
;
68 extern JSC_CONST_HASHTABLE HashTable regExpConstructorTable
;
69 extern JSC_CONST_HASHTABLE HashTable stringTable
;
75 void* jsByteArrayVPtr
;
82 // Bizarrely, calling fastMalloc here is faster than allocating space on the stack.
83 void* storage
= fastMalloc(sizeof(CollectorBlock
));
85 JSCell
* jsArray
= new (storage
) JSArray(JSArray::createStructure(jsNull()));
86 jsArrayVPtr
= jsArray
->vptr();
89 JSCell
* jsByteArray
= new (storage
) JSByteArray(JSByteArray::VPtrStealingHack
);
90 jsByteArrayVPtr
= jsByteArray
->vptr();
91 jsByteArray
->~JSCell();
93 JSCell
* jsString
= new (storage
) JSString(JSString::VPtrStealingHack
);
94 jsStringVPtr
= jsString
->vptr();
97 JSCell
* jsFunction
= new (storage
) JSFunction(JSFunction::createStructure(jsNull()));
98 jsFunctionVPtr
= jsFunction
->vptr();
99 jsFunction
->~JSCell();
104 JSGlobalData::JSGlobalData(bool isShared
, const VPtrSet
& vptrSet
)
105 : isSharedInstance(isShared
)
107 , arrayTable(fastNew
<HashTable
>(JSC::arrayTable
))
108 , dateTable(fastNew
<HashTable
>(JSC::dateTable
))
109 , jsonTable(fastNew
<HashTable
>(JSC::jsonTable
))
110 , mathTable(fastNew
<HashTable
>(JSC::mathTable
))
111 , numberTable(fastNew
<HashTable
>(JSC::numberTable
))
112 , regExpTable(fastNew
<HashTable
>(JSC::regExpTable
))
113 , regExpConstructorTable(fastNew
<HashTable
>(JSC::regExpConstructorTable
))
114 , stringTable(fastNew
<HashTable
>(JSC::stringTable
))
115 , activationStructure(JSActivation::createStructure(jsNull()))
116 , interruptedExecutionErrorStructure(JSObject::createStructure(jsNull()))
117 , staticScopeStructure(JSStaticScopeObject::createStructure(jsNull()))
118 , stringStructure(JSString::createStructure(jsNull()))
119 , notAnObjectErrorStubStructure(JSNotAnObjectErrorStub::createStructure(jsNull()))
120 , notAnObjectStructure(JSNotAnObject::createStructure(jsNull()))
122 , numberStructure(JSNumberCell::createStructure(jsNull()))
124 , jsArrayVPtr(vptrSet
.jsArrayVPtr
)
125 , jsByteArrayVPtr(vptrSet
.jsByteArrayVPtr
)
126 , jsStringVPtr(vptrSet
.jsStringVPtr
)
127 , jsFunctionVPtr(vptrSet
.jsFunctionVPtr
)
128 , identifierTable(createIdentifierTable())
129 , propertyNames(new CommonIdentifiers(this))
130 , emptyList(new MarkedArgumentBuffer
)
131 , lexer(new Lexer(this))
133 , interpreter(new Interpreter
)
138 , initializingLazyNumericCompareFunction(false)
140 , dynamicGlobalObject(0)
141 , scopeNodeBeingReparsed(0)
142 , firstStringifierToMark(0)
145 startProfilerServerIfNeeded();
149 JSGlobalData::~JSGlobalData()
151 // By the time this is destroyed, heap.destroy() must already have been called.
155 // Zeroing out to make the behavior more predictable when someone attempts to use a deleted instance.
159 arrayTable
->deleteTable();
160 dateTable
->deleteTable();
161 jsonTable
->deleteTable();
162 mathTable
->deleteTable();
163 numberTable
->deleteTable();
164 regExpTable
->deleteTable();
165 regExpConstructorTable
->deleteTable();
166 stringTable
->deleteTable();
168 fastDelete(const_cast<HashTable
*>(arrayTable
));
169 fastDelete(const_cast<HashTable
*>(dateTable
));
170 fastDelete(const_cast<HashTable
*>(jsonTable
));
171 fastDelete(const_cast<HashTable
*>(mathTable
));
172 fastDelete(const_cast<HashTable
*>(numberTable
));
173 fastDelete(const_cast<HashTable
*>(regExpTable
));
174 fastDelete(const_cast<HashTable
*>(regExpConstructorTable
));
175 fastDelete(const_cast<HashTable
*>(stringTable
));
180 deleteAllValues(opaqueJSClassData
);
184 delete propertyNames
;
185 deleteIdentifierTable(identifierTable
);
190 PassRefPtr
<JSGlobalData
> JSGlobalData::create(bool isShared
)
192 return adoptRef(new JSGlobalData(isShared
, VPtrSet()));
195 PassRefPtr
<JSGlobalData
> JSGlobalData::createLeaked()
197 Structure::startIgnoringLeaks();
198 RefPtr
<JSGlobalData
> data
= create();
199 Structure::stopIgnoringLeaks();
200 return data
.release();
203 bool JSGlobalData::sharedInstanceExists()
205 return sharedInstanceInternal();
208 JSGlobalData
& JSGlobalData::sharedInstance()
210 JSGlobalData
*& instance
= sharedInstanceInternal();
212 instance
= create(true).releaseRef();
213 #if ENABLE(JSC_MULTIPLE_THREADS)
214 instance
->makeUsableFromMultipleThreads();
220 JSGlobalData
*& JSGlobalData::sharedInstanceInternal()
222 ASSERT(JSLock::currentThreadIsHoldingLock());
223 static JSGlobalData
* sharedInstance
;
224 return sharedInstance
;
227 // FIXME: We can also detect forms like v1 < v2 ? -1 : 0, reverse comparison, etc.
228 const Vector
<Instruction
>& JSGlobalData::numericCompareFunction(ExecState
* exec
)
230 if (!lazyNumericCompareFunction
.size() && !initializingLazyNumericCompareFunction
) {
231 initializingLazyNumericCompareFunction
= true;
232 RefPtr
<ProgramNode
> programNode
= parser
->parse
<ProgramNode
>(exec
, 0, makeSource(UString("(function (v1, v2) { return v1 - v2; })")), 0, 0);
233 RefPtr
<FunctionBodyNode
> functionBody
= extractFunctionBody(programNode
.get());
234 lazyNumericCompareFunction
= functionBody
->bytecode(exec
->scopeChain()).instructions();
235 initializingLazyNumericCompareFunction
= false;
238 return lazyNumericCompareFunction
;
241 JSGlobalData::ClientData::~ClientData()