source: webkit/trunk/JavaScriptCore/kjs/JSGlobalObject.cpp@ 34838

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

JavaScriptCore:

2008-06-27 Geoffrey Garen <[email protected]>

Reviewed by Oliver Hunt.


One RegisterFile to rule them all!


SunSpider reports a 0.2% speedup.

This patch removes the RegisterFileStack abstraction and replaces it with
a single register file that


(a) allocates a fixed storage area, including a fixed area for global
vars, so that no operation may cause the register file to reallocate


and

(b) swaps between global storage areas when executing code in different
global objects.


This patch also changes the layout of the register file so that all call
frames, including call frames for global code, get a header. This is
required to support re-entrant global code. It also just makes things simpler.


  • VM/CodeGenerator.cpp: (KJS::CodeGenerator::addGlobalVar): New function. Differs from addVar in that


(a) global vars don't contribute to a CodeBlock's numLocals count, since
global storage is fixed and allocated at startup


and


(b) references to global vars get shifted to elide intermediate stack
between "r" and the global storage area.


  • VM/Machine.cpp: (KJS::Machine::dumpRegisters): Updated this function to match the new register file layout, and added the ability to dump exact identifiers for the different parts of a call frame.


(KJS::Machine::unwindCallFrame): Updated this function to match the new
register file layout.


(KJS::Machine::execute): Updated this function to initialize a call frame
header for global code, and to swap global storage areas when switching
to execution in a new global object.


(KJS::Machine::privateExecute): Got rid of "safeForReentry" and re-reading
of registerBase because the register file is always safe for reentry now,
and registerBase never changes.


  • VM/Machine.h: Moved the call frame header enum from Machine to RegisterFile, to resolve a header dependency problem (a good sign that the enum belonged in RegisterFile all along!)
  • VM/RegisterFile.cpp:
  • VM/RegisterFile.h: Changed RegisterFile to mmap a fixed size register area. This allows us to avoid re-allocting the register file later on. Instead, we rely on the OS to allocate physical pages to the register file as necessary.
  • VM/RegisterFileStack.cpp: Removed. Tada!
  • VM/RegisterFileStack.h: Removed. Tada!
  • kjs/DebuggerCallFrame.cpp: Updated this class to match the new register file layout, greatly simplifying it in the process.
  • kjs/JSActivation.h:
  • kjs/JSActivation.cpp: Moved some of this logic up to JSVariableObject, since the global object now needs to be able to tear off its registers just like the activation object.
  • kjs/JSFunction.cpp: No need to fiddle with the register file anymore.
  • kjs/JSGlobalObject.h:
  • kjs/JSGlobalObject.cpp: Updated JSGlobalObject to support moving its global storage area into and out of the register file.
  • kjs/PropertySlot.cpp: No need to fiddle with the register file anymore.
  • kjs/collector.cpp: Renamed markStackObjectConservatively to markConservatively, since we don't just mark stack objects this way.


Also, added code to mark the machine's register file.

  • kjs/config.h: Moved some platforms #defines from here...
  • wtf/Platform.h: ...to here, to support mmap/VirtualAlloc detection in RegisterFile.h.

LayoutTests:

2008-06-26 Geoffrey Garen <[email protected]>

Reviewed by Oliver Hunt.


Added a test for what happens when a script exceeds the limit on declared
global variables.

  • fast/js/global-var-limit-expected.txt: Added.
  • fast/js/global-var-limit.html: Added.
  • fast/js/global-recursion-on-full-stack-expected.txt: Updated for new (slightly more correct) behavior. Since the stack overflow happens in the middle of a try/catch block, it should be caught, instead of logged to the console.
  • Property svn:eol-style set to native
File size: 20.6 KB
Line 
1/*
2 * Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
3 * Copyright (C) 2008 Cameron Zwarich ([email protected])
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
15 * its contributors may be used to endorse or promote products derived
16 * from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
19 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
22 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
25 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30#include "config.h"
31#include "JSGlobalObject.h"
32
33#include "CodeBlock.h"
34#include "ArrayPrototype.h"
35#include "BooleanObject.h"
36#include "date_object.h"
37#include "debugger.h"
38#include "error_object.h"
39#include "FunctionPrototype.h"
40#include "MathObject.h"
41#include "NumberObject.h"
42#include "object_object.h"
43#include "RegExpObject.h"
44#include "ScopeChainMark.h"
45#include "string_object.h"
46
47#if HAVE(SYS_TIME_H)
48#include <sys/time.h>
49#endif
50
51#if PLATFORM(WIN_OS)
52#include <windows.h>
53#endif
54
55#if PLATFORM(QT)
56#include <QDateTime>
57#endif
58
59namespace KJS {
60
61// Default number of ticks before a timeout check should be done.
62static const int initialTickCountThreshold = 255;
63
64// Preferred number of milliseconds between each timeout check
65static const int preferredScriptCheckTimeInterval = 1000;
66
67static inline void markIfNeeded(JSValue* v)
68{
69 if (v && !v->marked())
70 v->mark();
71}
72
73// Returns the current time in milliseconds
74// It doesn't matter what "current time" is here, just as long as
75// it's possible to measure the time difference correctly.
76static inline unsigned getCurrentTime()
77{
78#if HAVE(SYS_TIME_H)
79 struct timeval tv;
80 gettimeofday(&tv, 0);
81 return tv.tv_sec * 1000 + tv.tv_usec / 1000;
82#elif PLATFORM(QT)
83 QDateTime t = QDateTime::currentDateTime();
84 return t.toTime_t() * 1000 + t.time().msec();
85#elif PLATFORM(WIN_OS)
86 return timeGetTime();
87#else
88#error Platform does not have getCurrentTime function
89#endif
90}
91
92JSGlobalObject::~JSGlobalObject()
93{
94 ASSERT(JSLock::currentThreadIsHoldingLock());
95
96 if (d()->debugger)
97 d()->debugger->detach(this);
98
99 d()->next->d()->prev = d()->prev;
100 d()->prev->d()->next = d()->next;
101 JSGlobalObject*& headObject = head();
102 if (headObject == this)
103 headObject = d()->next;
104 if (headObject == this)
105 headObject = 0;
106
107 HashSet<ProgramCodeBlock*>::const_iterator end = codeBlocks().end();
108 for (HashSet<ProgramCodeBlock*>::const_iterator it = codeBlocks().begin(); it != end; ++it)
109 (*it)->globalObject = 0;
110
111 RegisterFile& registerFile = globalData()->machine->registerFile();
112 if (registerFile.globalObject() == this) {
113 registerFile.setGlobalObject(0);
114 registerFile.setNumGlobals(0);
115 }
116 delete d();
117}
118
119void JSGlobalObject::init(JSObject* thisValue)
120{
121 ASSERT(JSLock::currentThreadIsHoldingLock());
122
123 d()->globalData = (Heap::heap(this) == JSGlobalData::sharedInstance().heap) ? &JSGlobalData::sharedInstance() : &JSGlobalData::threadInstance();
124
125 if (JSGlobalObject*& headObject = head()) {
126 d()->prev = headObject;
127 d()->next = headObject->d()->next;
128 headObject->d()->next->d()->prev = this;
129 headObject->d()->next = this;
130 } else
131 headObject = d()->next = d()->prev = this;
132
133 resetTimeoutCheck();
134 d()->timeoutTime = 0;
135 d()->timeoutCheckCount = 0;
136
137 d()->recursion = 0;
138 d()->debugger = 0;
139
140 d()->globalExec.set(new ExecState(this, thisValue, d()->globalScopeChain.node()));
141
142 d()->pageGroupIdentifier = 0;
143
144 reset(prototype());
145}
146
147void JSGlobalObject::put(ExecState* exec, const Identifier& propertyName, JSValue* value)
148{
149 ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(this));
150
151 if (symbolTablePut(propertyName, value))
152 return;
153 return JSVariableObject::put(exec, propertyName, value);
154}
155
156void JSGlobalObject::putWithAttributes(ExecState* exec, const Identifier& propertyName, JSValue* value, unsigned attributes)
157{
158 if (symbolTablePutWithAttributes(propertyName, value, attributes))
159 return;
160
161 JSValue* valueBefore = getDirect(propertyName);
162 JSVariableObject::put(exec, propertyName, value);
163 if (!valueBefore) {
164 if (JSValue* valueAfter = getDirect(propertyName))
165 putDirect(propertyName, valueAfter, attributes);
166 }
167}
168
169void JSGlobalObject::defineGetter(ExecState* exec, const Identifier& propertyName, JSObject* getterFunc)
170{
171 PropertySlot slot;
172 if (!symbolTableGet(propertyName, slot))
173 JSVariableObject::defineGetter(exec, propertyName, getterFunc);
174}
175
176void JSGlobalObject::defineSetter(ExecState* exec, const Identifier& propertyName, JSObject* setterFunc)
177{
178 PropertySlot slot;
179 if (!symbolTableGet(propertyName, slot))
180 JSVariableObject::defineSetter(exec, propertyName, setterFunc);
181}
182
183static inline JSObject* lastInPrototypeChain(JSObject* object)
184{
185 JSObject* o = object;
186 while (o->prototype()->isObject())
187 o = static_cast<JSObject*>(o->prototype());
188 return o;
189}
190
191void JSGlobalObject::reset(JSValue* prototype)
192{
193 // Clear before inititalizing, to avoid calling mark() on stale pointers --
194 // which would be wasteful -- or uninitialized pointers -- which would be
195 // dangerous. (The allocations below may cause a GC.)
196
197 _prop.clear();
198 symbolTable().clear();
199
200 // Prototypes
201 d()->functionPrototype = 0;
202 d()->objectPrototype = 0;
203
204 d()->arrayPrototype = 0;
205 d()->stringPrototype = 0;
206 d()->booleanPrototype = 0;
207 d()->numberPrototype = 0;
208 d()->datePrototype = 0;
209 d()->regExpPrototype = 0;
210 d()->errorPrototype = 0;
211
212 d()->evalErrorPrototype = 0;
213 d()->rangeErrorPrototype = 0;
214 d()->referenceErrorPrototype = 0;
215 d()->syntaxErrorPrototype = 0;
216 d()->typeErrorPrototype = 0;
217 d()->URIErrorPrototype = 0;
218
219 // Constructors
220 d()->regExpConstructor = 0;
221 d()->errorConstructor = 0;
222
223 d()->evalErrorConstructor = 0;
224 d()->rangeErrorConstructor = 0;
225 d()->referenceErrorConstructor = 0;
226 d()->syntaxErrorConstructor = 0;
227 d()->typeErrorConstructor = 0;
228 d()->URIErrorConstructor = 0;
229
230 d()->evalFunction = 0;
231
232 ExecState* exec = d()->globalExec.get();
233
234 // Prototypes
235
236 d()->functionPrototype = new (exec) FunctionPrototype(exec);
237 d()->objectPrototype = new (exec) ObjectPrototype(exec, d()->functionPrototype);
238 d()->functionPrototype->setPrototype(d()->objectPrototype);
239
240 d()->arrayPrototype = new (exec) ArrayPrototype(exec, d()->objectPrototype);
241 d()->stringPrototype = new (exec) StringPrototype(exec, d()->objectPrototype);
242 d()->booleanPrototype = new (exec) BooleanPrototype(exec, d()->objectPrototype, d()->functionPrototype);
243 d()->numberPrototype = new (exec) NumberPrototype(exec, d()->objectPrototype, d()->functionPrototype);
244 d()->datePrototype = new (exec) DatePrototype(exec, d()->objectPrototype);
245 d()->regExpPrototype = new (exec) RegExpPrototype(exec, d()->objectPrototype, d()->functionPrototype);
246 d()->errorPrototype = new (exec) ErrorPrototype(exec, d()->objectPrototype, d()->functionPrototype);
247
248 d()->evalErrorPrototype = new (exec) NativeErrorPrototype(exec, d()->errorPrototype, "EvalError", "EvalError");
249 d()->rangeErrorPrototype = new (exec) NativeErrorPrototype(exec, d()->errorPrototype, "RangeError", "RangeError");
250 d()->referenceErrorPrototype = new (exec) NativeErrorPrototype(exec, d()->errorPrototype, "ReferenceError", "ReferenceError");
251 d()->syntaxErrorPrototype = new (exec) NativeErrorPrototype(exec, d()->errorPrototype, "SyntaxError", "SyntaxError");
252 d()->typeErrorPrototype = new (exec) NativeErrorPrototype(exec, d()->errorPrototype, "TypeError", "TypeError");
253 d()->URIErrorPrototype = new (exec) NativeErrorPrototype(exec, d()->errorPrototype, "URIError", "URIError");
254
255 // Constructors
256
257 JSValue* objectConstructor = new (exec) ObjectConstructor(exec, d()->objectPrototype, d()->functionPrototype);
258 JSValue* functionConstructor = new (exec) FunctionConstructor(exec, d()->functionPrototype);
259 JSValue* arrayConstructor = new (exec) ArrayConstructor(exec, d()->functionPrototype, d()->arrayPrototype);
260 JSValue* stringConstructor = new (exec) StringConstructor(exec, d()->functionPrototype, d()->stringPrototype);
261 JSValue* booleanConstructor = new (exec) BooleanConstructor(exec, d()->functionPrototype, d()->booleanPrototype);
262 JSValue* numberConstructor = new (exec) NumberConstructor(exec, d()->functionPrototype, d()->numberPrototype);
263 JSValue* dateConstructor = new (exec) DateConstructor(exec, d()->functionPrototype, d()->datePrototype);
264
265 d()->regExpConstructor = new (exec) RegExpConstructor(exec, d()->functionPrototype, d()->regExpPrototype);
266
267 d()->errorConstructor = new (exec) ErrorConstructor(exec, d()->functionPrototype, d()->errorPrototype);
268
269 d()->evalErrorConstructor = new (exec) NativeErrorConstructor(exec, d()->functionPrototype, d()->evalErrorPrototype);
270 d()->rangeErrorConstructor = new (exec) NativeErrorConstructor(exec, d()->functionPrototype, d()->rangeErrorPrototype);
271 d()->referenceErrorConstructor = new (exec) NativeErrorConstructor(exec, d()->functionPrototype, d()->referenceErrorPrototype);
272 d()->syntaxErrorConstructor = new (exec) NativeErrorConstructor(exec, d()->functionPrototype, d()->syntaxErrorPrototype);
273 d()->typeErrorConstructor = new (exec) NativeErrorConstructor(exec, d()->functionPrototype, d()->typeErrorPrototype);
274 d()->URIErrorConstructor = new (exec) NativeErrorConstructor(exec, d()->functionPrototype, d()->URIErrorPrototype);
275
276 d()->functionPrototype->putDirect(exec->propertyNames().constructor, functionConstructor, DontEnum);
277
278 d()->objectPrototype->putDirect(exec->propertyNames().constructor, objectConstructor, DontEnum);
279 d()->functionPrototype->putDirect(exec->propertyNames().constructor, functionConstructor, DontEnum);
280 d()->arrayPrototype->putDirect(exec->propertyNames().constructor, arrayConstructor, DontEnum);
281 d()->booleanPrototype->putDirect(exec->propertyNames().constructor, booleanConstructor, DontEnum);
282 d()->stringPrototype->putDirect(exec->propertyNames().constructor, stringConstructor, DontEnum);
283 d()->numberPrototype->putDirect(exec->propertyNames().constructor, numberConstructor, DontEnum);
284 d()->datePrototype->putDirect(exec->propertyNames().constructor, dateConstructor, DontEnum);
285 d()->regExpPrototype->putDirect(exec->propertyNames().constructor, d()->regExpConstructor, DontEnum);
286 d()->errorPrototype->putDirect(exec->propertyNames().constructor, d()->errorConstructor, DontEnum);
287 d()->evalErrorPrototype->putDirect(exec->propertyNames().constructor, d()->evalErrorConstructor, DontEnum);
288 d()->rangeErrorPrototype->putDirect(exec->propertyNames().constructor, d()->rangeErrorConstructor, DontEnum);
289 d()->referenceErrorPrototype->putDirect(exec->propertyNames().constructor, d()->referenceErrorConstructor, DontEnum);
290 d()->syntaxErrorPrototype->putDirect(exec->propertyNames().constructor, d()->syntaxErrorConstructor, DontEnum);
291 d()->typeErrorPrototype->putDirect(exec->propertyNames().constructor, d()->typeErrorConstructor, DontEnum);
292 d()->URIErrorPrototype->putDirect(exec->propertyNames().constructor, d()->URIErrorConstructor, DontEnum);
293
294 // Set global constructors
295
296 // FIXME: These properties could be handled by a static hash table.
297
298 putDirect(Identifier(exec, "Object"), objectConstructor, DontEnum);
299 putDirect(Identifier(exec, "Function"), functionConstructor, DontEnum);
300 putDirect(Identifier(exec, "Array"), arrayConstructor, DontEnum);
301 putDirect(Identifier(exec, "Boolean"), booleanConstructor, DontEnum);
302 putDirect(Identifier(exec, "String"), stringConstructor, DontEnum);
303 putDirect(Identifier(exec, "Number"), numberConstructor, DontEnum);
304 putDirect(Identifier(exec, "Date"), dateConstructor, DontEnum);
305 putDirect(Identifier(exec, "RegExp"), d()->regExpConstructor, DontEnum);
306 putDirect(Identifier(exec, "Error"), d()->errorConstructor, DontEnum);
307 putDirect(Identifier(exec, "EvalError"), d()->evalErrorConstructor);
308 putDirect(Identifier(exec, "RangeError"), d()->rangeErrorConstructor);
309 putDirect(Identifier(exec, "ReferenceError"), d()->referenceErrorConstructor);
310 putDirect(Identifier(exec, "SyntaxError"), d()->syntaxErrorConstructor);
311 putDirect(Identifier(exec, "TypeError"), d()->typeErrorConstructor);
312 putDirect(Identifier(exec, "URIError"), d()->URIErrorConstructor);
313
314 // Set global values.
315 GlobalPropertyInfo staticGlobals[] = {
316 GlobalPropertyInfo(Identifier(exec, "Math"), new (exec) MathObject(exec, d()->objectPrototype), DontEnum | DontDelete),
317 GlobalPropertyInfo(Identifier(exec, "NaN"), jsNaN(exec), DontEnum | DontDelete),
318 GlobalPropertyInfo(Identifier(exec, "Infinity"), jsNumber(exec, Inf), DontEnum | DontDelete),
319 GlobalPropertyInfo(Identifier(exec, "undefined"), jsUndefined(), DontEnum | DontDelete)
320 };
321
322 addStaticGlobals(staticGlobals, sizeof(staticGlobals) / sizeof(GlobalPropertyInfo));
323
324 // Set global functions.
325
326 d()->evalFunction = new (exec) GlobalEvalFunction(exec, d()->functionPrototype, 1, exec->propertyNames().eval, globalFuncEval, this);
327 putDirectFunction(d()->evalFunction, DontEnum);
328 putDirectFunction(new (exec) PrototypeFunction(exec, d()->functionPrototype, 2, Identifier(exec, "parseInt"), globalFuncParseInt), DontEnum);
329 putDirectFunction(new (exec) PrototypeFunction(exec, d()->functionPrototype, 1, Identifier(exec, "parseFloat"), globalFuncParseFloat), DontEnum);
330 putDirectFunction(new (exec) PrototypeFunction(exec, d()->functionPrototype, 1, Identifier(exec, "isNaN"), globalFuncIsNaN), DontEnum);
331 putDirectFunction(new (exec) PrototypeFunction(exec, d()->functionPrototype, 1, Identifier(exec, "isFinite"), globalFuncIsFinite), DontEnum);
332 putDirectFunction(new (exec) PrototypeFunction(exec, d()->functionPrototype, 1, Identifier(exec, "escape"), globalFuncEscape), DontEnum);
333 putDirectFunction(new (exec) PrototypeFunction(exec, d()->functionPrototype, 1, Identifier(exec, "unescape"), globalFuncUnescape), DontEnum);
334 putDirectFunction(new (exec) PrototypeFunction(exec, d()->functionPrototype, 1, Identifier(exec, "decodeURI"), globalFuncDecodeURI), DontEnum);
335 putDirectFunction(new (exec) PrototypeFunction(exec, d()->functionPrototype, 1, Identifier(exec, "decodeURIComponent"), globalFuncDecodeURIComponent), DontEnum);
336 putDirectFunction(new (exec) PrototypeFunction(exec, d()->functionPrototype, 1, Identifier(exec, "encodeURI"), globalFuncEncodeURI), DontEnum);
337 putDirectFunction(new (exec) PrototypeFunction(exec, d()->functionPrototype, 1, Identifier(exec, "encodeURIComponent"), globalFuncEncodeURIComponent), DontEnum);
338#ifndef NDEBUG
339 putDirectFunction(new (exec) PrototypeFunction(exec, d()->functionPrototype, 1, Identifier(exec, "kjsprint"), globalFuncKJSPrint), DontEnum);
340#endif
341
342 // Set prototype, and also insert the object prototype at the end of the chain.
343
344 setPrototype(prototype);
345 lastInPrototypeChain(this)->setPrototype(d()->objectPrototype);
346}
347
348void JSGlobalObject::startTimeoutCheck()
349{
350 if (!d()->timeoutCheckCount)
351 resetTimeoutCheck();
352
353 ++d()->timeoutCheckCount;
354}
355
356void JSGlobalObject::stopTimeoutCheck()
357{
358 --d()->timeoutCheckCount;
359}
360
361void JSGlobalObject::resetTimeoutCheck()
362{
363 d()->tickCount = 0;
364 d()->ticksUntilNextTimeoutCheck = initialTickCountThreshold;
365 d()->timeAtLastCheckTimeout = 0;
366 d()->timeExecuting = 0;
367}
368
369bool JSGlobalObject::checkTimeout()
370{
371 d()->tickCount = 0;
372
373 unsigned currentTime = getCurrentTime();
374
375 if (!d()->timeAtLastCheckTimeout) {
376 // Suspicious amount of looping in a script -- start timing it
377 d()->timeAtLastCheckTimeout = currentTime;
378 return false;
379 }
380
381 unsigned timeDiff = currentTime - d()->timeAtLastCheckTimeout;
382
383 if (timeDiff == 0)
384 timeDiff = 1;
385
386 d()->timeExecuting += timeDiff;
387 d()->timeAtLastCheckTimeout = currentTime;
388
389 // Adjust the tick threshold so we get the next checkTimeout call in the interval specified in
390 // preferredScriptCheckTimeInterval
391 d()->ticksUntilNextTimeoutCheck = (unsigned)((float)preferredScriptCheckTimeInterval / timeDiff) * d()->ticksUntilNextTimeoutCheck;
392
393 // If the new threshold is 0 reset it to the default threshold. This can happen if the timeDiff is higher than the
394 // preferred script check time interval.
395 if (d()->ticksUntilNextTimeoutCheck == 0)
396 d()->ticksUntilNextTimeoutCheck = initialTickCountThreshold;
397
398 if (d()->timeoutTime && d()->timeExecuting > d()->timeoutTime) {
399 if (shouldInterruptScript())
400 return true;
401
402 resetTimeoutCheck();
403 }
404
405 return false;
406}
407
408void JSGlobalObject::mark()
409{
410 JSVariableObject::mark();
411
412 HashSet<ProgramCodeBlock*>::const_iterator end = codeBlocks().end();
413 for (HashSet<ProgramCodeBlock*>::const_iterator it = codeBlocks().begin(); it != end; ++it)
414 (*it)->mark();
415
416 markIfNeeded(d()->globalExec->exception());
417
418 markIfNeeded(d()->regExpConstructor);
419 markIfNeeded(d()->errorConstructor);
420 markIfNeeded(d()->evalErrorConstructor);
421 markIfNeeded(d()->rangeErrorConstructor);
422 markIfNeeded(d()->referenceErrorConstructor);
423 markIfNeeded(d()->syntaxErrorConstructor);
424 markIfNeeded(d()->typeErrorConstructor);
425 markIfNeeded(d()->URIErrorConstructor);
426
427 markIfNeeded(d()->evalFunction);
428
429 markIfNeeded(d()->objectPrototype);
430 markIfNeeded(d()->functionPrototype);
431 markIfNeeded(d()->arrayPrototype);
432 markIfNeeded(d()->booleanPrototype);
433 markIfNeeded(d()->stringPrototype);
434 markIfNeeded(d()->numberPrototype);
435 markIfNeeded(d()->datePrototype);
436 markIfNeeded(d()->regExpPrototype);
437 markIfNeeded(d()->errorPrototype);
438 markIfNeeded(d()->evalErrorPrototype);
439 markIfNeeded(d()->rangeErrorPrototype);
440 markIfNeeded(d()->referenceErrorPrototype);
441 markIfNeeded(d()->syntaxErrorPrototype);
442 markIfNeeded(d()->typeErrorPrototype);
443 markIfNeeded(d()->URIErrorPrototype);
444}
445
446JSGlobalObject* JSGlobalObject::toGlobalObject(ExecState*) const
447{
448 return const_cast<JSGlobalObject*>(this);
449}
450
451ExecState* JSGlobalObject::globalExec()
452{
453 return d()->globalExec.get();
454}
455
456bool JSGlobalObject::isDynamicScope() const
457{
458 return true;
459}
460
461void JSGlobalObject::copyGlobalsFrom(RegisterFile& registerFile)
462{
463 ASSERT(!d()->registerArray);
464
465 int numGlobals = registerFile.numGlobals();
466 if (!numGlobals) {
467 ASSERT(!d()->registerOffset);
468 d()->registerBase = 0;
469 return;
470 }
471 copyRegisterArray(registerFile.lastGlobal(), numGlobals);
472}
473
474void JSGlobalObject::copyGlobalsTo(RegisterFile& registerFile)
475{
476 JSGlobalObject* lastGlobalObject = registerFile.globalObject();
477 if (lastGlobalObject && lastGlobalObject != this)
478 lastGlobalObject->copyGlobalsFrom(registerFile);
479
480 registerFile.setGlobalObject(this);
481 registerFile.setNumGlobals(symbolTable().size());
482
483 if (d()->registerArray) {
484 memcpy(*registerFile.basePointer() - d()->registerOffset, d()->registerArray, d()->registerOffset * sizeof(Register));
485 setRegisterArray(0, 0);
486 }
487
488 d()->registerBase = registerFile.basePointer();
489 d()->registerOffset = 0;
490}
491
492void* JSGlobalObject::operator new(size_t size)
493{
494#ifdef JAVASCRIPTCORE_BUILDING_ALL_IN_ONE_FILE
495 return JSGlobalData::threadInstance().heap->inlineAllocate(size);
496#else
497 return JSGlobalData::threadInstance().heap->allocate(size);
498#endif
499}
500
501void* JSGlobalObject::operator new(size_t size, SharedTag)
502{
503#ifdef JAVASCRIPTCORE_BUILDING_ALL_IN_ONE_FILE
504 return JSGlobalData::sharedInstance().heap->inlineAllocate(size);
505#else
506 return JSGlobalData::sharedInstance().heap->allocate(size);
507#endif
508}
509
510} // namespace KJS
Note: See TracBrowser for help on using the repository browser.