summaryrefslogtreecommitdiff
path: root/Source/JavaScriptCore/runtime/JSGlobalObject.cpp
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@digia.com>2012-09-18 15:53:33 +0200
committerSimon Hausmann <simon.hausmann@digia.com>2012-09-18 15:53:33 +0200
commit6bbb7fbbac94d0f511a7bd0cbd50854ab643bfb2 (patch)
treed9c68d1cca0b3e352f1e438561f3e504e641a08f /Source/JavaScriptCore/runtime/JSGlobalObject.cpp
parentd0424a769059c84ae20beb3c217812792ea6726b (diff)
downloadqtwebkit-6bbb7fbbac94d0f511a7bd0cbd50854ab643bfb2.tar.gz
Imported WebKit commit c7503cef7ecb236730d1309676ab9fc723fd061d (http://svn.webkit.org/repository/webkit/trunk@128886)
New snapshot with various build fixes
Diffstat (limited to 'Source/JavaScriptCore/runtime/JSGlobalObject.cpp')
-rw-r--r--Source/JavaScriptCore/runtime/JSGlobalObject.cpp94
1 files changed, 93 insertions, 1 deletions
diff --git a/Source/JavaScriptCore/runtime/JSGlobalObject.cpp b/Source/JavaScriptCore/runtime/JSGlobalObject.cpp
index 8ee8e1498..a6993aabc 100644
--- a/Source/JavaScriptCore/runtime/JSGlobalObject.cpp
+++ b/Source/JavaScriptCore/runtime/JSGlobalObject.cpp
@@ -111,6 +111,7 @@ static const int preferredScriptCheckTimeInterval = 1000;
JSGlobalObject::JSGlobalObject(JSGlobalData& globalData, Structure* structure, const GlobalObjectMethodTable* globalObjectMethodTable)
: Base(globalData, structure, 0)
, m_masqueradesAsUndefinedWatchpoint(adoptRef(new WatchpointSet(InitializedWatching)))
+ , m_havingABadTimeWatchpoint(adoptRef(new WatchpointSet(InitializedWatching)))
, m_weakRandom(Options::forceWeakRandomSeed() ? Options::forcedWeakRandomSeed() : static_cast<unsigned>(randomNumber() * (std::numeric_limits<unsigned>::max() + 1.0)))
, m_evalEnabled(true)
, m_globalObjectMethodTable(globalObjectMethodTable ? globalObjectMethodTable : &s_globalObjectMethodTable)
@@ -230,7 +231,8 @@ void JSGlobalObject::reset(JSValue prototype)
m_callbackObjectStructure.set(exec->globalData(), this, JSCallbackObject<JSNonFinalObject>::createStructure(exec->globalData(), this, m_objectPrototype.get()));
m_arrayPrototype.set(exec->globalData(), this, ArrayPrototype::create(exec, this, ArrayPrototype::createStructure(exec->globalData(), this, m_objectPrototype.get())));
- m_arrayStructure.set(exec->globalData(), this, JSArray::createStructure(exec->globalData(), this, m_arrayPrototype.get()));
+ m_arrayStructure.set(exec->globalData(), this, JSArray::createStructure(exec->globalData(), this, m_arrayPrototype.get(), ArrayWithArrayStorage));
+ m_arrayStructureForSlowPut.set(exec->globalData(), this, JSArray::createStructure(exec->globalData(), this, m_arrayPrototype.get(), ArrayWithSlowPutArrayStorage));
m_regExpMatchesArrayStructure.set(exec->globalData(), this, RegExpMatchesArray::createStructure(exec->globalData(), this, m_arrayPrototype.get()));
m_stringPrototype.set(exec->globalData(), this, StringPrototype::create(exec, this, StringPrototype::createStructure(exec->globalData(), this, m_objectPrototype.get())));
@@ -329,6 +331,96 @@ void JSGlobalObject::reset(JSValue prototype)
resetPrototype(exec->globalData(), prototype);
}
+// Private namespace for helpers for JSGlobalObject::haveABadTime()
+namespace {
+
+class ObjectsWithBrokenIndexingFinder : public MarkedBlock::VoidFunctor {
+public:
+ ObjectsWithBrokenIndexingFinder(MarkedArgumentBuffer&, JSGlobalObject*);
+ void operator()(JSCell*);
+
+private:
+ MarkedArgumentBuffer& m_foundObjects;
+ JSGlobalObject* m_globalObject;
+};
+
+ObjectsWithBrokenIndexingFinder::ObjectsWithBrokenIndexingFinder(
+ MarkedArgumentBuffer& foundObjects, JSGlobalObject* globalObject)
+ : m_foundObjects(foundObjects)
+ , m_globalObject(globalObject)
+{
+}
+
+inline bool hasBrokenIndexing(JSObject* object)
+{
+ // This will change if we have more indexing types.
+ return !!(object->structure()->indexingType() & HasArrayStorage);
+}
+
+void ObjectsWithBrokenIndexingFinder::operator()(JSCell* cell)
+{
+ if (!cell->isObject())
+ return;
+
+ JSObject* object = asObject(cell);
+
+ // Run this filter first, since it's cheap, and ought to filter out a lot of objects.
+ if (!hasBrokenIndexing(object))
+ return;
+
+ // We only want to have a bad time in the affected global object, not in the entire
+ // VM. But we have to be careful, since there may be objects that claim to belong to
+ // a different global object that have prototypes from our global object.
+ bool foundGlobalObject = false;
+ for (JSObject* current = object; ;) {
+ if (current->unwrappedGlobalObject() == m_globalObject) {
+ foundGlobalObject = true;
+ break;
+ }
+
+ JSValue prototypeValue = current->prototype();
+ if (prototypeValue.isNull())
+ break;
+ current = asObject(prototypeValue);
+ }
+ if (!foundGlobalObject)
+ return;
+
+ m_foundObjects.append(object);
+}
+
+} // end private namespace for helpers for JSGlobalObject::haveABadTime()
+
+void JSGlobalObject::haveABadTime(JSGlobalData& globalData)
+{
+ ASSERT(&globalData == &this->globalData());
+
+ if (isHavingABadTime())
+ return;
+
+ // Make sure that all allocations or indexed storage transitions that are inlining
+ // the assumption that it's safe to transition to a non-SlowPut array storage don't
+ // do so anymore.
+ m_havingABadTimeWatchpoint->notifyWrite();
+ ASSERT(isHavingABadTime()); // The watchpoint is what tells us that we're having a bad time.
+
+ // Make sure that all JSArray allocations that load the appropriate structure from
+ // this object now load a structure that uses SlowPut.
+ m_arrayStructure.set(globalData, this, m_arrayStructureForSlowPut.get());
+
+ // Make sure that all objects that have indexed storage switch to the slow kind of
+ // indexed storage.
+ MarkedArgumentBuffer foundObjects; // Use MarkedArgumentBuffer because switchToSlowPutArrayStorage() may GC.
+ ObjectsWithBrokenIndexingFinder finder(foundObjects, this);
+ globalData.heap.objectSpace().forEachLiveCell(finder);
+ while (!foundObjects.isEmpty()) {
+ JSObject* object = asObject(foundObjects.last());
+ foundObjects.removeLast();
+ ASSERT(hasBrokenIndexing(object));
+ object->switchToSlowPutArrayStorage(globalData);
+ }
+}
+
void JSGlobalObject::createThrowTypeError(ExecState* exec)
{
JSFunction* thrower = JSFunction::create(exec, this, 0, String(), globalFuncThrowTypeError);