MapData and WeakMapData don't need to be objects

https://bugs.webkit.org/show_bug.cgi?id=121167

Patch by Sam Weinig <sam@webkit.org> on 2013-09-11
Reviewed by Geoffrey Garen.

* runtime/JSGlobalObject.cpp:
(JSC::JSGlobalObject::reset):
(JSC::JSGlobalObject::visitChildren):
* runtime/JSGlobalObject.h:
(JSC::JSGlobalObject::mapStructure):
Remove MapData and WeakMapData structures (they moved to VM with other non-object Structures).

* runtime/JSMap.cpp:
(JSC::JSMap::finishCreation):
* runtime/JSMap.h:
(JSC::JSMap::create):
* runtime/JSSet.cpp:
(JSC::JSSet::finishCreation):
* runtime/JSSet.h:
(JSC::JSSet::create):
* runtime/JSWeakMap.cpp:
(JSC::JSWeakMap::finishCreation):
* runtime/JSWeakMap.h:
(JSC::JSWeakMap::create):
Update to not pass a global object to the MapData or WeakMapData Structure.

* runtime/MapData.cpp:
(JSC::MapData::MapData):
* runtime/MapData.h:
(JSC::MapData::create):
(JSC::MapData::createStructure):
* runtime/WeakMapData.cpp:
(JSC::WeakMapData::WeakMapData):
(JSC::WeakMapData::set): Change to take a VM rather than a CallFrame, as that it all it needs.
* runtime/WeakMapData.h:
(JSC::WeakMapData::create):
(JSC::WeakMapData::createStructure):
Instead of inheriting from JSDestructibleObject, inherit from JSCell and mark self as needing destruction
and having an immortal structure.

* runtime/VM.cpp:
(JSC::VM::VM):
* runtime/VM.h:
Add MapData and WeakMapData Structures.

