summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/Collector.cpp7
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/Collector.h2
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/wtf/symbian/BlockAllocatorSymbian.cpp104
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/wtf/symbian/BlockAllocatorSymbian.h15
4 files changed, 88 insertions, 40 deletions
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Collector.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Collector.cpp
index a7744dde72..6af1784139 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Collector.cpp
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Collector.cpp
@@ -135,10 +135,10 @@ Heap::Heap(JSGlobalData* globalData)
, m_registeredThreads(0)
, m_currentThreadRegistrar(0)
#endif
- , m_globalData(globalData)
#if OS(SYMBIAN)
- , m_blockallocator(JSCCOLLECTOR_VIRTUALMEM_RESERVATION, BLOCK_SIZE)
+ , m_blockallocator(WTF::AlignedBlockAllocator::instance(JSCCOLLECTOR_VIRTUALMEM_RESERVATION, BLOCK_SIZE))
#endif
+ , m_globalData(globalData)
{
ASSERT(globalData);
memset(&m_heap, 0, sizeof(CollectorHeap));
@@ -183,9 +183,6 @@ void Heap::destroy()
t = next;
}
#endif
-#if OS(SYMBIAN)
- m_blockallocator.destroy();
-#endif
m_globalData = 0;
}
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Collector.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Collector.h
index d3616dc449..9c6ffa7c47 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Collector.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Collector.h
@@ -173,7 +173,7 @@ namespace JSC {
#if OS(SYMBIAN)
// Allocates collector blocks with correct alignment
- WTF::AlignedBlockAllocator m_blockallocator;
+ WTF::AlignedBlockAllocator& m_blockallocator;
#endif
JSGlobalData* m_globalData;
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/symbian/BlockAllocatorSymbian.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/symbian/BlockAllocatorSymbian.cpp
index 6a28e9ef4f..f09bf8e123 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/symbian/BlockAllocatorSymbian.cpp
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/symbian/BlockAllocatorSymbian.cpp
@@ -31,7 +31,7 @@
#if OS(SYMBIAN)
#include "BlockAllocatorSymbian.h"
-
+#include <e32atomics.h>
namespace WTF {
@@ -43,40 +43,56 @@ AlignedBlockAllocator::AlignedBlockAllocator(TUint32 reservationSize, TUint32 bl
: m_reservation(reservationSize),
m_blockSize(blockSize)
{
+ TInt err = m_lock.CreateLocal();
+ __ASSERT_ALWAYS(m_map.bits, User::Panic(_L("AlignedBlkAlloc0"), err));
+
+ // Get system's page size value.
+ SYMBIAN_PAGESIZE(m_pageSize);
+
+ // We only accept multiples of system page size for both initial reservation and the alignment/block size
+ m_reservation = SYMBIAN_ROUNDUPTOMULTIPLE(m_reservation, m_pageSize);
+ __ASSERT_ALWAYS(SYMBIAN_ROUNDUPTOMULTIPLE(m_blockSize, m_pageSize), User::Panic(_L("AlignedBlkAlloc1"), KErrArgument));
- // Get system's page size value.
- SYMBIAN_PAGESIZE(m_pageSize);
-
- // We only accept multiples of system page size for both initial reservation and the alignment/block size
- m_reservation = SYMBIAN_ROUNDUPTOMULTIPLE(m_reservation, m_pageSize);
- __ASSERT_ALWAYS(SYMBIAN_ROUNDUPTOMULTIPLE(m_blockSize, m_pageSize), User::Panic(_L("AlignedBlockAllocator1"), KErrArgument));
-
- // Calculate max. bit flags we need to carve a reservationSize range into blockSize-sized blocks
- m_map.numBits = m_reservation / m_blockSize;
- const TUint32 bitsPerWord = 8*sizeof(TUint32);
- const TUint32 numWords = (m_map.numBits + bitsPerWord -1) / bitsPerWord;
-
- m_map.bits = new TUint32[numWords];
- __ASSERT_ALWAYS(m_map.bits, User::Panic(_L("AlignedBlockAllocator2"), KErrNoMemory));
- m_map.clearAll();
-
- // Open a Symbian RChunk, and reserve requested virtual address range
- // Any thread in this process can operate this rchunk due to EOwnerProcess access rights.
- TInt ret = m_chunk.CreateDisconnectedLocal(0 , 0, (TInt)m_reservation , EOwnerProcess);
- if (ret != KErrNone)
- User::Panic(_L("AlignedBlockAllocator3"), ret);
-
- // This is the offset to m_chunk.Base() required to make it m_blockSize-aligned
- m_offset = SYMBIAN_ROUNDUPTOMULTIPLE(TUint32(m_chunk.Base()), m_blockSize) - TUint(m_chunk.Base());
+ // Calculate max. bit flags we need to carve a reservationSize range into blockSize-sized blocks
+ m_map.numBits = m_reservation / m_blockSize;
+ const TUint32 bitsPerWord = 8*sizeof(TUint32);
+ const TUint32 numWords = (m_map.numBits + bitsPerWord -1) / bitsPerWord;
+
+ m_map.bits = new TUint32[numWords];
+ __ASSERT_ALWAYS(m_map.bits, User::Panic(_L("AlignedBlkAlloc2"), KErrNoMemory));
+ m_map.clearAll();
+ // Open a Symbian RChunk, and reserve requested virtual address range
+ // Any thread in this process can operate this rchunk due to EOwnerProcess access rights.
+ TInt ret = m_chunk.CreateDisconnectedLocal(0 , 0, (TInt)m_reservation , EOwnerProcess);
+ if (ret != KErrNone)
+ User::Panic(_L("AlignedBlkAlloc3"), ret);
+
+ // This is the offset to m_chunk.Base() required to make it m_blockSize-aligned
+ m_offset = SYMBIAN_ROUNDUPTOMULTIPLE(TUint32(m_chunk.Base()), m_blockSize) - TUint(m_chunk.Base());
}
-void* AlignedBlockAllocator::alloc()
+struct AlignedBlockAllocatorScopeLock
{
+ RFastLock& lock;
+ AlignedBlockAllocatorScopeLock(RFastLock& aLock) : lock(aLock)
+ {
+ lock.Wait();
+ }
+ ~AlignedBlockAllocatorScopeLock()
+ {
+ lock.Signal();
+ }
+};
+void* AlignedBlockAllocator::alloc()
+{
TInt freeRam = 0;
void* address = 0;
-
+
+ // lock until this function returns
+ AlignedBlockAllocatorScopeLock lock(m_lock);
+
// Look up first free slot in bit map
const TInt freeIdx = m_map.findFree();
@@ -100,11 +116,14 @@ void* AlignedBlockAllocator::alloc()
void AlignedBlockAllocator::free(void* block)
{
+ // lock until this function returns
+ AlignedBlockAllocatorScopeLock lock(m_lock);
+
// Calculate index of block to be freed
TInt idx = TUint(static_cast<TUint8*>(block) - m_chunk.Base() - m_offset) / m_blockSize;
- __ASSERT_DEBUG(idx >= 0 && idx < m_map.numBits, User::Panic(_L("AlignedBlockAllocator4"), KErrCorrupt)); // valid index check
- __ASSERT_DEBUG(m_map.get(idx), User::Panic(_L("AlignedBlockAllocator5"), KErrCorrupt)); // in-use flag check
+ __ASSERT_DEBUG(idx >= 0 && idx < m_map.numBits, User::Panic(_L("AlignedBlkAlloc4"), KErrCorrupt)); // valid index check
+ __ASSERT_DEBUG(m_map.get(idx), User::Panic(_L("AlignedBlkAlloc5"), KErrCorrupt)); // in-use flag check
// Return committed region to system RAM pool (the physical RAM becomes usable by others)
TInt ret = m_chunk.Decommit(m_offset + m_blockSize * idx, m_blockSize);
@@ -127,6 +146,33 @@ AlignedBlockAllocator::~AlignedBlockAllocator()
delete [] m_map.bits;
}
+struct AlignedBlockAllocatorPtr
+{
+ AlignedBlockAllocator* ptr;
+ ~AlignedBlockAllocatorPtr()
+ {
+ delete ptr;
+ ptr = 0;
+ }
+};
+
+AlignedBlockAllocator& AlignedBlockAllocator::instance(TUint32 reservationSize, TUint32 blockSize)
+{
+ // static cleanup for plugin unload case where leaking this much address space would not be good.
+ static AlignedBlockAllocatorPtr pAllocator;
+ // static data is zero initialized, so using zero to indicate not-yet-created.
+ if (!pAllocator.ptr)
+ {
+ AlignedBlockAllocator* newAllocator = new AlignedBlockAllocator(reservationSize, blockSize);
+ AlignedBlockAllocator* expected = 0;
+ // atomic if (pAllocator == 0) pAllocator = newAllocator; else delete newAllocator;
+ if (!__e32_atomic_cas_ord_ptr(&pAllocator.ptr, &expected, newAllocator))
+ delete newAllocator;
+ __ASSERT_ALWAYS(pAllocator.ptr, User::Panic(_L("AlignedBlkAlloc6"), KErrNoMemory));
+ }
+ return *pAllocator.ptr;
+}
+
} // end of namespace
#endif // SYMBIAN
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/symbian/BlockAllocatorSymbian.h b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/symbian/BlockAllocatorSymbian.h
index 21422f6208..5f1a8cab07 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/symbian/BlockAllocatorSymbian.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/symbian/BlockAllocatorSymbian.h
@@ -60,18 +60,22 @@ namespace WTF {
*/
class AlignedBlockAllocator {
public:
+ static AlignedBlockAllocator& instance(TUint32 reservationSize, TUint32 blockSize);
+ void* alloc();
+ void free(void* data);
+
+ private:
AlignedBlockAllocator(TUint32 reservationSize, TUint32 blockSize);
~AlignedBlockAllocator();
void destroy();
- void* alloc();
- void free(void* data);
-
- private:
+
+ private:
RChunk m_chunk; // Symbian chunk that lets us reserve/commit/decommit
TUint m_offset; // offset of first committed region from base
TInt m_pageSize; // cached value of system page size, typically 4K on Symbian
TUint32 m_reservation;
- TUint32 m_blockSize;
+ TUint32 m_blockSize;
+ RFastLock m_lock;
// Tracks comitted/decommitted state of a blockSize region
struct {
@@ -111,6 +115,7 @@ class AlignedBlockAllocator {
} m_map;
+ friend class AlignedBlockAllocatorPtr;
};
}