Skip to content
Permalink
Browse files
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.

Canonical link: https://commits.webkit.org/139116@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@155558 268f45cc-cd09-0410-ab3c-d52691b4dbfc
  • Loading branch information
Sam Weinig authored and webkit-commit-queue committed Sep 11, 2013
1 parent 331d6a1 commit 827eb507876688faaf7287be98f63833ea216d3f
@@ -1,3 +1,54 @@
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 @@ class JSGlobalObject : public JSSegmentedVariableObject {
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 @@ class JSGlobalObject : public JSSegmentedVariableObject {
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 @@ class JSMap : public JSNonFinalObject {
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,15 +58,14 @@ class JSMap : public JSNonFinalObject {
MapData* mapData() { return m_mapData.get(); }

private:

static const unsigned StructureFlags = OverridesVisitChildren | Base::StructureFlags;

JSMap(VM& vm, Structure* structure)
: Base(vm, structure)
{
}

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 @@ class JSSet : public JSNonFinalObject {
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 @@ class JSSet : public JSNonFinalObject {
{
}

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 @@ class JSWeakMap : public JSNonFinalObject {
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,15 +65,14 @@ class JSWeakMap : public JSNonFinalObject {
void clear(CallFrame*);

private:

static const unsigned StructureFlags = OverridesVisitChildren | Base::StructureFlags;

JSWeakMap(VM& vm, Structure* structure)
: Base(vm, structure)
{
}

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 @@ class MapData : public JSDestructibleObject {
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 @@ class MapData : public JSDestructibleObject {

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)

0 comments on commit 827eb50

Please sign in to comment.