* runtime/WeakMapPrototype.cpp:
(JSC::protoFuncWeakMapSet):
Pass a VM rather than an ExecState.

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@155558 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent f44603e1
2013-09-11 Sam Weinig <sam@webkit.org>
MapData and WeakMapData don't need to be objects
https://bugs.webkit.org/show_bug.cgi?id=121167
Reviewed by Geoffrey Garen.
* runtime/JSGlobalObject.cpp:
(JSC::JSGlobalObject::reset):
(JSC::JSGlobalObject::visitChildren):
* runtime/JSGlobalObject.h:
(JSC::JSGlobalObject::mapStructure):
Remove MapData and WeakMapData structures (they moved to VM with other non-object Structures).
* runtime/JSMap.cpp:
(JSC::JSMap::finishCreation):
* runtime/JSMap.h:
(JSC::JSMap::create):
* runtime/JSSet.cpp:
(JSC::JSSet::finishCreation):
* runtime/JSSet.h:
(JSC::JSSet::create):
* runtime/JSWeakMap.cpp:
(JSC::JSWeakMap::finishCreation):
* runtime/JSWeakMap.h:
(JSC::JSWeakMap::create):
Update to not pass a global object to the MapData or WeakMapData Structure.
* runtime/MapData.cpp:
(JSC::MapData::MapData):
* runtime/MapData.h:
(JSC::MapData::create):
(JSC::MapData::createStructure):
* runtime/WeakMapData.cpp:
(JSC::WeakMapData::WeakMapData):
(JSC::WeakMapData::set): Change to take a VM rather than a CallFrame, as that it all it needs.
* runtime/WeakMapData.h:
(JSC::WeakMapData::create):
(JSC::WeakMapData::createStructure):
Instead of inheriting from JSDestructibleObject, inherit from JSCell and mark self as needing destruction
and having an immortal structure.
* runtime/VM.cpp:
(JSC::VM::VM):
* runtime/VM.h:
Add MapData and WeakMapData Structures.
* runtime/WeakMapPrototype.cpp:
(JSC::protoFuncWeakMapSet):
Pass a VM rather than an ExecState.
2013-09-10 Filip Pizlo <fpizlo@apple.com>
Propagate the Int48 stuff into the prediction propagator.
......
......@@ -76,7 +76,6 @@
#include "LegacyProfiler.h"
#include "Lookup.h"
#include "MapConstructor.h"
#include "MapData.h"
#include "MapPrototype.h"
#include "MathObject.h"
#include "NameConstructor.h"
......@@ -101,7 +100,6 @@
#include "StringConstructor.h"
#include "StringPrototype.h"
#include "WeakMapConstructor.h"
#include "WeakMapData.h"
#include "WeakMapPrototype.h"
#if ENABLE(PROMISES)
......@@ -311,10 +309,6 @@ void JSGlobalObject::reset(JSValue prototype)
m_promiseWrapperCallbackStructure.set(exec->vm(), this, JSPromiseWrapperCallback::createStructure(exec->vm(), this, m_functionPrototype.get()));
#endif // ENABLE(PROMISES)
m_mapDataStructure.set(exec->vm(), this, MapData::createStructure(exec->vm(), this, jsNull()));
m_weakMapDataStructure.set(exec->vm(), this, WeakMapData::createStructure(exec->vm(), this, jsNull()));
#define CREATE_PROTOTYPE_FOR_SIMPLE_TYPE(capitalName, lowerName, properName, instanceType, jsName) \
m_ ## lowerName ## Prototype.set(exec->vm(), this, capitalName##Prototype::create(exec, this, capitalName##Prototype::createStructure(exec->vm(), this, m_objectPrototype.get()))); \
m_ ## properName ## Structure.set(exec->vm(), this, instanceType::createStructure(exec->vm(), this, m_ ## lowerName ## Prototype.get()));
......@@ -644,9 +638,6 @@ void JSGlobalObject::visitChildren(JSCell* cell, SlotVisitor& visitor)
#undef VISIT_SIMPLE_TYPE
visitor.append(&thisObject->m_mapDataStructure);
visitor.append(&thisObject->m_weakMapDataStructure);
for (unsigned i = NUMBER_OF_TYPED_ARRAY_TYPES; i--;) {
visitor.append(&thisObject->m_typedArrays[i].prototype);
visitor.append(&thisObject->m_typedArrays[i].structure);
......
......@@ -200,9 +200,6 @@ protected:
WriteBarrier<Structure> m_promiseWrapperCallbackStructure;
#endif // ENABLE(PROMISES)
WriteBarrier<Structure> m_mapDataStructure;
WriteBarrier<Structure> m_weakMapDataStructure;
#define DEFINE_STORAGE_FOR_SIMPLE_TYPE(capitalName, lowerName, properName, instanceType, jsName) \
WriteBarrier<capitalName ## Prototype> m_ ## lowerName ## Prototype; \
WriteBarrier<Structure> m_ ## properName ## Structure;
......@@ -399,8 +396,6 @@ public:
Structure* privateNameStructure() const { return m_privateNameStructure.get(); }
Structure* internalFunctionStructure() const { return m_internalFunctionStructure.get(); }
Structure* mapStructure() const { return m_mapStructure.get(); }
Structure* mapDataStructure() const { return m_mapDataStructure.get(); }
Structure* weakMapDataStructure() const { return m_weakMapDataStructure.get(); }
Structure* regExpMatchesArrayStructure() const { return m_regExpMatchesArrayStructure.get(); }
Structure* regExpStructure() const { return m_regExpStructure.get(); }
Structure* setStructure() const { return m_setStructure.get(); }
......
......@@ -41,10 +41,10 @@ void JSMap::visitChildren(JSCell* cell, SlotVisitor& visitor)
visitor.append(&thisObject->m_mapData);
}
void JSMap::finishCreation(VM& vm, JSGlobalObject* globalObject)
void JSMap::finishCreation(VM& vm)
{
Base::finishCreation(vm);
m_mapData.set(vm, this, MapData::create(vm, globalObject));
m_mapData.set(vm, this, MapData::create(vm));
}
......
......@@ -46,7 +46,7 @@ public:
static JSMap* create(VM& vm, Structure* structure)
{
JSMap* instance = new (NotNull, allocateCell<JSMap>(vm.heap)) JSMap(vm, structure);
instance->finishCreation(vm, structure->globalObject());
instance->finishCreation(vm);
return instance;
}
......@@ -58,7 +58,6 @@ public:
MapData* mapData() { return m_mapData.get(); }
private:
static const unsigned StructureFlags = OverridesVisitChildren | Base::StructureFlags;
JSMap(VM& vm, Structure* structure)
......@@ -66,7 +65,7 @@ private:
{
}
JS_EXPORT_PRIVATE void finishCreation(VM&, JSGlobalObject*);
JS_EXPORT_PRIVATE void finishCreation(VM&);
static void visitChildren(JSCell*, SlotVisitor&);
......
......@@ -41,10 +41,10 @@ void JSSet::visitChildren(JSCell* cell, SlotVisitor& visitor)
visitor.append(&thisObject->m_mapData);
}
void JSSet::finishCreation(VM& vm, JSGlobalObject* globalObject)
void JSSet::finishCreation(VM& vm)
{
Base::finishCreation(vm);
m_mapData.set(vm, this, MapData::create(vm, globalObject));
m_mapData.set(vm, this, MapData::create(vm));
}
}
......@@ -46,7 +46,7 @@ public:
static JSSet* create(VM& vm, Structure* structure)
{
JSSet* instance = new (NotNull, allocateCell<JSSet>(vm.heap)) JSSet(vm, structure);
instance->finishCreation(vm, structure->globalObject());
instance->finishCreation(vm);
return instance;
}
......@@ -66,7 +66,7 @@ private:
{
}
JS_EXPORT_PRIVATE void finishCreation(VM&, JSGlobalObject*);
JS_EXPORT_PRIVATE void finishCreation(VM&);
static void visitChildren(JSCell*, SlotVisitor&);
......
......@@ -34,10 +34,10 @@ namespace JSC {
const ClassInfo JSWeakMap::s_info = { "WeakMap", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(JSWeakMap) };
void JSWeakMap::finishCreation(VM& vm, JSGlobalObject* globalObject)
void JSWeakMap::finishCreation(VM& vm)
{
Base::finishCreation(vm);
m_weakMapData.set(vm, this, WeakMapData::create(vm, globalObject));
m_weakMapData.set(vm, this, WeakMapData::create(vm));
}
void JSWeakMap::visitChildren(JSCell* cell, SlotVisitor& visitor)
......
......@@ -43,14 +43,18 @@ public:
return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
}
static JSWeakMap* create(ExecState* exec, Structure* structure)
static JSWeakMap* create(VM& vm, Structure* structure)
{
VM& vm = exec->vm();
JSWeakMap* instance = new (NotNull, allocateCell<JSWeakMap>(vm.heap)) JSWeakMap(vm, structure);
instance->finishCreation(vm, structure->globalObject());
instance->finishCreation(vm);
return instance;
}
static JSWeakMap* create(ExecState* exec, Structure* structure)
{
return create(exec->vm(), structure);
}
WeakMapData* weakMapData() { return m_weakMapData.get(); }
JSValue get(CallFrame*, JSObject*);
......@@ -61,7 +65,6 @@ public:
void clear(CallFrame*);
private:
static const unsigned StructureFlags = OverridesVisitChildren | Base::StructureFlags;
JSWeakMap(VM& vm, Structure* structure)
......@@ -69,7 +72,7 @@ private:
{
}
void finishCreation(VM&, JSGlobalObject*);
void finishCreation(VM&);
static void visitChildren(JSCell*, SlotVisitor&);
WriteBarrier<WeakMapData> m_weakMapData;
......
......@@ -37,12 +37,12 @@
namespace JSC {
const ClassInfo MapData::s_info = { "MapData", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(MapData) };
const ClassInfo MapData::s_info = { "MapData", 0, 0, 0, CREATE_METHOD_TABLE(MapData) };
static const int32_t minimumMapSize = 8;
MapData::MapData(VM& vm, JSGlobalObject* globalObject)
: Base(vm, globalObject->mapDataStructure())
MapData::MapData(VM& vm)
: Base(vm, vm.mapDataStructure.get())
, m_capacity(0)
, m_size(0)
, m_deletedCount(0)
......
......@@ -26,19 +26,17 @@
#ifndef MapData_h
#define MapData_h
#include "CallFrame.h"
#include "JSCJSValue.h"
#include "JSDestructibleObject.h"
#include "JSCell.h"
#include "Structure.h"
#include <wtf/HashFunctions.h>
#include <wtf/HashMap.h>
#include <wtf/MathExtras.h>
namespace JSC {
class MapData : public JSDestructibleObject {
class MapData : public JSCell {
public:
typedef JSDestructibleObject Base;
typedef JSCell Base;
struct const_iterator {
const_iterator(const MapData*);
......@@ -68,18 +66,21 @@ public:
JSValue value;
};
static MapData* create(VM& vm, JSGlobalObject* globalObject)
static MapData* create(VM& vm)
{
MapData* mapData = new (NotNull, allocateCell<MapData>(vm.heap)) MapData(vm, globalObject);
MapData* mapData = new (NotNull, allocateCell<MapData>(vm.heap)) MapData(vm);
mapData->finishCreation(vm);
return mapData;
}
static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
{
return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
return Structure::create(vm, globalObject, prototype, TypeInfo(CompoundType, StructureFlags), info());
}
static const bool needsDestruction = true;
static const bool hasImmortalStructure = true;
JS_EXPORT_PRIVATE void set(CallFrame*, KeyType, JSValue);
JSValue get(CallFrame*, KeyType);
bool remove(CallFrame*, KeyType);
......@@ -109,7 +110,7 @@ private:
size_t capacityInBytes() { return m_capacity * sizeof(Entry); }
MapData(VM&, JSGlobalObject*);
MapData(VM&);
static void destroy(JSCell*);
static void visitChildren(JSCell*, SlotVisitor&);
static void copyBackingStore(JSCell*, CopyVisitor&, CopyToken);
......
......@@ -46,8 +46,8 @@
#include "Identifier.h"
#include "IncrementalSweeper.h"
#include "Interpreter.h"
#include "JSActivation.h"
#include "JSAPIValueWrapper.h"
#include "JSActivation.h"
#include "JSArray.h"
#include "JSFunction.h"
#include "JSGlobalObjectFunctions.h"
......@@ -68,6 +68,7 @@
#include "StrictEvalActivation.h"
#include "StrongInlines.h"
#include "UnlinkedCodeBlock.h"
#include "WeakMapData.h"
#include <wtf/ProcessID.h>
#include <wtf/RetainPtr.h>
#include <wtf/StringPrintStream.h>
......@@ -241,6 +242,9 @@ VM::VM(VMType vmType, HeapType heapType)
unlinkedEvalCodeBlockStructure.set(*this, UnlinkedEvalCodeBlock::createStructure(*this, 0, jsNull()));
unlinkedFunctionCodeBlockStructure.set(*this, UnlinkedFunctionCodeBlock::createStructure(*this, 0, jsNull()));
propertyTableStructure.set(*this, PropertyTable::createStructure(*this, 0, jsNull()));
mapDataStructure.set(*this, MapData::createStructure(*this, 0, jsNull()));
weakMapDataStructure.set(*this, WeakMapData::createStructure(*this, 0, jsNull()));
smallStrings.initializeCommonStrings(*this);
wtfThreadData().setCurrentIdentifierTable(existingEntryIdentifierTable);
......
......@@ -270,6 +270,8 @@ namespace JSC {
Strong<Structure> unlinkedEvalCodeBlockStructure;
Strong<Structure> unlinkedFunctionCodeBlockStructure;
Strong<Structure> propertyTableStructure;
Strong<Structure> mapDataStructure;
Strong<Structure> weakMapDataStructure;
IdentifierTable* identifierTable;
CommonIdentifiers* propertyNames;
......
......@@ -34,13 +34,12 @@
#include <wtf/MathExtras.h>
namespace JSC {
const ClassInfo WeakMapData::s_info = { "WeakMapData", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(WeakMapData) };
const ClassInfo WeakMapData::s_info = { "WeakMapData", 0, 0, 0, CREATE_METHOD_TABLE(WeakMapData) };
WeakMapData::WeakMapData(VM& vm, JSGlobalObject* globalObject)
: Base(vm, globalObject->weakMapDataStructure())
WeakMapData::WeakMapData(VM& vm)
: Base(vm, vm.weakMapDataStructure.get())
, m_deadKeyCleaner(this)
{
}
......@@ -68,11 +67,11 @@ void WeakMapData::visitChildren(JSCell* cell, SlotVisitor& visitor)
visitor.reportExtraMemoryUsage(thisObj->m_map.capacity() * (sizeof(JSObject*) + sizeof(WriteBarrier<Unknown>)));
}
void WeakMapData::set(CallFrame* callFrame, JSObject* key, JSValue value)
void WeakMapData::set(VM& vm, JSObject* key, JSValue value)
{
// Here we force the write barrier on the key.
auto result = m_map.add(WriteBarrier<JSObject>(callFrame->vm(), this, key).get(), WriteBarrier<Unknown>());
result.iterator->value.set(callFrame->vm(), this, value);
auto result = m_map.add(WriteBarrier<JSObject>(vm, this, key).get(), WriteBarrier<Unknown>());
result.iterator->value.set(vm, this, value);
}
JSValue WeakMapData::get(JSObject* key)
......
......@@ -26,47 +26,45 @@
#ifndef WeakMapData_h
#define WeakMapData_h
#include "CallFrame.h"
#include "JSCJSValue.h"
#include "JSDestructibleObject.h"
#include "JSCell.h"
#include "Structure.h"
#include <wtf/HashFunctions.h>
#include <wtf/HashMap.h>
#include <wtf/MathExtras.h>
namespace JSC {
class WeakImpl;
class WeakMapData;
class WeakMapData : public JSDestructibleObject {
class WeakMapData : public JSCell {
public:
typedef JSDestructibleObject Base;
typedef JSCell Base;
static WeakMapData* create(VM& vm, JSGlobalObject* globalObject)
static WeakMapData* create(VM& vm)
{
WeakMapData* weakMapData = new (NotNull, allocateCell<WeakMapData>(vm.heap)) WeakMapData(vm, globalObject);
WeakMapData* weakMapData = new (NotNull, allocateCell<WeakMapData>(vm.heap)) WeakMapData(vm);
weakMapData->finishCreation(vm);
return weakMapData;
}
static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
{
return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
return Structure::create(vm, globalObject, prototype, TypeInfo(CompoundType, StructureFlags), info());
}
void set(CallFrame*, JSObject*, JSValue);
static const bool needsDestruction = true;
static const bool hasImmortalStructure = true;
void set(VM&, JSObject*, JSValue);
JSValue get(JSObject*);
bool remove(JSObject*);
void removeDead(JSObject*);
bool contains(JSObject*);
void clear();
DECLARE_INFO;
static const unsigned StructureFlags = OverridesVisitChildren | Base::StructureFlags;
private:
WeakMapData(VM&, JSGlobalObject*);
WeakMapData(VM&);
static void destroy(JSCell*);
static void visitChildren(JSCell*, SlotVisitor&);
void finishCreation(VM&);
......
......@@ -119,7 +119,7 @@ EncodedJSValue JSC_HOST_CALL protoFuncWeakMapSet(CallFrame* callFrame)
JSValue key = callFrame->argument(0);
if (!key.isObject())
return JSValue::encode(throwTypeError(callFrame, WTF::ASCIILiteral("Attempted to set a non-object key in a WeakMap")));
map->set(callFrame, asObject(key), callFrame->argument(1));
map->set(callFrame->vm(), asObject(key), callFrame->argument(1));
return JSValue::encode(callFrame->thisValue());
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment