Commit 264f9e28 authored by ggaren@apple.com's avatar ggaren@apple.com
Browse files

2011-04-07 Geoffrey Garen <ggaren@apple.com>

        Reviewed by Maciej Stachowiak.

        Some Handle<T> cleanup
        https://bugs.webkit.org/show_bug.cgi?id=58109

        * bytecode/SamplingTool.h: Sorted alphabetically because that's the
        WebKit style. Added a Global.h #include that was previously missing
        but harmless.

        * collector/handles/Global.h:
        (JSC::Global::Global): Added a null constructor. No need for a special
        tag, and the tag is incompatible with some data structures.
        
        (JSC::Global::isHashTableDeletedValue):
        (JSC::Global::~Global):
        (JSC::Global::set):
        (JSC::Global::operator=):
        (JSC::Global::clear):
        (JSC::Global::hashTableDeletedValue): Reordered constructors to be near
        each other.

        (JSC::Global::setWithWriteBarrier): Renamed internalSet to
        setWithWriteBarrier for clarity, and funneled more code into using set
        and setWithWriteBarrier to reduce duplication.

        * collector/handles/Handle.h:
        (JSC::HandleBase::operator!):
        (JSC::HandleBase::HandleBase): Removed isEmpty(), since we already have
        boolean and ! operators.

        (JSC::HandleBase::slot):
        (JSC::HandleBase::setSlot):
        (JSC::Handle::Handle): Added general support for null Handles. This was
        previously outlawed by ASSERTs, but our code has grown to support and
        rely on null Handles.
        
        * collector/handles/HandleHeap.cpp:
        (JSC::HandleHeap::markWeakHandles):
        (JSC::HandleHeap::finalizeWeakHandles):
        (JSC::HandleHeap::isValidWeakNode): Migrated from isValidWeakHandle,
        and beefed this up a bit.

        * collector/handles/HandleHeap.h:
        (JSC::HandleHeap::globalData): Added accessor, used by some new set functions.

        * collector/handles/Local.h: Moved hash traits to the bottom of the file,
        since this file is about the Local class, not the traits.

        (JSC::::Local): Updated for removal of invalidate().

        (JSC::::operator): Deployed "using" to avoid a lot of this->
        template funny business.

        (JSC::::setWithSlotCheck): Renamed from internalSet, more specific now.

        * interpreter/RegisterFile.h:
        (JSC::RegisterFile::RegisterFile): Updated to use null constructor.

        * jit/JITStubs.cpp:
        (JSC::JITThunks::hostFunctionStub):

        * runtime/JSPropertyNameIterator.h:
        (JSC::Structure::setEnumerationCache):
        * runtime/Structure.h: Removed clearEnumerationCache
        because it was an unused holdover from when the enumeration cache was
        not a handle.

        * runtime/WeakGCMap.h:
        (JSC::WeakGCMap::set): Finish initializing our handle before putting it
        in the table. This seemed more logical, and at one point was required
        to avoid triggering an ASSERT.

        * runtime/WeakGCPtr.h: Inherit from Handle instead of rolling our own
        handle-like behavior, to avoid duplication.

        (JSC::WeakGCPtr::WeakGCPtr):
        (JSC::WeakGCPtr::~WeakGCPtr):
        (JSC::WeakGCPtr::get):
        (JSC::WeakGCPtr::clear):
        (JSC::WeakGCPtr::set):
        (JSC::WeakGCPtr::setWithWriteBarrier): Removed duplicate code and
        standardized on Handle idioms.
2011-04-07  Geoffrey Garen  <ggaren@apple.com>

        Reviewed by Maciej Stachowiak.

        Some Handle<T> cleanup
        https://bugs.webkit.org/show_bug.cgi?id=58109

        * JSRun.h:
        * JSValueWrapper.h: #include a file that was missing before, but was
        harmlessly so until now.
2011-04-07  Geoffrey Garen  <ggaren@apple.com>

        Reviewed by Maciej Stachowiak.

        Some Handle<T> cleanup
        https://bugs.webkit.org/show_bug.cgi?id=58109

        * bindings/js/ScriptValue.h:
        (WebCore::ScriptValue::ScriptValue): Updated for new null constructor.
        (WebCore::ScriptValue::hasNoValue): Updated for removal of isEmpty().
