mirror of
https://github.com/Samsung/escargot.git
synced 2026-06-22 10:01:50 +00:00
Add reference counter in CompressibleString
* remove stack searching to check if CompressibleString is in use * add ref counter instead Signed-off-by: HyukWoo Park <hyukwoo.park@samsung.com>
This commit is contained in:
parent
73e5e66b4a
commit
b51839b7b9
4 changed files with 30 additions and 26 deletions
|
|
@ -47,6 +47,7 @@ CompressibleString::CompressibleString(VMInstance* instance)
|
|||
: String()
|
||||
, m_isOwnerMayFreed(false)
|
||||
, m_isCompressed(false)
|
||||
, m_refCount(0)
|
||||
, m_vmInstance(instance)
|
||||
, m_lastUsedTickcount(fastTickCount())
|
||||
{
|
||||
|
|
@ -56,6 +57,7 @@ CompressibleString::CompressibleString(VMInstance* instance)
|
|||
v.push_back(this);
|
||||
GC_REGISTER_FINALIZER_NO_ORDER(this, [](void* obj, void*) {
|
||||
CompressibleString* self = (CompressibleString*)obj;
|
||||
ASSERT(self->refCount() == 0);
|
||||
if (self->isCompressed()) {
|
||||
self->clearCompressedData();
|
||||
} else {
|
||||
|
|
@ -158,7 +160,8 @@ void CompressibleString::clearCompressedData()
|
|||
bool CompressibleString::compress()
|
||||
{
|
||||
ASSERT(!m_isCompressed);
|
||||
if (UNLIKELY(!m_bufferData.length)) {
|
||||
if (UNLIKELY(!m_bufferData.length || !!m_refCount)) {
|
||||
ESCARGOT_LOG_INFO("Compression Failed due to string usage in stack\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -188,23 +191,10 @@ void CompressibleString::decompress()
|
|||
constexpr static const size_t g_compressChunkSize = 1044465;
|
||||
static_assert(LZ4_COMPRESSBOUND(g_compressChunkSize) == 1024 * 1024, "");
|
||||
|
||||
static ATTRIBUTE_NO_SANITIZE_ADDRESS bool testPointerExistsOnStack(size_t* start, size_t* end, const void* ptr)
|
||||
{
|
||||
while (start != end) {
|
||||
if (UNLIKELY(*start == (size_t)ptr)) {
|
||||
// if there is reference on stack, we cannot compress string.
|
||||
return true;
|
||||
}
|
||||
start++;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename StringType>
|
||||
bool CompressibleString::compressWorker(void* callerSP)
|
||||
{
|
||||
ASSERT(!m_isCompressed);
|
||||
ASSERT(!m_isCompressed && !m_refCount);
|
||||
ASSERT(m_bufferData.length > 0);
|
||||
|
||||
#if defined(STACK_GROWS_DOWN)
|
||||
|
|
@ -215,11 +205,6 @@ bool CompressibleString::compressWorker(void* callerSP)
|
|||
size_t* end = (size_t*)((size_t)callerSP & ~(sizeof(size_t) - 1));
|
||||
#endif
|
||||
|
||||
if (testPointerExistsOnStack(start, end, m_bufferData.buffer)) {
|
||||
ESCARGOT_LOG_INFO("Compression Failed due to string usage in stack\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t originByteLength = m_bufferData.length * sizeof(StringType);
|
||||
int lastBoundLength = 0;
|
||||
char* tempBuffer = nullptr;
|
||||
|
|
|
|||
|
|
@ -78,7 +78,8 @@ public:
|
|||
if (isCompressed()) {
|
||||
decompress();
|
||||
}
|
||||
return StringBufferAccessData(m_bufferData.has8BitContent, m_bufferData.length, const_cast<void*>(m_bufferData.buffer));
|
||||
|
||||
return StringBufferAccessData(m_bufferData.has8BitContent, m_bufferData.length, const_cast<void*>(m_bufferData.buffer), &m_refCount);
|
||||
}
|
||||
|
||||
bool isCompressed()
|
||||
|
|
@ -86,6 +87,11 @@ public:
|
|||
return m_isCompressed;
|
||||
}
|
||||
|
||||
size_t refCount()
|
||||
{
|
||||
return m_refCount;
|
||||
}
|
||||
|
||||
void* operator new(size_t);
|
||||
void* operator new[](size_t) = delete;
|
||||
void operator delete[](void*) = delete;
|
||||
|
|
@ -118,6 +124,7 @@ private:
|
|||
|
||||
bool m_isOwnerMayFreed;
|
||||
bool m_isCompressed;
|
||||
size_t m_refCount; // reference count representing the usage of this CompressibleString
|
||||
VMInstance* m_vmInstance;
|
||||
uint64_t m_lastUsedTickcount;
|
||||
typedef Vector<CompressedElement, GCUtil::gc_malloc_allocator<CompressedElement>> CompressedDataVector;
|
||||
|
|
|
|||
|
|
@ -100,12 +100,27 @@ struct StringBufferAccessData {
|
|||
};
|
||||
void* extraData;
|
||||
|
||||
StringBufferAccessData(bool has8Bit, size_t len, void* buffer, void* extraDataKeepInStack = nullptr)
|
||||
StringBufferAccessData(bool has8Bit, size_t len, void* buffer, void* extraDataToKeep = nullptr)
|
||||
: has8BitContent(has8Bit)
|
||||
, length(len)
|
||||
, buffer(buffer)
|
||||
, extraData(extraDataKeepInStack)
|
||||
, extraData(extraDataToKeep)
|
||||
{
|
||||
if (extraData) {
|
||||
// increase refCount in CompressibleString
|
||||
size_t& count = *reinterpret_cast<size_t*>(extraData);
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
~StringBufferAccessData()
|
||||
{
|
||||
if (extraData) {
|
||||
// decrease refCount in CompressibleString
|
||||
size_t& count = *reinterpret_cast<size_t*>(extraData);
|
||||
ASSERT(count > 0);
|
||||
count--;
|
||||
}
|
||||
}
|
||||
|
||||
char16_t uncheckedCharAtFor8Bit(size_t idx) const
|
||||
|
|
|
|||
|
|
@ -139,9 +139,6 @@ protected:
|
|||
ASSERT(m_bufferData.hasSpecialImpl);
|
||||
|
||||
StringBufferAccessData r = m_bufferData.bufferAsString->bufferAccessData();
|
||||
// keep original buffer pointer in stack
|
||||
// without this, compressible string can free this pointer
|
||||
r.extraData = const_cast<void*>(r.buffer);
|
||||
r.length = m_bufferData.length;
|
||||
if (r.has8BitContent) {
|
||||
r.bufferAs8Bit += m_start;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue