The tiny set magic in StructureSet should be available in WTF
https://bugs.webkit.org/show_bug.cgi?id=145722
Reviewed by Geoffrey Garen.
Source/JavaScriptCore:
I moved the generic logic of small sets of pointers and moved it into WTF. Now,
StructureSet is a subclass of TinyPtrSet<Structure*>. There shouldn't be any functional
change.
* bytecode/StructureSet.cpp:
(JSC::StructureSet::filter):
(JSC::StructureSet::filterArrayModes):
(JSC::StructureSet::speculationFromStructures):
(JSC::StructureSet::arrayModesFromStructures):
(JSC::StructureSet::dumpInContext):
(JSC::StructureSet::dump):
(JSC::StructureSet::clear): Deleted.
(JSC::StructureSet::add): Deleted.
(JSC::StructureSet::remove): Deleted.
(JSC::StructureSet::contains): Deleted.
(JSC::StructureSet::merge): Deleted.
(JSC::StructureSet::exclude): Deleted.
(JSC::StructureSet::isSubsetOf): Deleted.
(JSC::StructureSet::overlaps): Deleted.
(JSC::StructureSet::operator==): Deleted.
(JSC::StructureSet::addOutOfLine): Deleted.
(JSC::StructureSet::containsOutOfLine): Deleted.
(JSC::StructureSet::copyFromOutOfLine): Deleted.
(JSC::StructureSet::OutOfLineList::create): Deleted.
(JSC::StructureSet::OutOfLineList::destroy): Deleted.
* bytecode/StructureSet.h:
(JSC::StructureSet::onlyStructure):
(JSC::StructureSet::StructureSet): Deleted.
(JSC::StructureSet::operator=): Deleted.
(JSC::StructureSet::~StructureSet): Deleted.
(JSC::StructureSet::isEmpty): Deleted.
(JSC::StructureSet::genericFilter): Deleted.
(JSC::StructureSet::isSupersetOf): Deleted.
(JSC::StructureSet::size): Deleted.
(JSC::StructureSet::at): Deleted.
(JSC::StructureSet::operator[]): Deleted.
(JSC::StructureSet::last): Deleted.
(JSC::StructureSet::iterator::iterator): Deleted.
(JSC::StructureSet::iterator::operator*): Deleted.
(JSC::StructureSet::iterator::operator++): Deleted.
(JSC::StructureSet::iterator::operator==): Deleted.
(JSC::StructureSet::iterator::operator!=): Deleted.
(JSC::StructureSet::begin): Deleted.
(JSC::StructureSet::end): Deleted.
(JSC::StructureSet::ContainsOutOfLine::ContainsOutOfLine): Deleted.
(JSC::StructureSet::ContainsOutOfLine::operator()): Deleted.
(JSC::StructureSet::copyFrom): Deleted.
(JSC::StructureSet::OutOfLineList::list): Deleted.
(JSC::StructureSet::OutOfLineList::OutOfLineList): Deleted.
(JSC::StructureSet::deleteStructureListIfNecessary): Deleted.
(JSC::StructureSet::isThin): Deleted.
(JSC::StructureSet::pointer): Deleted.
(JSC::StructureSet::singleStructure): Deleted.
(JSC::StructureSet::structureList): Deleted.
(JSC::StructureSet::set): Deleted.
(JSC::StructureSet::setEmpty): Deleted.
(JSC::StructureSet::getReservedFlag): Deleted.
(JSC::StructureSet::setReservedFlag): Deleted.
* dfg/DFGStructureAbstractValue.cpp:
(JSC::DFG::StructureAbstractValue::clobber):
(JSC::DFG::StructureAbstractValue::filter):
(JSC::DFG::StructureAbstractValue::filterSlow):
(JSC::DFG::StructureAbstractValue::contains):
* dfg/DFGStructureAbstractValue.h:
(JSC::DFG::StructureAbstractValue::makeTop):
Source/WTF:
As the management of structure sets evolved in JSC, the StructureSet data structure grew
increasingly smart. It's got some smart stuff for managing small sets of pointers. I
wanted to take the generic logic out of JSC and put it into a reusable templatized class
in WTF.
* WTF.vcxproj/WTF.vcxproj:
* WTF.xcodeproj/project.pbxproj:
* wtf/CMakeLists.txt:
* wtf/TinyPtrSet.h: Added.
(WTF::TinyPtrSet::TinyPtrSet):
(WTF::TinyPtrSet::operator=):
(WTF::TinyPtrSet::~TinyPtrSet):
(WTF::TinyPtrSet::clear):
(WTF::TinyPtrSet::onlyEntry):
(WTF::TinyPtrSet::isEmpty):
(WTF::TinyPtrSet::add):
(WTF::TinyPtrSet::remove):
(WTF::TinyPtrSet::contains):
(WTF::TinyPtrSet::merge):
(WTF::TinyPtrSet::forEach):
(WTF::TinyPtrSet::genericFilter):
(WTF::TinyPtrSet::filter):
(WTF::TinyPtrSet::exclude):
(WTF::TinyPtrSet::isSubsetOf):
(WTF::TinyPtrSet::isSupersetOf):
(WTF::TinyPtrSet::overlaps):
(WTF::TinyPtrSet::size):
(WTF::TinyPtrSet::at):
(WTF::TinyPtrSet::operator[]):
(WTF::TinyPtrSet::last):
(WTF::TinyPtrSet::iterator::iterator):
(WTF::TinyPtrSet::iterator::operator*):
(WTF::TinyPtrSet::iterator::operator++):
(WTF::TinyPtrSet::iterator::operator==):
(WTF::TinyPtrSet::iterator::operator!=):
(WTF::TinyPtrSet::begin):
(WTF::TinyPtrSet::end):
(WTF::TinyPtrSet::operator==):
(WTF::TinyPtrSet::addOutOfLine):
(WTF::TinyPtrSet::containsOutOfLine):
(WTF::TinyPtrSet::copyFrom):
(WTF::TinyPtrSet::copyFromOutOfLine):
(WTF::TinyPtrSet::OutOfLineList::create):
(WTF::TinyPtrSet::OutOfLineList::destroy):
(WTF::TinyPtrSet::OutOfLineList::list):
(WTF::TinyPtrSet::OutOfLineList::OutOfLineList):
(WTF::TinyPtrSet::deleteListIfNecessary):
(WTF::TinyPtrSet::isThin):
(WTF::TinyPtrSet::pointer):
(WTF::TinyPtrSet::singleEntry):
(WTF::TinyPtrSet::list):
(WTF::TinyPtrSet::set):
(WTF::TinyPtrSet::setEmpty):
(WTF::TinyPtrSet::getReservedFlag):
(WTF::TinyPtrSet::setReservedFlag):
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@185324 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/JavaScriptCore/bytecode/StructureSet.cpp b/Source/JavaScriptCore/bytecode/StructureSet.cpp
index 3d2c109..55fdb7d 100644
--- a/Source/JavaScriptCore/bytecode/StructureSet.cpp
+++ b/Source/JavaScriptCore/bytecode/StructureSet.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014, 2015 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -31,203 +31,27 @@
namespace JSC {
-void StructureSet::clear()
-{
- deleteStructureListIfNecessary();
- setEmpty();
-}
-
-bool StructureSet::add(Structure* structure)
-{
- ASSERT(structure);
- if (isThin()) {
- if (singleStructure() == structure)
- return false;
- if (!singleStructure()) {
- set(structure);
- return true;
- }
- OutOfLineList* list = OutOfLineList::create(defaultStartingSize);
- list->m_length = 2;
- list->list()[0] = singleStructure();
- list->list()[1] = structure;
- set(list);
- return true;
- }
-
- return addOutOfLine(structure);
-}
-
-bool StructureSet::remove(Structure* structure)
-{
- if (isThin()) {
- if (singleStructure() == structure) {
- setEmpty();
- return true;
- }
- return false;
- }
-
- OutOfLineList* list = structureList();
- for (unsigned i = 0; i < list->m_length; ++i) {
- if (list->list()[i] != structure)
- continue;
- list->list()[i] = list->list()[--list->m_length];
- if (!list->m_length) {
- OutOfLineList::destroy(list);
- setEmpty();
- }
- return true;
- }
- return false;
-}
-
-bool StructureSet::contains(Structure* structure) const
-{
- if (isThin())
- return singleStructure() == structure;
-
- return containsOutOfLine(structure);
-}
-
-bool StructureSet::merge(const StructureSet& other)
-{
- if (other.isThin()) {
- if (other.singleStructure())
- return add(other.singleStructure());
- return false;
- }
-
- OutOfLineList* list = other.structureList();
- if (list->m_length >= 2) {
- if (isThin()) {
- OutOfLineList* myNewList = OutOfLineList::create(
- list->m_length + !!singleStructure());
- if (singleStructure()) {
- myNewList->m_length = 1;
- myNewList->list()[0] = singleStructure();
- }
- set(myNewList);
- }
- bool changed = false;
- for (unsigned i = 0; i < list->m_length; ++i)
- changed |= addOutOfLine(list->list()[i]);
- return changed;
- }
-
- ASSERT(list->m_length);
- return add(list->list()[0]);
-}
-
-void StructureSet::filter(const StructureSet& other)
-{
- if (other.isThin()) {
- if (!other.singleStructure() || !contains(other.singleStructure()))
- clear();
- else {
- clear();
- set(other.singleStructure());
- }
- return;
- }
-
- ContainsOutOfLine containsOutOfLine(other);
- genericFilter(containsOutOfLine);
-}
-
-void StructureSet::exclude(const StructureSet& other)
-{
- if (other.isThin()) {
- if (other.singleStructure())
- remove(other.singleStructure());
- return;
- }
-
- if (isThin()) {
- if (!singleStructure())
- return;
- if (other.contains(singleStructure()))
- clear();
- return;
- }
-
- OutOfLineList* list = structureList();
- for (unsigned i = 0; i < list->m_length; ++i) {
- if (!other.containsOutOfLine(list->list()[i]))
- continue;
- list->list()[i--] = list->list()[--list->m_length];
- }
- if (!list->m_length)
- clear();
-}
-
#if ENABLE(DFG_JIT)
-namespace {
-
-class StructureAbstractValueContains {
-public:
- StructureAbstractValueContains(const DFG::StructureAbstractValue& value)
- : m_value(value)
- {
- }
-
- bool operator()(Structure* structure)
- {
- return m_value.contains(structure);
- }
-private:
- const DFG::StructureAbstractValue& m_value;
-};
-
-class SpeculatedTypeContains {
-public:
- SpeculatedTypeContains(SpeculatedType type)
- : m_type(type)
- {
- }
-
- bool operator()(Structure* structure)
- {
- return m_type & speculationFromStructure(structure);
- }
-private:
- SpeculatedType m_type;
-};
-
-class ArrayModesContains {
-public:
- ArrayModesContains(ArrayModes arrayModes)
- : m_arrayModes(arrayModes)
- {
- }
-
- bool operator()(Structure* structure)
- {
- return m_arrayModes & arrayModeFromStructure(structure);
- }
-private:
- ArrayModes m_arrayModes;
-};
-
-} // anonymous namespace
-
void StructureSet::filter(const DFG::StructureAbstractValue& other)
{
- StructureAbstractValueContains functor(other);
- genericFilter(functor);
+ genericFilter([&] (Structure* structure) -> bool { return other.contains(structure); });
}
void StructureSet::filter(SpeculatedType type)
{
- SpeculatedTypeContains functor(type);
- genericFilter(functor);
+ genericFilter(
+ [&] (Structure* structure) -> bool {
+ return type & speculationFromStructure(structure);
+ });
}
void StructureSet::filterArrayModes(ArrayModes arrayModes)
{
- ArrayModesContains functor(arrayModes);
- genericFilter(functor);
+ genericFilter(
+ [&] (Structure* structure) -> bool {
+ return arrayModes & arrayModeFromStructure(structure);
+ });
}
void StructureSet::filter(const DFG::AbstractValue& other)
@@ -239,89 +63,23 @@
#endif // ENABLE(DFG_JIT)
-bool StructureSet::isSubsetOf(const StructureSet& other) const
-{
- if (isThin()) {
- if (!singleStructure())
- return true;
- return other.contains(singleStructure());
- }
-
- if (other.isThin()) {
- if (!other.singleStructure())
- return false;
- OutOfLineList* list = structureList();
- if (list->m_length >= 2)
- return false;
- if (list->list()[0] == other.singleStructure())
- return true;
- return false;
- }
-
- OutOfLineList* list = structureList();
- for (unsigned i = 0; i < list->m_length; ++i) {
- if (!other.containsOutOfLine(list->list()[i]))
- return false;
- }
- return true;
-}
-
-bool StructureSet::overlaps(const StructureSet& other) const
-{
- if (isThin()) {
- if (!singleStructure())
- return false;
- return other.contains(singleStructure());
- }
-
- if (other.isThin()) {
- if (!other.singleStructure())
- return false;
- return containsOutOfLine(other.singleStructure());
- }
-
- OutOfLineList* list = structureList();
- for (unsigned i = 0; i < list->m_length; ++i) {
- if (other.containsOutOfLine(list->list()[i]))
- return true;
- }
- return false;
-}
-
-bool StructureSet::operator==(const StructureSet& other) const
-{
- if (size() != other.size())
- return false;
- return isSubsetOf(other);
-}
-
SpeculatedType StructureSet::speculationFromStructures() const
{
- if (isThin()) {
- if (!singleStructure())
- return SpecNone;
- return speculationFromStructure(singleStructure());
- }
-
SpeculatedType result = SpecNone;
- OutOfLineList* list = structureList();
- for (unsigned i = 0; i < list->m_length; ++i)
- mergeSpeculation(result, speculationFromStructure(list->list()[i]));
+ forEach(
+ [&] (Structure* structure) {
+ mergeSpeculation(result, speculationFromStructure(structure));
+ });
return result;
}
ArrayModes StructureSet::arrayModesFromStructures() const
{
- if (isThin()) {
- if (!singleStructure())
- return 0;
- return asArrayModes(singleStructure()->indexingType());
- }
-
ArrayModes result = 0;
- OutOfLineList* list = structureList();
- for (unsigned i = 0; i < list->m_length; ++i)
- mergeArrayModes(result, asArrayModes(list->list()[i]->indexingType()));
+ forEach(
+ [&] (Structure* structure) {
+ mergeArrayModes(result, asArrayModes(structure->indexingType()));
+ });
return result;
}
@@ -329,8 +87,7 @@
{
CommaPrinter comma;
out.print("[");
- for (size_t i = 0; i < size(); ++i)
- out.print(comma, inContext(*at(i), context));
+ forEach([&] (Structure* structure) { out.print(comma, inContext(*structure, context)); });
out.print("]");
}
@@ -339,59 +96,5 @@
dumpInContext(out, nullptr);
}
-bool StructureSet::addOutOfLine(Structure* structure)
-{
- OutOfLineList* list = structureList();
- for (unsigned i = 0; i < list->m_length; ++i) {
- if (list->list()[i] == structure)
- return false;
- }
-
- if (list->m_length < list->m_capacity) {
- list->list()[list->m_length++] = structure;
- return true;
- }
-
- OutOfLineList* newList = OutOfLineList::create(list->m_capacity * 2);
- newList->m_length = list->m_length + 1;
- for (unsigned i = list->m_length; i--;)
- newList->list()[i] = list->list()[i];
- newList->list()[list->m_length] = structure;
- OutOfLineList::destroy(list);
- set(newList);
- return true;
-}
-
-bool StructureSet::containsOutOfLine(Structure* structure) const
-{
- OutOfLineList* list = structureList();
- for (unsigned i = 0; i < list->m_length; ++i) {
- if (list->list()[i] == structure)
- return true;
- }
- return false;
-}
-
-void StructureSet::copyFromOutOfLine(const StructureSet& other)
-{
- ASSERT(!other.isThin() && other.m_pointer != reservedValue);
- OutOfLineList* otherList = other.structureList();
- OutOfLineList* myList = OutOfLineList::create(otherList->m_length);
- myList->m_length = otherList->m_length;
- for (unsigned i = otherList->m_length; i--;)
- myList->list()[i] = otherList->list()[i];
- set(myList);
-}
-
-StructureSet::OutOfLineList* StructureSet::OutOfLineList::create(unsigned capacity)
-{
- return new (NotNull, fastMalloc(sizeof(OutOfLineList) + capacity * sizeof(Structure*))) OutOfLineList(0, capacity);
-}
-
-void StructureSet::OutOfLineList::destroy(OutOfLineList* list)
-{
- fastFree(list);
-}
-
} // namespace JSC