summaryrefslogtreecommitdiffstats
path: root/JavaScriptCore/runtime
diff options
context:
space:
mode:
authorIain Merrick <husky@google.com>2010-09-13 16:35:48 +0100
committerIain Merrick <husky@google.com>2010-09-16 12:10:42 +0100
commit5abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306 (patch)
treeddce1aa5e3b6967a69691892e500897558ff8ab6 /JavaScriptCore/runtime
parent12bec63ec71e46baba27f0bd9bd9d8067683690a (diff)
downloadexternal_webkit-5abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306.zip
external_webkit-5abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306.tar.gz
external_webkit-5abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306.tar.bz2
Merge WebKit at r67178 : Initial merge by git.
Change-Id: I57e01163b6866cb029cdadf405a0394a3918bc18
Diffstat (limited to 'JavaScriptCore/runtime')
-rw-r--r--JavaScriptCore/runtime/InitializeThreading.cpp1
-rw-r--r--JavaScriptCore/runtime/JSGlobalData.cpp44
-rw-r--r--JavaScriptCore/runtime/JSGlobalData.h15
-rw-r--r--JavaScriptCore/runtime/RegExp.cpp99
-rw-r--r--JavaScriptCore/runtime/RegExp.h23
5 files changed, 154 insertions, 28 deletions
diff --git a/JavaScriptCore/runtime/InitializeThreading.cpp b/JavaScriptCore/runtime/InitializeThreading.cpp
index 33e8e68..08dddc1 100644
--- a/JavaScriptCore/runtime/InitializeThreading.cpp
+++ b/JavaScriptCore/runtime/InitializeThreading.cpp
@@ -58,6 +58,7 @@ static void initializeThreadingOnce()
#if ENABLE(JSC_MULTIPLE_THREADS)
s_dtoaP5Mutex = new Mutex;
initializeDates();
+ RegisterFile::initializeThreading();
#endif
}
diff --git a/JavaScriptCore/runtime/JSGlobalData.cpp b/JavaScriptCore/runtime/JSGlobalData.cpp
index 97f9be5..5eaa59b 100644
--- a/JavaScriptCore/runtime/JSGlobalData.cpp
+++ b/JavaScriptCore/runtime/JSGlobalData.cpp
@@ -51,6 +51,10 @@
#include "Parser.h"
#include "RegExpCache.h"
#include <wtf/WTFThreadData.h>
+#if ENABLE(REGEXP_TRACING)
+#include "RegExp.h"
+#endif
+
#if ENABLE(JSC_MULTIPLE_THREADS)
#include <wtf/Threading.h>
@@ -145,6 +149,9 @@ JSGlobalData::JSGlobalData(GlobalDataType globalDataType, ThreadStackType thread
, cachedUTCOffset(NaN)
, maxReentryDepth(threadStackType == ThreadStackTypeSmall ? MaxSmallThreadReentryDepth : MaxLargeThreadReentryDepth)
, m_regExpCache(new RegExpCache(this))
+#if ENABLE(REGEXP_TRACING)
+ , m_rtTraceList(new RTTraceList())
+#endif
#ifndef NDEBUG
, exclusiveThread(0)
#endif
@@ -218,6 +225,9 @@ JSGlobalData::~JSGlobalData()
delete clientData;
delete m_regExpCache;
+#if ENABLE(REGEXP_TRACING)
+ delete m_rtTraceList;
+#endif
}
PassRefPtr<JSGlobalData> JSGlobalData::createContextGroup(ThreadStackType type)
@@ -301,4 +311,38 @@ void JSGlobalData::dumpSampleData(ExecState* exec)
interpreter->dumpSampleData(exec);
}
+
+#if ENABLE(REGEXP_TRACING)
+void JSGlobalData::addRegExpToTrace(PassRefPtr<RegExp> regExp)
+{
+ m_rtTraceList->add(regExp);
+}
+
+void JSGlobalData::dumpRegExpTrace()
+{
+ // The first RegExp object is ignored. It is create by the RegExpPrototype ctor and not used.
+ RTTraceList::iterator iter = ++m_rtTraceList->begin();
+
+ if (iter != m_rtTraceList->end()) {
+ printf("\nRegExp Tracing\n");
+ printf(" match() matches\n");
+ printf("Regular Expression JIT Address calls found\n");
+ printf("----------------------------------------+----------------+----------+----------\n");
+
+ unsigned reCount = 0;
+
+ for (; iter != m_rtTraceList->end(); ++iter, ++reCount)
+ (*iter)->printTraceData();
+
+ printf("%d Regular Expressions\n", reCount);
+ }
+
+ m_rtTraceList->clear();
+}
+#else
+void JSGlobalData::dumpRegExpTrace()
+{
+}
+#endif
+
} // namespace JSC
diff --git a/JavaScriptCore/runtime/JSGlobalData.h b/JavaScriptCore/runtime/JSGlobalData.h
index 43c4bab..8e2ed61 100644
--- a/JavaScriptCore/runtime/JSGlobalData.h
+++ b/JavaScriptCore/runtime/JSGlobalData.h
@@ -46,6 +46,9 @@
#include <wtf/HashMap.h>
#include <wtf/RefCounted.h>
#include <wtf/ThreadSpecific.h>
+#if ENABLE(REGEXP_TRACING)
+#include <wtf/ListHashSet.h>
+#endif
struct OpaqueJSClass;
struct OpaqueJSClassContextData;
@@ -64,6 +67,9 @@ namespace JSC {
class Stringifier;
class Structure;
class UString;
+#if ENABLE(REGEXP_TRACING)
+ class RegExp;
+#endif
struct HashTable;
struct Instruction;
@@ -222,6 +228,11 @@ namespace JSC {
BumpPointerAllocator m_regexAllocator;
#endif
+#if ENABLE(REGEXP_TRACING)
+ typedef ListHashSet<RefPtr<RegExp> > RTTraceList;
+ RTTraceList* m_rtTraceList;
+#endif
+
#ifndef NDEBUG
ThreadIdentifier exclusiveThread;
#endif
@@ -234,6 +245,10 @@ namespace JSC {
void stopSampling();
void dumpSampleData(ExecState* exec);
RegExpCache* regExpCache() { return m_regExpCache; }
+#if ENABLE(REGEXP_TRACING)
+ void addRegExpToTrace(PassRefPtr<RegExp> regExp);
+#endif
+ void dumpRegExpTrace();
private:
JSGlobalData(GlobalDataType, ThreadStackType);
static JSGlobalData*& sharedInstanceInternal();
diff --git a/JavaScriptCore/runtime/RegExp.cpp b/JavaScriptCore/runtime/RegExp.cpp
index 5ad9f3f..d4545cb 100644
--- a/JavaScriptCore/runtime/RegExp.cpp
+++ b/JavaScriptCore/runtime/RegExp.cpp
@@ -46,11 +46,33 @@
namespace JSC {
+struct RegExpRepresentation {
+#if ENABLE(YARR_JIT)
+ Yarr::RegexCodeBlock m_regExpJITCode;
+#elif ENABLE(YARR)
+ OwnPtr<Yarr::BytecodePattern> m_regExpBytecode;
+#else
+ JSRegExp* m_regExp;
+#endif
+
+#if !ENABLE(YARR)
+ ~RegExpRepresentation()
+ {
+ jsRegExpFree(m_regExp);
+ }
+#endif
+};
+
inline RegExp::RegExp(JSGlobalData* globalData, const UString& pattern, const UString& flags)
: m_pattern(pattern)
, m_flagBits(0)
, m_constructionError(0)
, m_numSubpatterns(0)
+#if ENABLE(REGEXP_TRACING)
+ , m_rtMatchCallCount(0)
+ , m_rtMatchFoundCount(0)
+#endif
+ , m_representation(adoptPtr(new RegExpRepresentation))
{
// NOTE: The global flag is handled on a case-by-case basis by functions like
// String::match and RegExpObject::match.
@@ -65,16 +87,17 @@ inline RegExp::RegExp(JSGlobalData* globalData, const UString& pattern, const US
compile(globalData);
}
-#if !ENABLE(YARR)
RegExp::~RegExp()
{
- jsRegExpFree(m_regExp);
}
-#endif
PassRefPtr<RegExp> RegExp::create(JSGlobalData* globalData, const UString& pattern, const UString& flags)
{
- return adoptRef(new RegExp(globalData, pattern, flags));
+ RefPtr<RegExp> res = adoptRef(new RegExp(globalData, pattern, flags));
+#if ENABLE(REGEXP_TRACING)
+ globalData->addRegExpToTrace(res);
+#endif
+ return res.release();
}
#if ENABLE(YARR)
@@ -82,9 +105,9 @@ PassRefPtr<RegExp> RegExp::create(JSGlobalData* globalData, const UString& patte
void RegExp::compile(JSGlobalData* globalData)
{
#if ENABLE(YARR_JIT)
- Yarr::jitCompileRegex(globalData, m_regExpJITCode, m_pattern, m_numSubpatterns, m_constructionError, ignoreCase(), multiline());
+ Yarr::jitCompileRegex(globalData, m_representation->m_regExpJITCode, m_pattern, m_numSubpatterns, m_constructionError, ignoreCase(), multiline());
#else
- m_regExpBytecode = Yarr::byteCompileRegex(m_pattern, m_numSubpatterns, m_constructionError, &globalData->m_regexAllocator, ignoreCase(), multiline());
+ m_representation->m_regExpBytecode = Yarr::byteCompileRegex(m_pattern, m_numSubpatterns, m_constructionError, &globalData->m_regexAllocator, ignoreCase(), multiline());
#endif
}
@@ -94,14 +117,18 @@ int RegExp::match(const UString& s, int startOffset, Vector<int, 32>* ovector)
startOffset = 0;
if (ovector)
ovector->resize(0);
+
+#if ENABLE(REGEXP_TRACING)
+ m_rtMatchCallCount++;
+#endif
if (static_cast<unsigned>(startOffset) > s.length() || s.isNull())
return -1;
#if ENABLE(YARR_JIT)
- if (!!m_regExpJITCode) {
+ if (!!m_representation->m_regExpJITCode) {
#else
- if (m_regExpBytecode) {
+ if (m_representation->m_regExpBytecode) {
#endif
int offsetVectorSize = (m_numSubpatterns + 1) * 3; // FIXME: should be 2 - but adding temporary fallback to pcre.
int* offsetVector;
@@ -119,9 +146,9 @@ int RegExp::match(const UString& s, int startOffset, Vector<int, 32>* ovector)
offsetVector[j] = -1;
#if ENABLE(YARR_JIT)
- int result = Yarr::executeRegex(m_regExpJITCode, s.characters(), startOffset, s.length(), offsetVector, offsetVectorSize);
+ int result = Yarr::executeRegex(m_representation->m_regExpJITCode, s.characters(), startOffset, s.length(), offsetVector, offsetVectorSize);
#else
- int result = Yarr::interpretRegex(m_regExpBytecode.get(), s.characters(), startOffset, s.length(), offsetVector);
+ int result = Yarr::interpretRegex(m_representation->m_regExpBytecode.get(), s.characters(), startOffset, s.length(), offsetVector);
#endif
if (result < 0) {
@@ -134,6 +161,11 @@ int RegExp::match(const UString& s, int startOffset, Vector<int, 32>* ovector)
ovector->clear();
}
+#if ENABLE(REGEXP_TRACING)
+ if (result != -1)
+ m_rtMatchFoundCount++;
+#endif
+
return result;
}
@@ -144,14 +176,18 @@ int RegExp::match(const UString& s, int startOffset, Vector<int, 32>* ovector)
void RegExp::compile(JSGlobalData*)
{
- m_regExp = 0;
+ m_representation->m_regExp = 0;
JSRegExpIgnoreCaseOption ignoreCaseOption = ignoreCase() ? JSRegExpIgnoreCase : JSRegExpDoNotIgnoreCase;
JSRegExpMultilineOption multilineOption = multiline() ? JSRegExpMultiline : JSRegExpSingleLine;
- m_regExp = jsRegExpCompile(reinterpret_cast<const UChar*>(m_pattern.characters()), m_pattern.length(), ignoreCaseOption, multilineOption, &m_numSubpatterns, &m_constructionError);
+ m_representation->m_regExp = jsRegExpCompile(reinterpret_cast<const UChar*>(m_pattern.characters()), m_pattern.length(), ignoreCaseOption, multilineOption, &m_numSubpatterns, &m_constructionError);
}
int RegExp::match(const UString& s, int startOffset, Vector<int, 32>* ovector)
{
+#if ENABLE(REGEXP_TRACING)
+ m_rtMatchCallCount++;
+#endif
+
if (startOffset < 0)
startOffset = 0;
if (ovector)
@@ -160,7 +196,7 @@ int RegExp::match(const UString& s, int startOffset, Vector<int, 32>* ovector)
if (static_cast<unsigned>(startOffset) > s.length() || s.isNull())
return -1;
- if (m_regExp) {
+ if (m_representation->m_regExp) {
// Set up the offset vector for the result.
// First 2/3 used for result, the last third used by PCRE.
int* offsetVector;
@@ -175,7 +211,7 @@ int RegExp::match(const UString& s, int startOffset, Vector<int, 32>* ovector)
offsetVector = ovector->data();
}
- int numMatches = jsRegExpExecute(m_regExp, reinterpret_cast<const UChar*>(s.characters()), s.length(), startOffset, offsetVector, offsetVectorSize);
+ int numMatches = jsRegExpExecute(m_representation->m_regExp, reinterpret_cast<const UChar*>(s.characters()), s.length(), startOffset, offsetVector, offsetVectorSize);
if (numMatches < 0) {
#ifndef NDEBUG
@@ -187,12 +223,45 @@ int RegExp::match(const UString& s, int startOffset, Vector<int, 32>* ovector)
return -1;
}
+#if ENABLE(REGEXP_TRACING)
+ m_rtMatchFoundCount++;
+#endif
+
return offsetVector[0];
}
return -1;
}
-
+
#endif
+#if ENABLE(REGEXP_TRACING)
+ void RegExp::printTraceData()
+ {
+ char formattedPattern[41];
+ char rawPattern[41];
+
+ strncpy(rawPattern, m_pattern.utf8().data(), 40);
+ rawPattern[40]= '\0';
+
+ int pattLen = strlen(rawPattern);
+
+ snprintf(formattedPattern, 41, (pattLen <= 38) ? "/%.38s/" : "/%.36s...", rawPattern);
+
+#if ENABLE(YARR_JIT)
+ Yarr::RegexCodeBlock& codeBlock = m_representation->m_regExpJITCode;
+
+ char jitAddr[20];
+ if (codeBlock.getFallback())
+ sprintf(jitAddr, "fallback");
+ else
+ sprintf(jitAddr, "0x%014lx", (uintptr_t)codeBlock.getAddr());
+#else
+ const char* jitAddr = "JIT Off";
+#endif
+
+ printf("%-40.40s %16.16s %10d %10d\n", formattedPattern, jitAddr, m_rtMatchCallCount, m_rtMatchFoundCount);
+ }
+#endif
+
} // namespace JSC
diff --git a/JavaScriptCore/runtime/RegExp.h b/JavaScriptCore/runtime/RegExp.h
index aadad6b..e6e2fbc 100644
--- a/JavaScriptCore/runtime/RegExp.h
+++ b/JavaScriptCore/runtime/RegExp.h
@@ -26,21 +26,16 @@
#include "ExecutableAllocator.h"
#include <wtf/Forward.h>
#include <wtf/RefCounted.h>
-#include "yarr/RegexJIT.h"
-#include "yarr/RegexInterpreter.h"
-
-struct JSRegExp;
namespace JSC {
+ struct RegExpRepresentation;
class JSGlobalData;
class RegExp : public RefCounted<RegExp> {
public:
static PassRefPtr<RegExp> create(JSGlobalData* globalData, const UString& pattern, const UString& flags);
-#if !ENABLE(YARR)
~RegExp();
-#endif
bool global() const { return m_flagBits & Global; }
bool ignoreCase() const { return m_flagBits & IgnoreCase; }
@@ -53,6 +48,10 @@ namespace JSC {
int match(const UString&, int startOffset, Vector<int, 32>* ovector = 0);
unsigned numSubpatterns() const { return m_numSubpatterns; }
+
+#if ENABLE(REGEXP_TRACING)
+ void printTraceData();
+#endif
private:
RegExp(JSGlobalData* globalData, const UString& pattern, const UString& flags);
@@ -65,14 +64,12 @@ namespace JSC {
int m_flagBits;
const char* m_constructionError;
unsigned m_numSubpatterns;
-
-#if ENABLE(YARR_JIT)
- Yarr::RegexCodeBlock m_regExpJITCode;
-#elif ENABLE(YARR)
- OwnPtr<Yarr::BytecodePattern> m_regExpBytecode;
-#else
- JSRegExp* m_regExp;
+#if ENABLE(REGEXP_TRACING)
+ unsigned m_rtMatchCallCount;
+ unsigned m_rtMatchFoundCount;
#endif
+
+ OwnPtr<RegExpRepresentation> m_representation;
};
} // namespace JSC