source: webkit/trunk/JavaScriptCore/kjs/JSGlobalObject.h@ 34810

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

Reviewed by Maciej.

Make JSGlobalData per-thread.

No change on SunSpider total.

  • wtf/ThreadSpecific.h: Re-enabled the actual implementation.
  • kjs/JSGlobalObject.cpp: (KJS::JSGlobalObject::~JSGlobalObject): Re-added a JSLock-related assertion. We'll probably want to preserve these somehow to keep legacy behavior in working condition. (KJS::JSGlobalObject::init): Initialize globalData pointer earlier, so that it is ready when updating JSGlobalObject linked list.
  • kjs/JSGlobalObject.h: (KJS::JSGlobalObject::head): Changed head() to be non-static, and to use JSGlobalData associated with the current object.
  • kjs/InitializeThreading.cpp: (KJS::initializeThreadingOnce): Removed a no longer needed Heap::registerAsMainThread() call.
  • kjs/JSGlobalData.h: Removed a lying lie comment - parserObjectExtraRefCounts is not transient, and while newParserObjects may conceptually be such, there is still some node manipulation going on outside Parser::parse which touches it.
  • kjs/JSGlobalData.cpp: (KJS::JSGlobalData::~JSGlobalData): Delete recently added members. (KJS::JSGlobalData::sharedInstance): Actually use a separate instance.
  • kjs/collector.cpp: (KJS::Heap::Heap): (KJS::Heap::~Heap): Added a destructor, which unconditionally deletes everything. (KJS::Heap::sweep): Removed code related to "collect on main thread only" logic. (KJS::Heap::collect): Ditto. (KJS::Heap::globalObjectCount): Explicitly use per-thread instance of JSGlobalObject linked list now that JSGlobalObject::head() is not static. Curently, WebCoreStatistics methods only work with the main thread currently anyway. (KJS::Heap::protectedGlobalObjectCount): Ditto.
  • kjs/collector.h: Removed code related to "collect on main thread only" logic.
  • Property svn:eol-style set to native
