Commit b34a1489 authored by levin@chromium.org's avatar levin@chromium.org
Browse files

JavaScriptCore:

2009-05-25  David Levin  <levin@chromium.org>

        Reviewed by Maciej Stachowiak and Oliver Hunt.

        https://bugs.webkit.org/show_bug.cgi?id=25126
        Allow the buffer underlying UString to be shared.

        In order to not grow the underlying size of any structure,
        there is a union in the Rep string which holds
         + m_sharedBuffer -- a pointer to the shared ref counted buffer
           if the class is BaseString and the buffer is being shared OR
         + m_baseString -- the BaseString if the class is only UString::Rep
           but not a UString::BaseString

        Ideally, m_sharedBuffer would be a RefPtr, but it cannot be because
        it is in a union.

        No change in sunspider perf.

        * JavaScriptCore.vcproj/WTF/WTF.vcproj:
        * JavaScriptCore.xcodeproj/project.pbxproj:
        * runtime/UString.cpp:
        (JSC::UString::Rep::share):
        (JSC::UString::Rep::destroy):
        (JSC::UString::BaseString::sharedBuffer):
        ...
parent 7b8ca75f
2009-05-25 David Levin <levin@chromium.org>
Reviewed by Maciej Stachowiak and Oliver Hunt.
https://bugs.webkit.org/show_bug.cgi?id=25126
Allow the buffer underlying UString to be shared.
In order to not grow the underlying size of any structure,
there is a union in the Rep string which holds
+ m_sharedBuffer -- a pointer to the shared ref counted buffer
if the class is BaseString and the buffer is being shared OR
+ m_baseString -- the BaseString if the class is only UString::Rep
but not a UString::BaseString
Ideally, m_sharedBuffer would be a RefPtr, but it cannot be because
it is in a union.
No change in sunspider perf.
* JavaScriptCore.vcproj/WTF/WTF.vcproj:
* JavaScriptCore.xcodeproj/project.pbxproj:
* runtime/UString.cpp:
(JSC::UString::Rep::share):
(JSC::UString::Rep::destroy):
(JSC::UString::BaseString::sharedBuffer):
(JSC::UString::BaseString::setSharedBuffer):
(JSC::UString::BaseString::slowIsBufferReadOnly):
(JSC::expandCapacity):
(JSC::UString::Rep::reserveCapacity):
(JSC::UString::expandPreCapacity):
(JSC::concatenate):
(JSC::UString::append):
* runtime/UString.h:
(JSC::UString::Rep::Rep):
(JSC::UString::Rep::):
(JSC::UString::BaseString::isShared):
(JSC::UString::BaseString::isBufferReadOnly):
(JSC::UString::Rep::baseString):
* wtf/CrossThreadRefCounted.h:
(WTF::CrossThreadRefCounted::isShared):
* wtf/OwnFastMallocPtr.h: Added.
(WTF::OwnFastMallocPtr::OwnFastMallocPtr):
(WTF::OwnFastMallocPtr::~OwnFastMallocPtr):
(WTF::OwnFastMallocPtr::get):
(WTF::OwnFastMallocPtr::release):
2009-05-25 Oliver Hunt <oliver@apple.com>
 
Reviewed by Maciej Stachowiak.
......@@ -220,6 +220,10 @@
RelativePath="..\..\wtf\unicode\icu\CollatorICU.cpp"
>
</File>
<File
RelativePath="..\..\wtf\CrossThreadRefCounted.h"
>
</File>
<File
RelativePath="..\..\wtf\CurrentTime.cpp"
>
......@@ -332,6 +336,10 @@
RelativePath="..\..\wtf\OwnArrayPtr.h"
>
</File>
<File
RelativePath="..\..\wtf\OwnFastMallocPtr.h"
>
</File>
<File
RelativePath="..\..\wtf\OwnPtr.h"
>
......
......@@ -42,6 +42,8 @@
0B1F921D0F1753500036468E /* PtrAndFlags.h in Headers */ = {isa = PBXBuildFile; fileRef = 0B1F921B0F17502D0036468E /* PtrAndFlags.h */; settings = {ATTRIBUTES = (Private, ); }; };
0B330C270F38C62300692DE3 /* TypeTraits.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0B330C260F38C62300692DE3 /* TypeTraits.cpp */; };
0B4D7E630F319AC800AD7E58 /* TypeTraits.h in Headers */ = {isa = PBXBuildFile; fileRef = 0B4D7E620F319AC800AD7E58 /* TypeTraits.h */; settings = {ATTRIBUTES = (Private, ); }; };
0BDFFAE00FC6192900D69EF4 /* CrossThreadRefCounted.h in Headers */ = {isa = PBXBuildFile; fileRef = 0BDFFAD40FC6171000D69EF4 /* CrossThreadRefCounted.h */; settings = {ATTRIBUTES = (Private, ); }; };
0BDFFAE10FC6193100D69EF4 /* OwnFastMallocPtr.h in Headers */ = {isa = PBXBuildFile; fileRef = 0BDFFAD10FC616EC00D69EF4 /* OwnFastMallocPtr.h */; settings = {ATTRIBUTES = (Private, ); }; };
140B7D1D0DC69AF7009C42B8 /* JSActivation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 14DA818F0D99FD2000B0A4FB /* JSActivation.cpp */; };
140D17D70E8AD4A9000CD17D /* JSBasePrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 140D17D60E8AD4A9000CD17D /* JSBasePrivate.h */; settings = {ATTRIBUTES = (Private, ); }; };
141211310A48794D00480255 /* JavaScriptCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 932F5BD90822A1C700736975 /* JavaScriptCore.framework */; };
......@@ -455,6 +457,8 @@
0B1F921B0F17502D0036468E /* PtrAndFlags.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PtrAndFlags.h; sourceTree = "<group>"; };
0B330C260F38C62300692DE3 /* TypeTraits.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TypeTraits.cpp; sourceTree = "<group>"; };
0B4D7E620F319AC800AD7E58 /* TypeTraits.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TypeTraits.h; sourceTree = "<group>"; };
0BDFFAD10FC616EC00D69EF4 /* OwnFastMallocPtr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OwnFastMallocPtr.h; sourceTree = "<group>"; };
0BDFFAD40FC6171000D69EF4 /* CrossThreadRefCounted.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CrossThreadRefCounted.h; sourceTree = "<group>"; };
140D17D60E8AD4A9000CD17D /* JSBasePrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSBasePrivate.h; sourceTree = "<group>"; };
141211020A48780900480255 /* minidom.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = minidom.c; path = tests/minidom.c; sourceTree = "<group>"; };
1412110D0A48788700480255 /* minidom.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = minidom.js; path = tests/minidom.js; sourceTree = "<group>"; };
......@@ -1161,6 +1165,7 @@
E1A596370DE3E1C300C17E37 /* AVLTree.h */,
A7A1F7AA0F252B3C00E184E2 /* ByteArray.cpp */,
A7A1F7AB0F252B3C00E184E2 /* ByteArray.h */,
0BDFFAD40FC6171000D69EF4 /* CrossThreadRefCounted.h */,
180B9AEF0F16C569009BDBC5 /* CurrentTime.cpp */,
180B9AF00F16C569009BDBC5 /* CurrentTime.h */,
5186111D0CC824830081412B /* Deque.h */,
......@@ -1192,6 +1197,7 @@
9303F5690991190000AD71B8 /* Noncopyable.h */,
C0A2723F0E509F1E00E96E15 /* NotFound.h */,
9303F5A409911A5800AD71B8 /* OwnArrayPtr.h */,
0BDFFAD10FC616EC00D69EF4 /* OwnFastMallocPtr.h */,
9303F567099118FA00AD71B8 /* OwnPtr.h */,
440B7AED0FAF7FCB0073323E /* OwnPtrCommon.h */,
44DD48520FAEA85000D6B4EB /* PassOwnPtr.h */,
......@@ -1829,6 +1835,8 @@
A7E2EA6B0FB460CF00601F06 /* LiteralParser.h in Headers */,
93052C350FB792190048FDC3 /* ParserArena.h in Headers */,
960626960FB8EC02009798AB /* JITStubCall.h in Headers */,
0BDFFAE00FC6192900D69EF4 /* CrossThreadRefCounted.h in Headers */,
0BDFFAE10FC6193100D69EF4 /* OwnFastMallocPtr.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
......
/*
* Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
* Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
* Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
* Copyright (C) 2007 Cameron Zwarich (cwzwarich@uwaterloo.ca)
* Copyright (c) 2009, Google Inc. All rights reserved.
* Copyright (C) 2009 Google Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
......@@ -232,6 +232,14 @@ PassRefPtr<UString::Rep> UString::Rep::createFromUTF8(const char* string)
return UString::Rep::createCopying(buffer.data(), p - buffer.data());
}
PassRefPtr<UString::Rep> UString::Rep::share(UChar* string, int length, PassRefPtr<UString::SharedUChar> sharedBuffer)
{
PassRefPtr<UString::Rep> rep = create(string, length);
rep->baseString()->setSharedBuffer(sharedBuffer);
rep->checkConsistency();
return rep;
}
void UString::Rep::destroy()
{
checkConsistency();
......@@ -241,10 +249,14 @@ void UString::Rep::destroy()
if (!isStatic()) {
if (identifierTable())
Identifier::remove(this);
UString::BaseString* base = baseString();
if (base == this)
fastFree(base->buf);
else
if (base == this) {
if (m_sharedBuffer)
m_sharedBuffer->deref();
else
fastFree(base->buf);
} else
base->deref();
delete this;
......@@ -368,6 +380,42 @@ void UString::Rep::checkConsistency() const
}
#endif
UString::SharedUChar* UString::BaseString::sharedBuffer()
{
// Don't share empty, null and 1 character strings from SmallStrings.
if (len <= 1)
return 0;
if (!m_sharedBuffer)
setSharedBuffer(SharedUChar::create(new OwnFastMallocPtr<UChar>(buf)));
return m_sharedBuffer;
}
void UString::BaseString::setSharedBuffer(PassRefPtr<UString::SharedUChar> sharedBuffer)
{
// The manual steps below are because m_sharedBuffer can't be a RefPtr. m_sharedBuffer
// is in a union with another variable to avoid making BaseString any larger.
if (m_sharedBuffer)
m_sharedBuffer->deref();
m_sharedBuffer = sharedBuffer.releaseRef();
}
bool UString::BaseString::slowIsBufferReadOnly()
{
// The buffer may not be modified as soon as the underlying data has been shared with another class.
if (m_sharedBuffer->isShared())
return true;
// At this point, we know it that the underlying buffer isn't shared outside of this base class,
// so get rid of m_sharedBuffer.
OwnPtr<OwnFastMallocPtr<UChar> > mallocPtr(m_sharedBuffer->release());
UChar* unsharedBuf = const_cast<UChar*>(mallocPtr->release());
setSharedBuffer(0);
preCapacity += (buf - unsharedBuf);
buf = unsharedBuf;
return false;
}
// Put these early so they can be inlined.
static inline size_t expandedSize(size_t capacitySize, size_t precapacitySize)
{
......@@ -417,6 +465,7 @@ static inline size_t expandedSize(size_t capacitySize, size_t precapacitySize)
static inline bool expandCapacity(UString::Rep* rep, int requiredLength)
{
rep->checkConsistency();
ASSERT(!rep->baseString()->isBufferReadOnly());
UString::BaseString* base = rep->baseString();
......@@ -442,23 +491,25 @@ bool UString::Rep::reserveCapacity(int capacity)
// If this is an empty string there is no point 'growing' it - just allocate a new one.
// If the BaseString is shared with another string that is using more capacity than this
// string is, then growing the buffer won't help.
if (!m_baseString->buf || !m_baseString->capacity || (offset + len) != m_baseString->usedCapacity)
// If the BaseString's buffer is readonly, then it isn't allowed to grow.
UString::BaseString* base = baseString();
if (!base->buf || !base->capacity || (offset + len) != base->usedCapacity || base->isBufferReadOnly())
return false;
// If there is already sufficient capacity, no need to grow!
if (capacity <= m_baseString->capacity)
if (capacity <= base->capacity)
return true;
checkConsistency();
size_t newCapacity = expandedSize(capacity, m_baseString->preCapacity);
UChar* oldBuf = m_baseString->buf;
m_baseString->buf = reallocChars(m_baseString->buf, newCapacity);
if (!m_baseString->buf) {
m_baseString->buf = oldBuf;
size_t newCapacity = expandedSize(capacity, base->preCapacity);
UChar* oldBuf = base->buf;
base->buf = reallocChars(base->buf, newCapacity);
if (!base->buf) {
base->buf = oldBuf;
return false;
}
m_baseString->capacity = newCapacity - m_baseString->preCapacity;
base->capacity = newCapacity - base->preCapacity;
checkConsistency();
return true;
......@@ -473,6 +524,7 @@ void UString::expandCapacity(int requiredLength)
void UString::expandPreCapacity(int requiredPreCap)
{
m_rep->checkConsistency();
ASSERT(!m_rep->baseString()->isBufferReadOnly());
BaseString* base = m_rep->baseString();
......@@ -585,7 +637,7 @@ static ALWAYS_INLINE PassRefPtr<UString::Rep> concatenate(PassRefPtr<UString::Re
rep->len = length;
rep->_hash = 0;
}
} else if (thisOffset + thisSize == base->usedCapacity && thisSize >= minShareSize) {
} else if (thisOffset + thisSize == base->usedCapacity && thisSize >= minShareSize && !base->isBufferReadOnly()) {
// this reaches the end of the buffer - extend it if it's long enough to append to
if (!expandCapacity(rep.get(), newCapacityWithOverflowCheck(thisOffset, length)))
rep = &UString::Rep::null();
......@@ -594,7 +646,7 @@ static ALWAYS_INLINE PassRefPtr<UString::Rep> concatenate(PassRefPtr<UString::Re
rep = UString::Rep::create(rep, 0, length);
}
} else {
// this is shared with someone using more capacity, gotta make a whole new string
// This is shared in some way that prevents us from modifying base, so we must make a whole new string.
size_t newCapacity = expandedSize(length, 0);
UChar* d = allocChars(newCapacity);
if (!d)
......@@ -640,7 +692,7 @@ static ALWAYS_INLINE PassRefPtr<UString::Rep> concatenate(PassRefPtr<UString::Re
rep->len = length;
rep->_hash = 0;
}
} else if (thisOffset + thisSize == base->usedCapacity && thisSize >= minShareSize) {
} else if (thisOffset + thisSize == base->usedCapacity && thisSize >= minShareSize && !base->isBufferReadOnly()) {
// this string reaches the end of the buffer - extend it
expandCapacity(rep.get(), newCapacityWithOverflowCheck(thisOffset, length));
UChar* d = rep->data();
......@@ -650,7 +702,7 @@ static ALWAYS_INLINE PassRefPtr<UString::Rep> concatenate(PassRefPtr<UString::Re
rep = UString::Rep::create(rep, 0, length);
}
} else {
// this is shared with someone using more capacity, gotta make a whole new string
// This is shared in some way that prevents us from modifying base, so we must make a whole new string.
size_t newCapacity = expandedSize(length, 0);
UChar* d = allocChars(newCapacity);
if (!d)
......@@ -681,7 +733,7 @@ PassRefPtr<UString::Rep> concatenate(UString::Rep* a, UString::Rep* b)
// possible cases:
UString::BaseString* aBase = a->baseString();
if (bSize == 1 && aOffset + aSize == aBase->usedCapacity && aOffset + aSize < aBase->capacity) {
if (bSize == 1 && aOffset + aSize == aBase->usedCapacity && aOffset + aSize < aBase->capacity && !aBase->isBufferReadOnly()) {
// b is a single character (common fast case)
++aBase->usedCapacity;
a->data()[aSize] = b->data()[0];
......@@ -700,7 +752,7 @@ PassRefPtr<UString::Rep> concatenate(UString::Rep* a, UString::Rep* b)
UString::BaseString* bBase = b->baseString();
if (aOffset + aSize == aBase->usedCapacity && aSize >= minShareSize && 4 * aSize >= bSize
&& (-bOffset != bBase->usedPreCapacity || aSize >= bSize)) {
&& (-bOffset != bBase->usedPreCapacity || aSize >= bSize) && !aBase->isBufferReadOnly()) {
// - a reaches the end of its buffer so it qualifies for shared append
// - also, it's at least a quarter the length of b - appending to a much shorter
// string does more harm than good
......@@ -720,7 +772,7 @@ PassRefPtr<UString::Rep> concatenate(UString::Rep* a, UString::Rep* b)
return result;
}
if (-bOffset == bBase->usedPreCapacity && bSize >= minShareSize && 4 * bSize >= aSize) {
if (-bOffset == bBase->usedPreCapacity && bSize >= minShareSize && 4 * bSize >= aSize && !bBase->isBufferReadOnly()) {
// - b reaches the beginning of its buffer so it qualifies for shared prepend
// - also, it's at least a quarter the length of a - prepending to a much shorter
// string does more harm than good
......@@ -1083,7 +1135,7 @@ UString& UString::append(const UString &t)
m_rep->len = length;
m_rep->_hash = 0;
}
} else if (thisOffset + thisSize == base->usedCapacity && thisSize >= minShareSize) {
} else if (thisOffset + thisSize == base->usedCapacity && thisSize >= minShareSize && !base->isBufferReadOnly()) {
// this reaches the end of the buffer - extend it if it's long enough to append to
expandCapacity(newCapacityWithOverflowCheck(thisOffset, length));
if (data()) {
......@@ -1091,7 +1143,7 @@ UString& UString::append(const UString &t)
m_rep = Rep::create(m_rep, 0, length);
}
} else {
// this is shared with someone using more capacity, gotta make a whole new string
// This is shared in some way that prevents us from modifying base, so we must make a whole new string.
size_t newCapacity = expandedSize(length, 0);
UChar* d = allocChars(newCapacity);
if (!d)
......@@ -1163,7 +1215,7 @@ UString& UString::append(UChar c)
m_rep->len = length + 1;
m_rep->_hash = 0;
}
} else if (thisOffset + length == base->usedCapacity && length >= minShareSize) {
} else if (thisOffset + length == base->usedCapacity && length >= minShareSize && !base->isBufferReadOnly()) {
// this reaches the end of the string - extend it and share
expandCapacity(newCapacityWithOverflowCheck(thisOffset, length, true));
UChar* d = m_rep->data();
......@@ -1172,7 +1224,7 @@ UString& UString::append(UChar c)
m_rep = Rep::create(m_rep, 0, length + 1);
}
} else {
// this is shared with someone using more capacity, gotta make a whole new string
// This is shared in some way that prevents us from modifying base, so we must make a whole new string.
size_t newCapacity = expandedSize(length + 1, 0);
UChar* d = allocChars(newCapacity);
if (!d)
......
/*
* Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
* Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
* Copyright (c) 2009, Google Inc. All rights reserved.
* Copyright (C) 2009 Google Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
......@@ -27,6 +27,8 @@
#include <stdint.h>
#include <string.h>
#include <wtf/Assertions.h>
#include <wtf/CrossThreadRefCounted.h>
#include <wtf/OwnFastMallocPtr.h>
#include <wtf/PassRefPtr.h>
#include <wtf/PtrAndFlags.h>
#include <wtf/RefPtr.h>
......@@ -75,6 +77,7 @@ namespace JSC {
friend class JIT;
public:
typedef CrossThreadRefCounted<OwnFastMallocPtr<UChar> > SharedUChar;
struct BaseString;
struct Rep : Noncopyable {
friend class JIT;
......@@ -101,6 +104,9 @@ namespace JSC {
// Returns UString::Rep::null for null input or conversion failure.
static PassRefPtr<Rep> createFromUTF8(const char*);
// Uses SharedUChar to have joint ownership over the UChar*.
static PassRefPtr<Rep> share(UChar*, int, PassRefPtr<SharedUChar>);
void destroy();
bool baseIsSelf() const { return m_identifierTableAndFlags.isFlagSet(BaseStringFlag); }
......@@ -145,13 +151,13 @@ namespace JSC {
bool reserveCapacity(int capacity);
protected:
// constructor for use by BaseString subclass; they are their own bases
// Constructor for use by BaseString subclass; they use the union with m_baseString for another purpose.
Rep(int length)
: offset(0)
, len(length)
, rc(1)
, _hash(0)
, m_baseString(static_cast<BaseString*>(this))
, m_baseString(0)
{
}
......@@ -165,8 +171,12 @@ namespace JSC {
checkConsistency();
}
BaseString* m_baseString;
union {
// If !baseIsSelf()
BaseString* m_baseString;
// If baseIsSelf()
SharedUChar* m_sharedBuffer;
};
private:
// For SmallStringStorage which allocates an array and does initialization manually.
......@@ -180,7 +190,16 @@ namespace JSC {
struct BaseString : public Rep {
bool isShared() { return rc != 1; }
bool isShared() { return rc != 1 || isBufferReadOnly(); }
void setSharedBuffer(PassRefPtr<SharedUChar>);
SharedUChar* sharedBuffer();
bool isBufferReadOnly()
{
if (!m_sharedBuffer)
return false;
return slowIsBufferReadOnly();
}
// potentially shared data.
UChar* buf;
......@@ -205,6 +224,8 @@ namespace JSC {
checkConsistency();
}
bool slowIsBufferReadOnly();
friend struct Rep;
friend class SmallStringsStorage;
friend void initializeUString();
......@@ -453,12 +474,12 @@ namespace JSC {
inline UString::BaseString* UString::Rep::baseString()
{
return m_baseString;
return !baseIsSelf() ? m_baseString : reinterpret_cast<BaseString*>(this) ;
}
inline const UString::BaseString* UString::Rep::baseString() const
{
return m_baseString;
return const_cast<Rep*>(this)->baseString();
}
#ifdef NDEBUG
......
......@@ -35,7 +35,6 @@
#include <wtf/PassRefPtr.h>
#include <wtf/RefCounted.h>
#include <wtf/Threading.h>
#include <wtf/TypeTraits.h>
namespace WTF {
......@@ -66,6 +65,11 @@ namespace WTF {
void deref();
T* release();
bool isShared() const
{
return !m_refCounter.hasOneRef() || (m_threadSafeRefCounter && !m_threadSafeRefCounter->hasOneRef());
}
#ifndef NDEBUG
bool mayBePassedToAnotherThread() const { ASSERT(!m_threadId); return m_refCounter.hasOneRef(); }
#endif
......
/*
* Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
* Copyright (C) 2009 Google Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*
*/
#ifndef OwnFastMallocPtr_h
#define OwnFastMallocPtr_h
#include "FastMalloc.h"
#include "Noncopyable.h"
namespace WTF {
template<class T> class OwnFastMallocPtr : Noncopyable {
public:
explicit OwnFastMallocPtr(T* ptr) : m_ptr(ptr)
{
}
~OwnFastMallocPtr()
{
fastFree(m_ptr);
}
T* get() const { return m_ptr; }
T* release() { T* ptr = m_ptr; m_ptr = 0; return ptr; }
private:
T* m_ptr;
};
} // namespace WTF
using WTF::OwnFastMallocPtr;
#endif // OwnFastMallocPtr_h
2009-05-25 David Levin <levin@chromium.org>
Reviewed by Maciej Stachowiak and Oliver Hunt.
https://bugs.webkit.org/show_bug.cgi?id=25126
Added forwarding headers.
* ForwardingHeaders/wtf/CrossThreadRefCounted.h: Added.
* ForwardingHeaders/wtf/OwnFastMallocPtr.h: Added.
2009-05-23 David Kilzer <ddkilzer@apple.com>
Part 1 of 2: Bug 25495: Implement PassOwnPtr and replace uses of std::auto_ptr
......
#include <JavaScriptCore/CrossThreadRefCounted.h>
#include <JavaScriptCore/OwnFastMallocPtr.h>
2009-05-25 David Levin <levin@chromium.org>
Reviewed by Maciej Stachowiak and Oliver Hunt.
Added forwarding headers.
* ForwardingHeaders/wtf/CrossThreadRefCounted.h: Added.
* ForwardingHeaders/wtf/OwnFastMallocPtr.h: Added.
2009-05-25 Anders Carlsson <andersca@apple.com>
 
Reviewed by Sam Weinig.
#include <JavaScriptCore/CrossThreadRefCounted.h>
#include <JavaScriptCore/OwnFastMallocPtr.h>
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