// Preferred number of milliseconds between each timeout check
static const int preferredScriptCheckTimeInterval = 1000;
-static inline void markIfNeeded(JSValue v)
+static inline void markIfNeeded(MarkStack& markStack, JSValue v)
{
- if (v && !v.marked())
- v.mark();
+ if (v)
+ markStack.append(v);
}
-static inline void markIfNeeded(const RefPtr<Structure>& s)
+static inline void markIfNeeded(MarkStack& markStack, const RefPtr<Structure>& s)
{
if (s)
- s->mark();
+ markIfNeeded(markStack, s->storedPrototype());
}
JSGlobalObject::~JSGlobalObject()
if (headObject == this)
headObject = 0;
- HashSet<ProgramCodeBlock*>::const_iterator end = codeBlocks().end();
- for (HashSet<ProgramCodeBlock*>::const_iterator it = codeBlocks().begin(); it != end; ++it)
+ HashSet<GlobalCodeBlock*>::const_iterator end = codeBlocks().end();
+ for (HashSet<GlobalCodeBlock*>::const_iterator it = codeBlocks().begin(); it != end; ++it)
(*it)->clearGlobalObject();
RegisterFile& registerFile = globalData()->interpreter->registerFile();
- if (registerFile.globalObject() == this) {
- registerFile.setGlobalObject(0);
+ if (registerFile.clearGlobalObject(this))
registerFile.setNumGlobals(0);
- }
- delete d();
+ d()->destructor(d());
}
void JSGlobalObject::init(JSObject* thisValue)
{
ASSERT(JSLock::currentThreadIsHoldingLock());
+ structure()->disableSpecificFunctionTracking();
+
d()->globalData = Heap::heap(this)->globalData();
- d()->globalScopeChain = ScopeChain(this, d()->globalData.get(), thisValue);
+ d()->globalScopeChain = ScopeChain(this, d()->globalData.get(), this, thisValue);
JSGlobalObject::globalExec()->init(0, 0, d()->globalScopeChain.node(), CallFrame::noCaller(), 0, 0, 0);
}
}
-void JSGlobalObject::defineGetter(ExecState* exec, const Identifier& propertyName, JSObject* getterFunc)
+void JSGlobalObject::defineGetter(ExecState* exec, const Identifier& propertyName, JSObject* getterFunc, unsigned attributes)
{
PropertySlot slot;
if (!symbolTableGet(propertyName, slot))
- JSVariableObject::defineGetter(exec, propertyName, getterFunc);
+ JSVariableObject::defineGetter(exec, propertyName, getterFunc, attributes);
}
-void JSGlobalObject::defineSetter(ExecState* exec, const Identifier& propertyName, JSObject* setterFunc)
+void JSGlobalObject::defineSetter(ExecState* exec, const Identifier& propertyName, JSObject* setterFunc, unsigned attributes)
{
PropertySlot slot;
if (!symbolTableGet(propertyName, slot))
- JSVariableObject::defineSetter(exec, propertyName, setterFunc);
+ JSVariableObject::defineSetter(exec, propertyName, setterFunc, attributes);
}
static inline JSObject* lastInPrototypeChain(JSObject* object)
ErrorPrototype* errorPrototype = new (exec) ErrorPrototype(exec, ErrorPrototype::createStructure(d()->objectPrototype), d()->prototypeFunctionStructure.get());
d()->errorStructure = ErrorInstance::createStructure(errorPrototype);
- RefPtr<Structure> nativeErrorPrototypeStructure = NativeErrorPrototype::createStructure(errorPrototype);
-
- NativeErrorPrototype* evalErrorPrototype = new (exec) NativeErrorPrototype(exec, nativeErrorPrototypeStructure, "EvalError", "EvalError");
- NativeErrorPrototype* rangeErrorPrototype = new (exec) NativeErrorPrototype(exec, nativeErrorPrototypeStructure, "RangeError", "RangeError");
- NativeErrorPrototype* referenceErrorPrototype = new (exec) NativeErrorPrototype(exec, nativeErrorPrototypeStructure, "ReferenceError", "ReferenceError");
- NativeErrorPrototype* syntaxErrorPrototype = new (exec) NativeErrorPrototype(exec, nativeErrorPrototypeStructure, "SyntaxError", "SyntaxError");
- NativeErrorPrototype* typeErrorPrototype = new (exec) NativeErrorPrototype(exec, nativeErrorPrototypeStructure, "TypeError", "TypeError");
- NativeErrorPrototype* URIErrorPrototype = new (exec) NativeErrorPrototype(exec, nativeErrorPrototypeStructure, "URIError", "URIError");
-
// Constructors
- JSCell* objectConstructor = new (exec) ObjectConstructor(exec, ObjectConstructor::createStructure(d()->functionPrototype), d()->objectPrototype);
+ JSCell* objectConstructor = new (exec) ObjectConstructor(exec, ObjectConstructor::createStructure(d()->functionPrototype), d()->objectPrototype, d()->prototypeFunctionStructure.get());
JSCell* functionConstructor = new (exec) FunctionConstructor(exec, FunctionConstructor::createStructure(d()->functionPrototype), d()->functionPrototype);
- JSCell* arrayConstructor = new (exec) ArrayConstructor(exec, ArrayConstructor::createStructure(d()->functionPrototype), d()->arrayPrototype);
+ JSCell* arrayConstructor = new (exec) ArrayConstructor(exec, ArrayConstructor::createStructure(d()->functionPrototype), d()->arrayPrototype, d()->prototypeFunctionStructure.get());
JSCell* stringConstructor = new (exec) StringConstructor(exec, StringConstructor::createStructure(d()->functionPrototype), d()->prototypeFunctionStructure.get(), d()->stringPrototype);
JSCell* booleanConstructor = new (exec) BooleanConstructor(exec, BooleanConstructor::createStructure(d()->functionPrototype), d()->booleanPrototype);
JSCell* numberConstructor = new (exec) NumberConstructor(exec, NumberConstructor::createStructure(d()->functionPrototype), d()->numberPrototype);
d()->errorConstructor = new (exec) ErrorConstructor(exec, ErrorConstructor::createStructure(d()->functionPrototype), errorPrototype);
+ RefPtr<Structure> nativeErrorPrototypeStructure = NativeErrorPrototype::createStructure(errorPrototype);
RefPtr<Structure> nativeErrorStructure = NativeErrorConstructor::createStructure(d()->functionPrototype);
- d()->evalErrorConstructor = new (exec) NativeErrorConstructor(exec, nativeErrorStructure, evalErrorPrototype);
- d()->rangeErrorConstructor = new (exec) NativeErrorConstructor(exec, nativeErrorStructure, rangeErrorPrototype);
- d()->referenceErrorConstructor = new (exec) NativeErrorConstructor(exec, nativeErrorStructure, referenceErrorPrototype);
- d()->syntaxErrorConstructor = new (exec) NativeErrorConstructor(exec, nativeErrorStructure, syntaxErrorPrototype);
- d()->typeErrorConstructor = new (exec) NativeErrorConstructor(exec, nativeErrorStructure, typeErrorPrototype);
- d()->URIErrorConstructor = new (exec) NativeErrorConstructor(exec, nativeErrorStructure, URIErrorPrototype);
+ d()->evalErrorConstructor = new (exec) NativeErrorConstructor(exec, nativeErrorStructure, nativeErrorPrototypeStructure, "EvalError");
+ d()->rangeErrorConstructor = new (exec) NativeErrorConstructor(exec, nativeErrorStructure, nativeErrorPrototypeStructure, "RangeError");
+ d()->referenceErrorConstructor = new (exec) NativeErrorConstructor(exec, nativeErrorStructure, nativeErrorPrototypeStructure, "ReferenceError");
+ d()->syntaxErrorConstructor = new (exec) NativeErrorConstructor(exec, nativeErrorStructure, nativeErrorPrototypeStructure, "SyntaxError");
+ d()->typeErrorConstructor = new (exec) NativeErrorConstructor(exec, nativeErrorStructure, nativeErrorPrototypeStructure, "TypeError");
+ d()->URIErrorConstructor = new (exec) NativeErrorConstructor(exec, nativeErrorStructure, nativeErrorPrototypeStructure, "URIError");
d()->objectPrototype->putDirectFunctionWithoutTransition(exec->propertyNames().constructor, objectConstructor, DontEnum);
d()->functionPrototype->putDirectFunctionWithoutTransition(exec->propertyNames().constructor, functionConstructor, DontEnum);
d()->regExpPrototype->putDirectFunctionWithoutTransition(exec->propertyNames().constructor, d()->regExpConstructor, DontEnum);
errorPrototype->putDirectFunctionWithoutTransition(exec->propertyNames().constructor, d()->errorConstructor, DontEnum);
- evalErrorPrototype->putDirect(exec->propertyNames().constructor, d()->evalErrorConstructor, DontEnum);
- rangeErrorPrototype->putDirect(exec->propertyNames().constructor, d()->rangeErrorConstructor, DontEnum);
- referenceErrorPrototype->putDirect(exec->propertyNames().constructor, d()->referenceErrorConstructor, DontEnum);
- syntaxErrorPrototype->putDirect(exec->propertyNames().constructor, d()->syntaxErrorConstructor, DontEnum);
- typeErrorPrototype->putDirect(exec->propertyNames().constructor, d()->typeErrorConstructor, DontEnum);
- URIErrorPrototype->putDirect(exec->propertyNames().constructor, d()->URIErrorConstructor, DontEnum);
-
// Set global constructors
// FIXME: These properties could be handled by a static hash table.
// Set global values.
GlobalPropertyInfo staticGlobals[] = {
GlobalPropertyInfo(Identifier(exec, "Math"), new (exec) MathObject(exec, MathObject::createStructure(d()->objectPrototype)), DontEnum | DontDelete),
- GlobalPropertyInfo(Identifier(exec, "NaN"), jsNaN(exec), DontEnum | DontDelete),
- GlobalPropertyInfo(Identifier(exec, "Infinity"), jsNumber(exec, Inf), DontEnum | DontDelete),
- GlobalPropertyInfo(Identifier(exec, "undefined"), jsUndefined(), DontEnum | DontDelete),
+ GlobalPropertyInfo(Identifier(exec, "NaN"), jsNaN(exec), DontEnum | DontDelete | ReadOnly),
+ GlobalPropertyInfo(Identifier(exec, "Infinity"), jsNumber(exec, Inf), DontEnum | DontDelete | ReadOnly),
+ GlobalPropertyInfo(Identifier(exec, "undefined"), jsUndefined(), DontEnum | DontDelete | ReadOnly),
GlobalPropertyInfo(Identifier(exec, "JSON"), new (exec) JSONObject(JSONObject::createStructure(d()->objectPrototype)), DontEnum | DontDelete)
};
oldLastInPrototypeChain->setPrototype(objectPrototype);
}
-void JSGlobalObject::mark()
+void JSGlobalObject::markChildren(MarkStack& markStack)
{
- JSVariableObject::mark();
+ JSVariableObject::markChildren(markStack);
- HashSet<ProgramCodeBlock*>::const_iterator end = codeBlocks().end();
- for (HashSet<ProgramCodeBlock*>::const_iterator it = codeBlocks().begin(); it != end; ++it)
- (*it)->mark();
+ HashSet<GlobalCodeBlock*>::const_iterator end = codeBlocks().end();
+ for (HashSet<GlobalCodeBlock*>::const_iterator it = codeBlocks().begin(); it != end; ++it)
+ (*it)->markAggregate(markStack);
RegisterFile& registerFile = globalData()->interpreter->registerFile();
if (registerFile.globalObject() == this)
- registerFile.markGlobals(&globalData()->heap);
-
- markIfNeeded(d()->regExpConstructor);
- markIfNeeded(d()->errorConstructor);
- markIfNeeded(d()->evalErrorConstructor);
- markIfNeeded(d()->rangeErrorConstructor);
- markIfNeeded(d()->referenceErrorConstructor);
- markIfNeeded(d()->syntaxErrorConstructor);
- markIfNeeded(d()->typeErrorConstructor);
- markIfNeeded(d()->URIErrorConstructor);
-
- markIfNeeded(d()->evalFunction);
- markIfNeeded(d()->callFunction);
- markIfNeeded(d()->applyFunction);
-
- markIfNeeded(d()->objectPrototype);
- markIfNeeded(d()->functionPrototype);
- markIfNeeded(d()->arrayPrototype);
- markIfNeeded(d()->booleanPrototype);
- markIfNeeded(d()->stringPrototype);
- markIfNeeded(d()->numberPrototype);
- markIfNeeded(d()->datePrototype);
- markIfNeeded(d()->regExpPrototype);
-
- markIfNeeded(d()->methodCallDummy);
-
- markIfNeeded(d()->errorStructure);
+ registerFile.markGlobals(markStack, &globalData()->heap);
+
+ markIfNeeded(markStack, d()->regExpConstructor);
+ markIfNeeded(markStack, d()->errorConstructor);
+ markIfNeeded(markStack, d()->evalErrorConstructor);
+ markIfNeeded(markStack, d()->rangeErrorConstructor);
+ markIfNeeded(markStack, d()->referenceErrorConstructor);
+ markIfNeeded(markStack, d()->syntaxErrorConstructor);
+ markIfNeeded(markStack, d()->typeErrorConstructor);
+ markIfNeeded(markStack, d()->URIErrorConstructor);
+
+ markIfNeeded(markStack, d()->evalFunction);
+ markIfNeeded(markStack, d()->callFunction);
+ markIfNeeded(markStack, d()->applyFunction);
+
+ markIfNeeded(markStack, d()->objectPrototype);
+ markIfNeeded(markStack, d()->functionPrototype);
+ markIfNeeded(markStack, d()->arrayPrototype);
+ markIfNeeded(markStack, d()->booleanPrototype);
+ markIfNeeded(markStack, d()->stringPrototype);
+ markIfNeeded(markStack, d()->numberPrototype);
+ markIfNeeded(markStack, d()->datePrototype);
+ markIfNeeded(markStack, d()->regExpPrototype);
+
+ markIfNeeded(markStack, d()->methodCallDummy);
+
+ markIfNeeded(markStack, d()->errorStructure);
+ markIfNeeded(markStack, d()->argumentsStructure);
+ markIfNeeded(markStack, d()->arrayStructure);
+ markIfNeeded(markStack, d()->booleanObjectStructure);
+ markIfNeeded(markStack, d()->callbackConstructorStructure);
+ markIfNeeded(markStack, d()->callbackFunctionStructure);
+ markIfNeeded(markStack, d()->callbackObjectStructure);
+ markIfNeeded(markStack, d()->dateStructure);
+ markIfNeeded(markStack, d()->emptyObjectStructure);
+ markIfNeeded(markStack, d()->errorStructure);
+ markIfNeeded(markStack, d()->functionStructure);
+ markIfNeeded(markStack, d()->numberObjectStructure);
+ markIfNeeded(markStack, d()->prototypeFunctionStructure);
+ markIfNeeded(markStack, d()->regExpMatchesArrayStructure);
+ markIfNeeded(markStack, d()->regExpStructure);
+ markIfNeeded(markStack, d()->stringObjectStructure);
// No need to mark the other structures, because their prototypes are all
// guaranteed to be referenced elsewhere.
return;
size_t size = d()->registerArraySize;
- for (size_t i = 0; i < size; ++i) {
- Register& r = registerArray[i];
- if (!r.marked())
- r.mark();
- }
+ markStack.appendValues(reinterpret_cast<JSValue*>(registerArray), size);
}
ExecState* JSGlobalObject::globalExec()
return CallFrame::create(d()->globalCallFrame + RegisterFile::CallFrameHeaderSize);
}
-bool JSGlobalObject::isDynamicScope() const
+bool JSGlobalObject::isDynamicScope(bool&) const
{
return true;
}
void* JSGlobalObject::operator new(size_t size, JSGlobalData* globalData)
{
-#ifdef JAVASCRIPTCORE_BUILDING_ALL_IN_ONE_FILE
- return globalData->heap.inlineAllocate(size);
-#else
return globalData->heap.allocate(size);
+}
+
+void JSGlobalObject::destroyJSGlobalObjectData(void* jsGlobalObjectData)
+{
+ delete static_cast<JSGlobalObjectData*>(jsGlobalObjectData);
+}
+
+DynamicGlobalObjectScope::DynamicGlobalObjectScope(CallFrame* callFrame, JSGlobalObject* dynamicGlobalObject)
+ : m_dynamicGlobalObjectSlot(callFrame->globalData().dynamicGlobalObject)
+ , m_savedDynamicGlobalObject(m_dynamicGlobalObjectSlot)
+{
+ if (!m_dynamicGlobalObjectSlot) {
+#if ENABLE(JIT)
+ if (ExecutablePool::underMemoryPressure())
+ callFrame->globalData().recompileAllJSFunctions();
#endif
+ m_dynamicGlobalObjectSlot = dynamicGlobalObject;
+
+ // Reset the date cache between JS invocations to force the VM
+ // to observe time zone changes.
+ callFrame->globalData().resetDateCache();
+ }
}
} // namespace JSC