2011-04-07  Geoffrey Garen  <ggaren@apple.com>

        Some Handle<T> cleanup
        https://bugs.webkit.org/show_bug.cgi?id=58109

        * WebProcess/Plugins/Netscape/NPJSObject.cpp:
        (WebKit::NPJSObject::NPJSObject): Updated for new null constructor.


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@83259 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 8f74be2d
2011-04-07 Geoffrey Garen <ggaren@apple.com>
Reviewed by Maciej Stachowiak.
Some Handle<T> cleanup
https://bugs.webkit.org/show_bug.cgi?id=58109
* bytecode/SamplingTool.h: Sorted alphabetically because that's the
WebKit style. Added a Global.h #include that was previously missing
but harmless.
* collector/handles/Global.h:
(JSC::Global::Global): Added a null constructor. No need for a special
tag, and the tag is incompatible with some data structures.
(JSC::Global::isHashTableDeletedValue):
(JSC::Global::~Global):
(JSC::Global::set):
(JSC::Global::operator=):
(JSC::Global::clear):
(JSC::Global::hashTableDeletedValue): Reordered constructors to be near
each other.
(JSC::Global::setWithWriteBarrier): Renamed internalSet to
setWithWriteBarrier for clarity, and funneled more code into using set
and setWithWriteBarrier to reduce duplication.
* collector/handles/Handle.h:
(JSC::HandleBase::operator!):
(JSC::HandleBase::HandleBase): Removed isEmpty(), since we already have
boolean and ! operators.
(JSC::HandleBase::slot):
(JSC::HandleBase::setSlot):
(JSC::Handle::Handle): Added general support for null Handles. This was
previously outlawed by ASSERTs, but our code has grown to support and
rely on null Handles.
* collector/handles/HandleHeap.cpp:
(JSC::HandleHeap::markWeakHandles):
(JSC::HandleHeap::finalizeWeakHandles):
(JSC::HandleHeap::isValidWeakNode): Migrated from isValidWeakHandle,
and beefed this up a bit.
* collector/handles/HandleHeap.h:
(JSC::HandleHeap::globalData): Added accessor, used by some new set functions.
* collector/handles/Local.h: Moved hash traits to the bottom of the file,
since this file is about the Local class, not the traits.
(JSC::::Local): Updated for removal of invalidate().
(JSC::::operator): Deployed "using" to avoid a lot of this->
template funny business.
(JSC::::setWithSlotCheck): Renamed from internalSet, more specific now.
* interpreter/RegisterFile.h:
(JSC::RegisterFile::RegisterFile): Updated to use null constructor.
* jit/JITStubs.cpp:
(JSC::JITThunks::hostFunctionStub):
* runtime/JSPropertyNameIterator.h:
(JSC::Structure::setEnumerationCache):
* runtime/Structure.h: Removed clearEnumerationCache
because it was an unused holdover from when the enumeration cache was
not a handle.
* runtime/WeakGCMap.h:
(JSC::WeakGCMap::set): Finish initializing our handle before putting it
in the table. This seemed more logical, and at one point was required
to avoid triggering an ASSERT.
* runtime/WeakGCPtr.h: Inherit from Handle instead of rolling our own
handle-like behavior, to avoid duplication.
(JSC::WeakGCPtr::WeakGCPtr):
(JSC::WeakGCPtr::~WeakGCPtr):
(JSC::WeakGCPtr::get):
(JSC::WeakGCPtr::clear):
(JSC::WeakGCPtr::set):
(JSC::WeakGCPtr::setWithWriteBarrier): Removed duplicate code and
standardized on Handle idioms.
2011-04-07 Adam Barth <abarth@webkit.org> 2011-04-07 Adam Barth <abarth@webkit.org>
Reviewed by Martin Robinson. Reviewed by Martin Robinson.
......
...@@ -29,13 +29,13 @@ ...@@ -29,13 +29,13 @@
#ifndef SamplingTool_h #ifndef SamplingTool_h
#define SamplingTool_h #define SamplingTool_h
#include "Global.h"
#include "Nodes.h"
#include "Opcode.h"
#include <wtf/Assertions.h> #include <wtf/Assertions.h>
#include <wtf/HashMap.h> #include <wtf/HashMap.h>
#include <wtf/Threading.h> #include <wtf/Threading.h>
#include "Nodes.h"
#include "Opcode.h"
namespace JSC { namespace JSC {
class ScriptExecutable; class ScriptExecutable;
......
...@@ -33,114 +33,108 @@ ...@@ -33,114 +33,108 @@
namespace JSC { namespace JSC {
/* // A Global is a persistent handle whose lifetime is not limited to any given scope.
A Global is a persistent handle whose lifetime is not limited to any given
scope. Use Globals for data members and global variables.
*/
template <typename T> class Global : public Handle<T> { template <typename T> class Global : public Handle<T> {
using Handle<T>::slot;
using Handle<T>::setSlot;
public: public:
typedef typename Handle<T>::ExternalType ExternalType; typedef typename Handle<T>::ExternalType ExternalType;
Global(JSGlobalData& globalData, ExternalType ptr = ExternalType())
Global()
: Handle<T>()
{
}
Global(JSGlobalData& globalData, ExternalType value = ExternalType())
: Handle<T>(globalData.allocateGlobalHandle()) : Handle<T>(globalData.allocateGlobalHandle())
{ {
internalSet(ptr); set(value);
} }
Global(JSGlobalData& globalData, Handle<T> handle) Global(JSGlobalData& globalData, Handle<T> handle)
: Handle<T>(globalData.allocateGlobalHandle()) : Handle<T>(globalData.allocateGlobalHandle())
{ {
internalSet(handle.get()); set(handle.get());
}
Global(const Global& other)
: Handle<T>()
{
if (!other.slot())
return;
setSlot(HandleHeap::heapFor(other.slot())->allocate());
set(other.get());
}
template <typename U> Global(const Global<U>& other)
: Handle<T>()
{
if (!other.slot())
return;
setSlot(HandleHeap::heapFor(other.slot())->allocate());
set(other.get());
} }
enum EmptyValueTag { EmptyValue }; enum HashTableDeletedValueTag { HashTableDeletedValue };
Global(EmptyValueTag) bool isHashTableDeletedValue() const { return slot() == hashTableDeletedValue(); }
: Handle<T>(0, HandleBase::DontNullCheckSlot) Global(HashTableDeletedValueTag)
: Handle<T>(hashTableDeletedValue())
{ {
} }
~Global() ~Global()
{ {
HandleSlot slot = this->slot(); clear();
if (slot)
HandleHeap::heapFor(slot)->deallocate(slot);
} }
void set(JSGlobalData& globalData, ExternalType value) void set(JSGlobalData& globalData, ExternalType value)
{ {
if (!value) { if (!slot())
clear(); setSlot(globalData.allocateGlobalHandle());
return; set(value);
}
if (!this->slot())
this->setSlot(globalData.allocateGlobalHandle());
internalSet(value);
} }
template <typename U> Global& operator=(const Global<U>& handle) template <typename U> Global& operator=(const Global<U>& other)
{ {
if (handle.slot()) { if (!other.slot()) {
if (!this->slot())
this->setSlot(HandleHeap::heapFor(handle.slot())->allocate());
internalSet(handle.get());
} else
clear(); clear();
return *this;
}
set(*HandleHeap::heapFor(other.slot())->globalData(), other.get());
return *this; return *this;
} }
Global& operator=(const Global& handle) Global& operator=(const Global& other)
{ {
if (handle.slot()) { if (!other.slot()) {
if (!this->slot())
this->setSlot(HandleHeap::heapFor(handle.slot())->allocate());
internalSet(handle.get());
} else
clear(); clear();
return *this;
}
set(*HandleHeap::heapFor(other.slot())->globalData(), other.get());
return *this; return *this;
} }
void clear() void clear()
{ {
if (this->slot()) if (!slot())
internalSet(ExternalType()); return;
HandleHeap::heapFor(slot())->deallocate(slot());
setSlot(0);
} }
enum HashTableDeletedValueType { HashTableDeletedValue }; private:
const static intptr_t HashTableDeletedValueTag = 0x1; static HandleSlot hashTableDeletedValue() { return reinterpret_cast<HandleSlot>(-1); }
Global(HashTableDeletedValueType)
: Handle<T>(reinterpret_cast<HandleSlot>(HashTableDeletedValueTag))
{
}
bool isHashTableDeletedValue() const { return slot() == reinterpret_cast<HandleSlot>(HashTableDeletedValueTag); }
template <typename U> Global(const Global<U>& other) void set(ExternalType externalType)
: Handle<T>(other.slot() ? HandleHeap::heapFor(other.slot())->allocate() : 0, Handle<T>::DontNullCheckSlot)
{ {
if (other.slot()) ASSERT(slot());
internalSet(other.get()); JSValue value = HandleTypes<T>::toJSValue(externalType);
HandleHeap::heapFor(slot())->writeBarrier(slot(), value);
*slot() = value;
} }
Global(const Global& other)
: Handle<T>(other.slot() ? HandleHeap::heapFor(other.slot())->allocate() : 0, Handle<T>::DontNullCheckSlot)
{
if (other.slot())
internalSet(other.get());
}
protected:
void internalSet(ExternalType value)
{
JSValue newValue(HandleTypes<T>::toJSValue(value));
HandleSlot slot = this->slot();
ASSERT(slot);
HandleHeap::heapFor(slot)->writeBarrier(slot, newValue);
*slot = newValue;
}
using Handle<T>::slot;
}; };
} }
...@@ -149,7 +143,7 @@ namespace WTF { ...@@ -149,7 +143,7 @@ namespace WTF {
template<typename P> struct HashTraits<JSC::Global<P> > : GenericHashTraits<JSC::Global<P> > { template<typename P> struct HashTraits<JSC::Global<P> > : GenericHashTraits<JSC::Global<P> > {
static const bool emptyValueIsZero = true; static const bool emptyValueIsZero = true;
static JSC::Global<P> emptyValue() { return JSC::Global<P>(JSC::Global<P>::EmptyValue); } static JSC::Global<P> emptyValue() { return JSC::Global<P>(); }
static void constructDeletedValue(JSC::Global<P>& slot) { new (&slot) JSC::Global<P>(JSC::Global<P>::HashTableDeletedValue); } static void constructDeletedValue(JSC::Global<P>& slot) { new (&slot) JSC::Global<P>(JSC::Global<P>::HashTableDeletedValue); }
static bool isDeletedValue(const JSC::Global<P>& value) { return value.isHashTableDeletedValue(); } static bool isDeletedValue(const JSC::Global<P>& value) { return value.isHashTableDeletedValue(); }
}; };
......
...@@ -49,39 +49,21 @@ class HandleBase { ...@@ -49,39 +49,21 @@ class HandleBase {
friend class HandleHeap; friend class HandleHeap;
public: public:
bool operator!() const { return isEmpty(); } bool operator!() const { return !m_slot || !*m_slot; }
// This conversion operator allows implicit conversion to bool but not to other integer types. // This conversion operator allows implicit conversion to bool but not to other integer types.
typedef JSValue (HandleBase::*UnspecifiedBoolType); typedef JSValue (HandleBase::*UnspecifiedBoolType);
operator UnspecifiedBoolType*() const { return (m_slot && *m_slot) ? reinterpret_cast<UnspecifiedBoolType*>(1) : 0; } operator UnspecifiedBoolType*() const { return (m_slot && *m_slot) ? reinterpret_cast<UnspecifiedBoolType*>(1) : 0; }
bool isEmpty() const { return !m_slot || !*m_slot; }
protected: protected:
HandleBase(HandleSlot slot) HandleBase(HandleSlot slot)
: m_slot(slot) : m_slot(slot)
{ {
ASSERT(slot);
} }
enum DontNullCheckSlotTag { DontNullCheckSlot };
HandleBase(HandleSlot slot, DontNullCheckSlotTag)
: m_slot(slot)
{
}
HandleSlot slot() const { return m_slot; } HandleSlot slot() const { return m_slot; }
void invalidate()
{
// It is unsafe to use a handle after invalidating it.
m_slot = 0;
}
// needed by Global<>::operator= and Global<>::set if it's an empty handle
void setSlot(HandleSlot slot) void setSlot(HandleSlot slot)
{ {
ASSERT(!m_slot);
ASSERT(slot);
m_slot = slot; m_slot = slot;
} }
...@@ -165,15 +147,10 @@ public: ...@@ -165,15 +147,10 @@ public:
ExternalType get() const { return HandleTypes<T>::getFromSlot(this->slot()); } ExternalType get() const { return HandleTypes<T>::getFromSlot(this->slot()); }
protected: protected:
Handle(HandleSlot slot = 0)
Handle(HandleSlot slot)
: HandleBase(slot) : HandleBase(slot)
{ {
} }
Handle(HandleSlot slot, HandleBase::DontNullCheckSlotTag)
: HandleBase(slot, HandleBase::DontNullCheckSlot)
{
}
private: private:
friend class HandleHeap; friend class HandleHeap;
......
...@@ -30,26 +30,6 @@ ...@@ -30,26 +30,6 @@
namespace JSC { namespace JSC {
#if !ASSERT_DISABLED
static inline bool isValidWeakHandle(HandleSlot handle)
{
JSValue value = *handle;
if (!value || !value.isCell())
return false;
JSCell* cell = value.asCell();
if (!cell || !cell->structure())
return false;
#if ENABLE(JSC_ZOMBIES)
if (cell->isZombie())
return false;
#endif
return true;
}
#endif
WeakHandleOwner::~WeakHandleOwner() WeakHandleOwner::~WeakHandleOwner()
{ {
} }
...@@ -97,7 +77,7 @@ void HandleHeap::markWeakHandles(HeapRootMarker& heapRootMarker) ...@@ -97,7 +77,7 @@ void HandleHeap::markWeakHandles(HeapRootMarker& heapRootMarker)
Node* end = m_weakList.end(); Node* end = m_weakList.end();
for (Node* node = m_weakList.begin(); node != end; node = node->next()) { for (Node* node = m_weakList.begin(); node != end; node = node->next()) {
ASSERT(isValidWeakHandle(node->slot())); ASSERT(isValidWeakNode(node));
JSCell* cell = node->slot()->asCell(); JSCell* cell = node->slot()->asCell();
if (Heap::isMarked(cell)) if (Heap::isMarked(cell))
continue; continue;
...@@ -120,7 +100,7 @@ void HandleHeap::finalizeWeakHandles() ...@@ -120,7 +100,7 @@ void HandleHeap::finalizeWeakHandles()
for (Node* node = m_weakList.begin(); node != end; node = m_nextToFinalize) { for (Node* node = m_weakList.begin(); node != end; node = m_nextToFinalize) {
m_nextToFinalize = node->next(); m_nextToFinalize = node->next();
ASSERT(isValidWeakHandle(node->slot())); ASSERT(isValidWeakNode(node));
JSCell* cell = node->slot()->asCell(); JSCell* cell = node->slot()->asCell();
if (Heap::isMarked(cell)) if (Heap::isMarked(cell))
continue; continue;
...@@ -173,4 +153,27 @@ unsigned HandleHeap::protectedGlobalObjectCount() ...@@ -173,4 +153,27 @@ unsigned HandleHeap::protectedGlobalObjectCount()
return count; return count;
} }
#if !ASSERT_DISABLED
bool HandleHeap::isValidWeakNode(Node* node)
{
if (!node->isWeak())
return false;
JSValue value = *node->slot();
if (!value || !value.isCell())
return false;
JSCell* cell = value.asCell();
if (!cell || !cell->structure())
return false;
#if ENABLE(JSC_ZOMBIES)
if (cell->isZombie())
return false;
#endif
return true;
}
#endif
} // namespace JSC } // namespace JSC
...@@ -51,6 +51,8 @@ public: ...@@ -51,6 +51,8 @@ public:
static HandleHeap* heapFor(HandleSlot); static HandleHeap* heapFor(HandleSlot);
HandleHeap(JSGlobalData*); HandleHeap(JSGlobalData*);
JSGlobalData* globalData();
HandleSlot allocate(); HandleSlot allocate();
void deallocate(HandleSlot); void deallocate(HandleSlot);
...@@ -105,6 +107,10 @@ private: ...@@ -105,6 +107,10 @@ private:
static Node* toNode(HandleSlot); static Node* toNode(HandleSlot);
void grow(); void grow();
#if !ASSERT_DISABLED
bool isValidWeakNode(Node*);
#endif
JSGlobalData* m_globalData; JSGlobalData* m_globalData;
BlockStack<Node> m_blockStack; BlockStack<Node> m_blockStack;
...@@ -121,6 +127,11 @@ inline HandleHeap* HandleHeap::heapFor(HandleSlot handle) ...@@ -121,6 +127,11 @@ inline HandleHeap* HandleHeap::heapFor(HandleSlot handle)
return toNode(handle)->handleHeap(); return toNode(handle)->handleHeap();
} }
inline JSGlobalData* HandleHeap::globalData()
{
return m_globalData;
}
inline HandleSlot HandleHeap::toHandle(Node* node) inline HandleSlot HandleHeap::toHandle(Node* node)
{ {
return reinterpret_cast<HandleSlot>(node); return reinterpret_cast<HandleSlot>(node);
......
...@@ -35,65 +35,43 @@ ...@@ -35,65 +35,43 @@
outside of any LocalScope. outside of any LocalScope.
*/ */
namespace JSC {
template <typename T> class Local;
}
namespace WTF {
template<typename T> struct VectorTraits<JSC::Local<T> > {
static const bool needsDestruction = false;
static const bool needsInitialization = true;
static const bool canInitializeWithMemset = false;
static const bool canMoveWithMemcpy = true;
static const bool canCopyWithMemcpy = false;
static const bool canFillWithMemset = false;
static const bool canCompareWithMemcmp = true;
};
}
namespace JSC { namespace JSC {
template <typename T> class Local : public Handle<T> { template <typename T> class Local : public Handle<T> {
friend class LocalScope; friend class LocalScope;
using Handle<T>::slot;
public: public:
typedef typename Handle<T>::ExternalType ExternalType; typedef typename Handle<T>::ExternalType ExternalType;
Local(JSGlobalData&, ExternalType = ExternalType());