]> git.saurik.com Git - apple/javascriptcore.git/blobdiff - runtime/RegExpCache.cpp
JavaScriptCore-1218.34.tar.gz
[apple/javascriptcore.git] / runtime / RegExpCache.cpp
index 5e9d610c74bea4c9b93c79127e41a5c8602b0b5c..1ab3f5f515ce09281b2267819cc977c77bdc0118 100644 (file)
@@ -1,6 +1,7 @@
 /*
  * 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();
+    }
 }
 
 }