]> git.saurik.com Git - apple/javascriptcore.git/blobdiff - runtime/JSGlobalObject.cpp
JavaScriptCore-721.26.tar.gz
[apple/javascriptcore.git] / runtime / JSGlobalObject.cpp
index c56b84b0e7a46b5b46aff060ce3258daa3cc8d34..93ded4c7d9afb0d663b593630ecb0c1cc06d644b 100644 (file)
@@ -80,16 +80,16 @@ static const int initialTickCountThreshold = 255;
 // 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()
@@ -112,24 +112,24 @@ 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);
 
@@ -175,18 +175,18 @@ void JSGlobalObject::putWithAttributes(ExecState* exec, const Identifier& proper
     }
 }
 
-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)
@@ -245,20 +245,11 @@ void JSGlobalObject::reset(JSValue prototype)
     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);
@@ -268,14 +259,15 @@ void JSGlobalObject::reset(JSValue prototype)
 
     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);
@@ -287,13 +279,6 @@ void JSGlobalObject::reset(JSValue prototype)
     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.
@@ -317,9 +302,9 @@ void JSGlobalObject::reset(JSValue prototype)
     // 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)
     };
 
@@ -357,43 +342,58 @@ void JSGlobalObject::resetPrototype(JSValue prototype)
         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.
@@ -403,11 +403,7 @@ void JSGlobalObject::mark()
         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()
@@ -415,7 +411,7 @@ ExecState* JSGlobalObject::globalExec()
     return CallFrame::create(d()->globalCallFrame + RegisterFile::CallFrameHeaderSize);
 }
 
-bool JSGlobalObject::isDynamicScope() const
+bool JSGlobalObject::isDynamicScope(bool&) const
 {
     return true;
 }
@@ -452,11 +448,29 @@ void JSGlobalObject::copyGlobalsTo(RegisterFile& registerFile)
 
 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