File size: 12.4 KB
Line 
1// -*- c-basic-offset: 4 -*-
2/*
3 * Copyright (C) 2007 Eric Seidel <[email protected]>
4 * Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public License
17 * along with this library; see the file COPYING.LIB. If not, write to
18 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 * Boston, MA 02110-1301, USA.
20 *
21 */
22
23#ifndef KJS_GlobalObject_h
24#define KJS_GlobalObject_h
25
26#include "JSGlobalData.h"
27#include "JSVariableObject.h"
28#include "RegisterFile.h"
29#include "RegisterFileStack.h"
30#include <wtf/HashSet.h>
31#include <wtf/OwnPtr.h>
32
33namespace KJS {
34
35 class ArrayPrototype;
36 class BooleanPrototype;
37 class DatePrototype;
38 class Debugger;
39 class ErrorConstructor;
40 class ErrorPrototype;
41 class EvalError;
42 class EvalErrorPrototype;
43 class FunctionPrototype;
44 class GlobalEvalFunction;
45 class JSGlobalObject;
46 class NativeErrorConstructor;
47 class NativeErrorPrototype;
48 class NumberPrototype;
49 class ObjectPrototype;
50 class ProgramCodeBlock;
51 class RangeError;
52 class RangeErrorPrototype;
53 class ReferenceError;
54 class ReferenceError;
55 class ReferenceErrorPrototype;
56 class RegExpConstructor;
57 class RegExpPrototype;
58 class RuntimeMethod;
59 class ScopeChain;
60 class StringPrototype;
61 class SyntaxErrorPrototype;
62 class TypeError;
63 class TypeErrorPrototype;
64 class UriError;
65 class UriErrorPrototype;
66
67 struct ActivationStackNode;
68 struct HashTable;
69
70 typedef Vector<ExecState*, 16> ExecStateStack;
71
72 class JSGlobalObject : public JSVariableObject {
73 protected:
74 using JSVariableObject::JSVariableObjectData;
75
76 struct JSGlobalObjectData : public JSVariableObjectData {
77 JSGlobalObjectData(JSGlobalObject* globalObject, JSObject* thisValue)
78 : JSVariableObjectData(&symbolTable, registerFileStack.globalBasePointer(), 0)
79 , globalScopeChain(globalObject, thisValue)
80 {
81 }
82
83 JSGlobalObject* next;
84 JSGlobalObject* prev;
85
86 Debugger* debugger;
87
88 RegisterFileStack registerFileStack;
89 ScopeChain globalScopeChain;
90 OwnPtr<ExecState> globalExec;
91
92 int recursion;
93
94 unsigned timeoutTime;
95 unsigned timeAtLastCheckTimeout;
96 unsigned timeExecuting;
97 unsigned timeoutCheckCount;
98 unsigned tickCount;
99 unsigned ticksUntilNextTimeoutCheck;
100
101 RegExpConstructor* regExpConstructor;
102 ErrorConstructor* errorConstructor;
103 NativeErrorConstructor* evalErrorConstructor;
104 NativeErrorConstructor* rangeErrorConstructor;
105 NativeErrorConstructor* referenceErrorConstructor;
106 NativeErrorConstructor* syntaxErrorConstructor;
107 NativeErrorConstructor* typeErrorConstructor;
108 NativeErrorConstructor* URIErrorConstructor;
109
110 GlobalEvalFunction* evalFunction;
111
112 ObjectPrototype* objectPrototype;
113 FunctionPrototype* functionPrototype;
114 ArrayPrototype* arrayPrototype;
115 BooleanPrototype* booleanPrototype;
116 StringPrototype* stringPrototype;
117 NumberPrototype* numberPrototype;
118 DatePrototype* datePrototype;
119 RegExpPrototype* regExpPrototype;
120 ErrorPrototype* errorPrototype;
121 NativeErrorPrototype* evalErrorPrototype;
122 NativeErrorPrototype* rangeErrorPrototype;
123 NativeErrorPrototype* referenceErrorPrototype;
124 NativeErrorPrototype* syntaxErrorPrototype;
125 NativeErrorPrototype* typeErrorPrototype;
126 NativeErrorPrototype* URIErrorPrototype;
127
128 SymbolTable symbolTable;
129 unsigned pageGroupIdentifier;
130
131 JSGlobalData* globalData;
132
133 HashSet<ProgramCodeBlock*> codeBlocks;
134
135 OwnPtr<HashSet<JSObject*> > arrayVisitedElements; // Global data shared by array prototype functions.
136 };
137
138 public:
139 JSGlobalObject()
140 : JSVariableObject(new JSGlobalObjectData(this, this))
141 {
142 init(this);
143 }
144
145 protected:
146 JSGlobalObject(JSValue* prototype, JSObject* globalThisValue)
147 : JSVariableObject(prototype, new JSGlobalObjectData(this, globalThisValue))
148 {
149 init(globalThisValue);
150 }
151
152 public:
153 virtual ~JSGlobalObject();
154
155 virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&);
156 virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&, bool& slotIsWriteable);
157 virtual void put(ExecState*, const Identifier&, JSValue*);
158 virtual void putWithAttributes(ExecState*, const Identifier& propertyName, JSValue* value, unsigned attributes);
159
160 virtual void defineGetter(ExecState*, const Identifier& propertyName, JSObject* getterFunc);
161 virtual void defineSetter(ExecState*, const Identifier& propertyName, JSObject* setterFunc);
162
163 // Per-thread linked list of all global objects.
164 JSGlobalObject*& head() { return d()->globalData->head; }
165 JSGlobalObject* next() { return d()->next; }
166
167 // Resets the global object to contain only built-in properties, sets
168 // the global object's prototype to "prototype," then adds the
169 // default object prototype to the tail of the global object's
170 // prototype chain.
171 void reset(JSValue* prototype);
172
173 // The following accessors return pristine values, even if a script
174 // replaces the global object's associated property.
175
176 RegExpConstructor* regExpConstructor() const { return d()->regExpConstructor; }
177
178 ErrorConstructor* errorConstructor() const { return d()->errorConstructor; }
179 NativeErrorConstructor* evalErrorConstructor() const { return d()->evalErrorConstructor; }
180 NativeErrorConstructor* rangeErrorConstructor() const { return d()->rangeErrorConstructor; }
181 NativeErrorConstructor* referenceErrorConstructor() const { return d()->referenceErrorConstructor; }
182 NativeErrorConstructor* syntaxErrorConstructor() const { return d()->syntaxErrorConstructor; }
183 NativeErrorConstructor* typeErrorConstructor() const { return d()->typeErrorConstructor; }
184 NativeErrorConstructor* URIErrorConstructor() const { return d()->URIErrorConstructor; }
185
186 GlobalEvalFunction* evalFunction() const { return d()->evalFunction; }
187
188 ObjectPrototype* objectPrototype() const { return d()->objectPrototype; }
189 FunctionPrototype* functionPrototype() const { return d()->functionPrototype; }
190 ArrayPrototype* arrayPrototype() const { return d()->arrayPrototype; }
191 BooleanPrototype* booleanPrototype() const { return d()->booleanPrototype; }
192 StringPrototype* stringPrototype() const { return d()->stringPrototype; }
193 NumberPrototype* numberPrototype() const { return d()->numberPrototype; }
194 DatePrototype* datePrototype() const { return d()->datePrototype; }
195 RegExpPrototype* regExpPrototype() const { return d()->regExpPrototype; }
196 ErrorPrototype* errorPrototype() const { return d()->errorPrototype; }
197 NativeErrorPrototype* evalErrorPrototype() const { return d()->evalErrorPrototype; }
198 NativeErrorPrototype* rangeErrorPrototype() const { return d()->rangeErrorPrototype; }
199 NativeErrorPrototype* referenceErrorPrototype() const { return d()->referenceErrorPrototype; }
200 NativeErrorPrototype* syntaxErrorPrototype() const { return d()->syntaxErrorPrototype; }
201 NativeErrorPrototype* typeErrorPrototype() const { return d()->typeErrorPrototype; }
202 NativeErrorPrototype* URIErrorPrototype() const { return d()->URIErrorPrototype; }
203
204 void setPageGroupIdentifier(unsigned value) { d()->pageGroupIdentifier = value; }
205 unsigned pageGroupIdentifier() const { return d()->pageGroupIdentifier; }
206
207 void setTimeoutTime(unsigned timeoutTime) { d()->timeoutTime = timeoutTime; }
208 void startTimeoutCheck();
209 void stopTimeoutCheck();
210 bool timedOut();
211
212 Debugger* debugger() const { return d()->debugger; }
213 void setDebugger(Debugger* debugger) { d()->debugger = debugger; }
214
215 int recursion() { return d()->recursion; }
216 void incRecursion() { ++d()->recursion; }
217 void decRecursion() { --d()->recursion; }
218
219 ScopeChain& globalScopeChain() { return d()->globalScopeChain; }
220
221 virtual void mark();
222
223 virtual bool isGlobalObject() const { return true; }
224 virtual JSGlobalObject* toGlobalObject(ExecState*) const;
225
226 virtual ExecState* globalExec();
227
228 virtual bool shouldInterruptScript() const { return true; }
229
230 virtual bool allowsAccessFrom(const JSGlobalObject*) const { return true; }
231
232 virtual bool isDynamicScope() const;
233
234 HashSet<JSObject*>& arrayVisitedElements() { if (!d()->arrayVisitedElements) d()->arrayVisitedElements.set(new HashSet<JSObject*>); return *d()->arrayVisitedElements; }
235
236 HashSet<ProgramCodeBlock*>& codeBlocks() { return d()->codeBlocks; }
237
238 RegisterFileStack& registerFileStack() { return d()->registerFileStack; }
239
240 // Per-thread hash tables, cached on the global object for faster access.
241 JSGlobalData* globalData() { return d()->globalData; }
242
243 enum SharedTag { Shared };
244 void* operator new(size_t);
245 void* operator new(size_t, SharedTag);
246
247 void init(JSObject* thisValue);
248
249 JSGlobalObjectData* d() const { return static_cast<JSGlobalObjectData*>(JSVariableObject::d); }
250
251 protected:
252 struct GlobalPropertyInfo {
253 GlobalPropertyInfo(const Identifier& i, JSValue* v, unsigned a)
254 : identifier(i)
255 , value(v)
256 , attributes(a)
257 {
258 }
259
260 const Identifier identifier;
261 JSValue* value;
262 unsigned attributes;
263 };
264 void addStaticGlobals(GlobalPropertyInfo*, int count);
265
266 private:
267 bool checkTimeout();
268 void resetTimeoutCheck();
269 };
270
271 inline void JSGlobalObject::addStaticGlobals(GlobalPropertyInfo* globals, int count)
272 {
273 RegisterFile* registerFile = registerFileStack().current();
274 ASSERT(registerFile->safeForReentry() && registerFile->isGlobal() && !registerFile->size());
275 int index = -registerFile->numGlobalSlots() - 1;
276 registerFile->addGlobalSlots(count);
277 for (int i = 0; i < count; ++i) {
278 ASSERT(globals[i].attributes & DontDelete);
279 SymbolTableEntry newEntry(index, globals[i].attributes);
280 symbolTable().add(globals[i].identifier.ustring().rep(), newEntry);
281 valueAt(index) = globals[i].value;
282 --index;
283 }
284 }
285
286 inline bool JSGlobalObject::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
287 {
288 if (JSVariableObject::getOwnPropertySlot(exec, propertyName, slot))
289 return true;
290 return symbolTableGet(propertyName, slot);
291 }
292
293 inline bool JSGlobalObject::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot, bool& slotIsWriteable)
294 {
295 if (JSVariableObject::getOwnPropertySlotForWrite(exec, propertyName, slot, slotIsWriteable))
296 return true;
297 return symbolTableGet(propertyName, slot, slotIsWriteable);
298 }
299
300 inline bool JSGlobalObject::timedOut()
301 {
302 d()->tickCount++;
303
304 if (d()->tickCount != d()->ticksUntilNextTimeoutCheck)
305 return false;
306
307 return checkTimeout();
308 }
309
310 inline JSGlobalObject* ScopeChainNode::globalObject() const
311 {
312 JSGlobalObject* globalObject = static_cast<JSGlobalObject*>(bottom());
313 ASSERT(globalObject->isGlobalObject());
314 return globalObject;
315 }
316
317} // namespace KJS
318
319#endif // KJS_GlobalObject_h
Note: See TracBrowser for help on using the repository browser.