/*
* Copyright (C) 2010 University of Szeged
* Copyright (C) 2010 Renata Hodovan (hodovan@inf.u-szeged.hu)
+ * Copyright (C) 2012 Apple Inc. All rights reserved.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
*/
#include "config.h"
-
#include "RegExpCache.h"
+#include "Operations.h"
+#include "RegExpObject.h"
+#include "StrongInlines.h"
+
namespace JSC {
-PassRefPtr<RegExp> RegExpCache::lookupOrCreate(const UString& patternString, const UString& flags)
+RegExp* RegExpCache::lookupOrCreate(const String& patternString, RegExpFlags flags)
{
- if (isCacheable(patternString)) {
- pair<HashMap<RegExpKey, RefPtr<RegExp> >::iterator, bool> result = m_cacheMap.add(RegExpKey(flags, patternString), 0);
- if (!result.second)
- return result.first->second;
- }
- return create(patternString, flags);
-}
+ RegExpKey key(flags, patternString);
+ if (RegExp* regExp = m_weakCache.get(key))
+ return regExp;
-PassRefPtr<RegExp> RegExpCache::create(const UString& patternString, const UString& flags)
-{
- RefPtr<RegExp> regExp;
+ RegExp* regExp = RegExp::createWithoutCaching(*m_vm, patternString, flags);
+#if ENABLE(REGEXP_TRACING)
+ m_vm->addRegExpToTrace(regExp);
+#endif
- if (!flags.isNull())
- regExp = RegExp::create(m_globalData, patternString, flags);
- else
- regExp = RegExp::create(m_globalData, patternString);
+ weakAdd(m_weakCache, key, PassWeak<RegExp>(regExp, this));
+ return regExp;
+}
- if (patternString.size() >= maxCacheablePatternLength)
- return regExp;
+RegExpCache::RegExpCache(VM* vm)
+ : m_nextEntryInStrongCache(0)
+ , m_vm(vm)
+{
+}
- ++m_nextKeyToEvict;
- if (m_nextKeyToEvict == maxCacheableEntries) {
- m_nextKeyToEvict = 0;
- m_isFull = true;
- }
- if (m_isFull)
- m_cacheMap.remove(RegExpKey(patternKeyArray[m_nextKeyToEvict].flagsValue, patternKeyArray[m_nextKeyToEvict].pattern));
+void RegExpCache::finalize(Handle<Unknown> handle, void*)
+{
+ RegExp* regExp = static_cast<RegExp*>(handle.get().asCell());
+ weakRemove(m_weakCache, regExp->key(), regExp);
+ regExp->invalidateCode();
+}
- RegExpKey key = RegExpKey(flags, patternString);
- m_cacheMap.set(key, regExp);
- patternKeyArray[m_nextKeyToEvict].flagsValue = key.flagsValue;
- patternKeyArray[m_nextKeyToEvict].pattern = patternString.rep();
- return regExp;
+void RegExpCache::addToStrongCache(RegExp* regExp)
+{
+ String pattern = regExp->pattern();
+ if (pattern.length() > maxStrongCacheablePatternLength)
+ return;
+ m_strongCache[m_nextEntryInStrongCache].set(*m_vm, regExp);
+ m_nextEntryInStrongCache++;
+ if (m_nextEntryInStrongCache == maxStrongCacheableEntries)
+ m_nextEntryInStrongCache = 0;
}
-RegExpCache::RegExpCache(JSGlobalData* globalData)
- : m_globalData(globalData)
- , m_nextKeyToEvict(-1)
- , m_isFull(false)
+void RegExpCache::invalidateCode()
{
+ for (int i = 0; i < maxStrongCacheableEntries; i++)
+ m_strongCache[i].clear();
+ m_nextEntryInStrongCache = 0;
+
+ RegExpCacheMap::iterator end = m_weakCache.end();
+ for (RegExpCacheMap::iterator it = m_weakCache.begin(); it != end; ++it) {
+ RegExp* regExp = it->value.get();
+ if (!regExp) // Skip zombies.
+ continue;
+ regExp->invalidateCode();
+ }
}
}