summaryrefslogtreecommitdiff
path: root/Source/JavaScriptCore/profiler
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@digia.com>2013-09-13 12:51:20 +0200
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-09-19 20:50:05 +0200
commitd441d6f39bb846989d95bcf5caf387b42414718d (patch)
treee367e64a75991c554930278175d403c072de6bb8 /Source/JavaScriptCore/profiler
parent0060b2994c07842f4c59de64b5e3e430525c4b90 (diff)
downloadqtwebkit-d441d6f39bb846989d95bcf5caf387b42414718d.tar.gz
Import Qt5x2 branch of QtWebkit for Qt 5.2
Importing a new snapshot of webkit. Change-Id: I2d01ad12cdc8af8cb015387641120a9d7ea5f10c Reviewed-by: Allan Sandfeld Jensen <allan.jensen@digia.com>
Diffstat (limited to 'Source/JavaScriptCore/profiler')
-rw-r--r--Source/JavaScriptCore/profiler/LegacyProfiler.cpp (renamed from Source/JavaScriptCore/profiler/Profiler.cpp)51
-rw-r--r--Source/JavaScriptCore/profiler/LegacyProfiler.h (renamed from Source/JavaScriptCore/profiler/Profiler.h)58
-rw-r--r--Source/JavaScriptCore/profiler/ProfileGenerator.cpp5
-rw-r--r--Source/JavaScriptCore/profiler/ProfileNode.cpp2
-rw-r--r--Source/JavaScriptCore/profiler/ProfilerBytecode.cpp45
-rw-r--r--Source/JavaScriptCore/profiler/ProfilerBytecode.h65
-rw-r--r--Source/JavaScriptCore/profiler/ProfilerBytecodeSequence.cpp90
-rw-r--r--Source/JavaScriptCore/profiler/ProfilerBytecodeSequence.h65
-rw-r--r--Source/JavaScriptCore/profiler/ProfilerBytecodes.cpp69
-rw-r--r--Source/JavaScriptCore/profiler/ProfilerBytecodes.h63
-rw-r--r--Source/JavaScriptCore/profiler/ProfilerCompilation.cpp138
-rw-r--r--Source/JavaScriptCore/profiler/ProfilerCompilation.h88
-rw-r--r--Source/JavaScriptCore/profiler/ProfilerCompilationKind.cpp52
-rw-r--r--Source/JavaScriptCore/profiler/ProfilerCompilationKind.h47
-rw-r--r--Source/JavaScriptCore/profiler/ProfilerCompiledBytecode.cpp56
-rw-r--r--Source/JavaScriptCore/profiler/ProfilerCompiledBytecode.h55
-rw-r--r--Source/JavaScriptCore/profiler/ProfilerDatabase.cpp187
-rw-r--r--Source/JavaScriptCore/profiler/ProfilerDatabase.h93
-rw-r--r--Source/JavaScriptCore/profiler/ProfilerExecutionCounter.h50
-rw-r--r--Source/JavaScriptCore/profiler/ProfilerOSRExit.cpp60
-rw-r--r--Source/JavaScriptCore/profiler/ProfilerOSRExit.h61
-rw-r--r--Source/JavaScriptCore/profiler/ProfilerOSRExitSite.cpp46
-rw-r--r--Source/JavaScriptCore/profiler/ProfilerOSRExitSite.h52
-rw-r--r--Source/JavaScriptCore/profiler/ProfilerOrigin.cpp57
-rw-r--r--Source/JavaScriptCore/profiler/ProfilerOrigin.h120
-rw-r--r--Source/JavaScriptCore/profiler/ProfilerOriginStack.cpp111
-rw-r--r--Source/JavaScriptCore/profiler/ProfilerOriginStack.h102
-rw-r--r--Source/JavaScriptCore/profiler/ProfilerProfiledBytecodes.cpp56
-rw-r--r--Source/JavaScriptCore/profiler/ProfilerProfiledBytecodes.h51
29 files changed, 1941 insertions, 54 deletions
diff --git a/Source/JavaScriptCore/profiler/Profiler.cpp b/Source/JavaScriptCore/profiler/LegacyProfiler.cpp
index 9642a0684..1db2e625e 100644
--- a/Source/JavaScriptCore/profiler/Profiler.cpp
+++ b/Source/JavaScriptCore/profiler/LegacyProfiler.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2008, 2012 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -27,15 +27,16 @@
*/
#include "config.h"
-#include "Profiler.h"
+#include "LegacyProfiler.h"
-#include "CommonIdentifiers.h"
#include "CallFrame.h"
#include "CodeBlock.h"
+#include "CommonIdentifiers.h"
#include "InternalFunction.h"
#include "JSFunction.h"
#include "JSGlobalObject.h"
#include "Nodes.h"
+#include "Operations.h"
#include "Profile.h"
#include "ProfileGenerator.h"
#include "ProfileNode.h"
@@ -49,22 +50,25 @@ static unsigned ProfilesUID = 0;
static CallIdentifier createCallIdentifierFromFunctionImp(ExecState*, JSObject*, const String& defaultSourceURL, int defaultLineNumber);
-Profiler* Profiler::s_sharedProfiler = 0;
+LegacyProfiler* LegacyProfiler::s_sharedLegacyProfiler = 0;
-Profiler* Profiler::profiler()
+LegacyProfiler* LegacyProfiler::profiler()
{
- if (!s_sharedProfiler)
- s_sharedProfiler = new Profiler();
- return s_sharedProfiler;
+ if (!s_sharedLegacyProfiler)
+ s_sharedLegacyProfiler = new LegacyProfiler();
+ return s_sharedLegacyProfiler;
}
-void Profiler::startProfiling(ExecState* exec, const String& title)
+void LegacyProfiler::startProfiling(ExecState* exec, const String& title)
{
ASSERT_ARG(title, !title.isNull());
+ if (!exec)
+ return;
+
// Check if we currently have a Profile for this global ExecState and title.
// If so return early and don't create a new Profile.
- JSGlobalObject* origin = exec ? exec->lexicalGlobalObject() : 0;
+ JSGlobalObject* origin = exec->lexicalGlobalObject();
for (size_t i = 0; i < m_currentProfiles.size(); ++i) {
ProfileGenerator* profileGenerator = m_currentProfiles[i].get();
@@ -72,14 +76,17 @@ void Profiler::startProfiling(ExecState* exec, const String& title)
return;
}
- exec->globalData().m_enabledProfiler = this;
+ exec->vm().m_enabledProfiler = this;
RefPtr<ProfileGenerator> profileGenerator = ProfileGenerator::create(exec, title, ++ProfilesUID);
m_currentProfiles.append(profileGenerator);
}
-PassRefPtr<Profile> Profiler::stopProfiling(ExecState* exec, const String& title)
+PassRefPtr<Profile> LegacyProfiler::stopProfiling(ExecState* exec, const String& title)
{
- JSGlobalObject* origin = exec ? exec->lexicalGlobalObject() : 0;
+ if (!exec)
+ return 0;
+
+ JSGlobalObject* origin = exec->lexicalGlobalObject();
for (ptrdiff_t i = m_currentProfiles.size() - 1; i >= 0; --i) {
ProfileGenerator* profileGenerator = m_currentProfiles[i].get();
if (profileGenerator->origin() == origin && (title.isNull() || profileGenerator->title() == title)) {
@@ -88,7 +95,7 @@ PassRefPtr<Profile> Profiler::stopProfiling(ExecState* exec, const String& title
m_currentProfiles.remove(i);
if (!m_currentProfiles.size())
- exec->globalData().m_enabledProfiler = 0;
+ exec->vm().m_enabledProfiler = 0;
return returnProfile;
}
@@ -97,7 +104,7 @@ PassRefPtr<Profile> Profiler::stopProfiling(ExecState* exec, const String& title
return 0;
}
-void Profiler::stopProfiling(JSGlobalObject* origin)
+void LegacyProfiler::stopProfiling(JSGlobalObject* origin)
{
for (ptrdiff_t i = m_currentProfiles.size() - 1; i >= 0; --i) {
ProfileGenerator* profileGenerator = m_currentProfiles[i].get();
@@ -105,7 +112,7 @@ void Profiler::stopProfiling(JSGlobalObject* origin)
profileGenerator->stopProfiling();
m_currentProfiles.remove(i);
if (!m_currentProfiles.size())
- origin->globalData().m_enabledProfiler = 0;
+ origin->vm().m_enabledProfiler = 0;
}
}
}
@@ -118,14 +125,14 @@ static inline void dispatchFunctionToProfiles(ExecState* callerOrHandlerCallFram
}
}
-void Profiler::willExecute(ExecState* callerCallFrame, JSValue function)
+void LegacyProfiler::willExecute(ExecState* callerCallFrame, JSValue function)
{
ASSERT(!m_currentProfiles.isEmpty());
dispatchFunctionToProfiles(callerCallFrame, m_currentProfiles, &ProfileGenerator::willExecute, createCallIdentifier(callerCallFrame, function, "", 0), callerCallFrame->lexicalGlobalObject()->profileGroup());
}
-void Profiler::willExecute(ExecState* callerCallFrame, const String& sourceURL, int startingLineNumber)
+void LegacyProfiler::willExecute(ExecState* callerCallFrame, const String& sourceURL, int startingLineNumber)
{
ASSERT(!m_currentProfiles.isEmpty());
@@ -134,28 +141,28 @@ void Profiler::willExecute(ExecState* callerCallFrame, const String& sourceURL,
dispatchFunctionToProfiles(callerCallFrame, m_currentProfiles, &ProfileGenerator::willExecute, callIdentifier, callerCallFrame->lexicalGlobalObject()->profileGroup());
}
-void Profiler::didExecute(ExecState* callerCallFrame, JSValue function)
+void LegacyProfiler::didExecute(ExecState* callerCallFrame, JSValue function)
{
ASSERT(!m_currentProfiles.isEmpty());
dispatchFunctionToProfiles(callerCallFrame, m_currentProfiles, &ProfileGenerator::didExecute, createCallIdentifier(callerCallFrame, function, "", 0), callerCallFrame->lexicalGlobalObject()->profileGroup());
}
-void Profiler::didExecute(ExecState* callerCallFrame, const String& sourceURL, int startingLineNumber)
+void LegacyProfiler::didExecute(ExecState* callerCallFrame, const String& sourceURL, int startingLineNumber)
{
ASSERT(!m_currentProfiles.isEmpty());
dispatchFunctionToProfiles(callerCallFrame, m_currentProfiles, &ProfileGenerator::didExecute, createCallIdentifier(callerCallFrame, JSValue(), sourceURL, startingLineNumber), callerCallFrame->lexicalGlobalObject()->profileGroup());
}
-void Profiler::exceptionUnwind(ExecState* handlerCallFrame)
+void LegacyProfiler::exceptionUnwind(ExecState* handlerCallFrame)
{
ASSERT(!m_currentProfiles.isEmpty());
dispatchFunctionToProfiles(handlerCallFrame, m_currentProfiles, &ProfileGenerator::exceptionUnwind, createCallIdentifier(handlerCallFrame, JSValue(), "", 0), handlerCallFrame->lexicalGlobalObject()->profileGroup());
}
-CallIdentifier Profiler::createCallIdentifier(ExecState* exec, JSValue functionValue, const String& defaultSourceURL, int defaultLineNumber)
+CallIdentifier LegacyProfiler::createCallIdentifier(ExecState* exec, JSValue functionValue, const String& defaultSourceURL, int defaultLineNumber)
{
if (!functionValue)
return CallIdentifier(GlobalCodeExecution, defaultSourceURL, defaultLineNumber);
diff --git a/Source/JavaScriptCore/profiler/Profiler.h b/Source/JavaScriptCore/profiler/LegacyProfiler.h
index 6852457c7..6db57cbf2 100644
--- a/Source/JavaScriptCore/profiler/Profiler.h
+++ b/Source/JavaScriptCore/profiler/LegacyProfiler.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2008, 2012 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -26,8 +26,8 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef Profiler_h
-#define Profiler_h
+#ifndef LegacyProfiler_h
+#define LegacyProfiler_h
#include "Profile.h"
#include <wtf/PassRefPtr.h>
@@ -36,38 +36,38 @@
namespace JSC {
- class ExecState;
- class JSGlobalData;
- class JSGlobalObject;
- class JSObject;
- class JSValue;
- class ProfileGenerator;
- struct CallIdentifier;
+class ExecState;
+class VM;
+class JSGlobalObject;
+class JSObject;
+class JSValue;
+class ProfileGenerator;
+struct CallIdentifier;
- class Profiler {
- WTF_MAKE_FAST_ALLOCATED;
- public:
- JS_EXPORT_PRIVATE static Profiler* profiler();
- static CallIdentifier createCallIdentifier(ExecState*, JSValue, const WTF::String& sourceURL, int lineNumber);
+class LegacyProfiler {
+ WTF_MAKE_FAST_ALLOCATED;
+public:
+ JS_EXPORT_PRIVATE static LegacyProfiler* profiler();
+ static CallIdentifier createCallIdentifier(ExecState*, JSValue, const WTF::String& sourceURL, int lineNumber);
- JS_EXPORT_PRIVATE void startProfiling(ExecState*, const WTF::String& title);
- JS_EXPORT_PRIVATE PassRefPtr<Profile> stopProfiling(ExecState*, const WTF::String& title);
- void stopProfiling(JSGlobalObject*);
+ JS_EXPORT_PRIVATE void startProfiling(ExecState*, const WTF::String& title);
+ JS_EXPORT_PRIVATE PassRefPtr<Profile> stopProfiling(ExecState*, const WTF::String& title);
+ void stopProfiling(JSGlobalObject*);
- void willExecute(ExecState* callerCallFrame, JSValue function);
- void willExecute(ExecState* callerCallFrame, const WTF::String& sourceURL, int startingLineNumber);
- void didExecute(ExecState* callerCallFrame, JSValue function);
- void didExecute(ExecState* callerCallFrame, const WTF::String& sourceURL, int startingLineNumber);
+ void willExecute(ExecState* callerCallFrame, JSValue function);
+ void willExecute(ExecState* callerCallFrame, const WTF::String& sourceURL, int startingLineNumber);
+ void didExecute(ExecState* callerCallFrame, JSValue function);
+ void didExecute(ExecState* callerCallFrame, const WTF::String& sourceURL, int startingLineNumber);
- void exceptionUnwind(ExecState* handlerCallFrame);
+ void exceptionUnwind(ExecState* handlerCallFrame);
- const Vector<RefPtr<ProfileGenerator> >& currentProfiles() { return m_currentProfiles; };
+ const Vector<RefPtr<ProfileGenerator> >& currentProfiles() { return m_currentProfiles; };
- private:
- Vector<RefPtr<ProfileGenerator> > m_currentProfiles;
- static Profiler* s_sharedProfiler;
- };
+private:
+ Vector<RefPtr<ProfileGenerator> > m_currentProfiles;
+ static LegacyProfiler* s_sharedLegacyProfiler;
+};
} // namespace JSC
-#endif // Profiler_h
+#endif // LegacyProfiler_h
diff --git a/Source/JavaScriptCore/profiler/ProfileGenerator.cpp b/Source/JavaScriptCore/profiler/ProfileGenerator.cpp
index 09877d3c8..d240aff34 100644
--- a/Source/JavaScriptCore/profiler/ProfileGenerator.cpp
+++ b/Source/JavaScriptCore/profiler/ProfileGenerator.cpp
@@ -32,8 +32,9 @@
#include "JSStringRef.h"
#include "JSFunction.h"
#include "Interpreter.h"
+#include "LegacyProfiler.h"
+#include "Operations.h"
#include "Profile.h"
-#include "Profiler.h"
#include "Tracing.h"
namespace JSC {
@@ -63,7 +64,7 @@ void ProfileGenerator::addParentForConsoleStart(ExecState* exec)
JSValue function;
exec->interpreter()->retrieveLastCaller(exec, lineNumber, sourceID, sourceURL, function);
- m_currentNode = ProfileNode::create(exec, Profiler::createCallIdentifier(exec, function ? function.toThisObject(exec) : 0, sourceURL, lineNumber), m_head.get(), m_head.get());
+ m_currentNode = ProfileNode::create(exec, LegacyProfiler::createCallIdentifier(exec, function ? function.toThisObject(exec) : 0, sourceURL, lineNumber), m_head.get(), m_head.get());
m_head->insertNode(m_currentNode.get());
}
diff --git a/Source/JavaScriptCore/profiler/ProfileNode.cpp b/Source/JavaScriptCore/profiler/ProfileNode.cpp
index 6c36e47d0..5b6a25411 100644
--- a/Source/JavaScriptCore/profiler/ProfileNode.cpp
+++ b/Source/JavaScriptCore/profiler/ProfileNode.cpp
@@ -29,7 +29,7 @@
#include "config.h"
#include "ProfileNode.h"
-#include "Profiler.h"
+#include "LegacyProfiler.h"
#include <stdio.h>
#include <wtf/DateMath.h>
#include <wtf/DataLog.h>
diff --git a/Source/JavaScriptCore/profiler/ProfilerBytecode.cpp b/Source/JavaScriptCore/profiler/ProfilerBytecode.cpp
new file mode 100644
index 000000000..ca602e42f
--- /dev/null
+++ b/Source/JavaScriptCore/profiler/ProfilerBytecode.cpp
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2012 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "ProfilerBytecode.h"
+
+#include "JSGlobalObject.h"
+#include "ObjectConstructor.h"
+#include "Operations.h"
+
+namespace JSC { namespace Profiler {
+
+JSValue Bytecode::toJS(ExecState* exec) const
+{
+ JSObject* result = constructEmptyObject(exec);
+ result->putDirect(exec->vm(), exec->propertyNames().bytecodeIndex, jsNumber(m_bytecodeIndex));
+ result->putDirect(exec->vm(), exec->propertyNames().opcode, jsString(exec, String::fromUTF8(opcodeNames[m_opcodeID])));
+ result->putDirect(exec->vm(), exec->propertyNames().description, jsString(exec, String::fromUTF8(m_description)));
+ return result;
+}
+
+} } // namespace JSC::Profiler
+
diff --git a/Source/JavaScriptCore/profiler/ProfilerBytecode.h b/Source/JavaScriptCore/profiler/ProfilerBytecode.h
new file mode 100644
index 000000000..8e99c9a09
--- /dev/null
+++ b/Source/JavaScriptCore/profiler/ProfilerBytecode.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2012 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef ProfilerBytecode_h
+#define ProfilerBytecode_h
+
+#include "JSCJSValue.h"
+#include "Opcode.h"
+#include <wtf/text/CString.h>
+
+namespace JSC { namespace Profiler {
+
+class Bytecode {
+public:
+ Bytecode()
+ : m_bytecodeIndex(std::numeric_limits<unsigned>::max())
+ {
+ }
+
+ Bytecode(unsigned bytecodeIndex, OpcodeID opcodeID, const CString& description)
+ : m_bytecodeIndex(bytecodeIndex)
+ , m_opcodeID(opcodeID)
+ , m_description(description)
+ {
+ }
+
+ unsigned bytecodeIndex() const { return m_bytecodeIndex; }
+ OpcodeID opcodeID() const { return m_opcodeID; }
+ const CString& description() const { return m_description; }
+
+ JSValue toJS(ExecState*) const;
+private:
+ unsigned m_bytecodeIndex;
+ OpcodeID m_opcodeID;
+ CString m_description;
+};
+
+inline unsigned getBytecodeIndexForBytecode(Bytecode* bytecode) { return bytecode->bytecodeIndex(); }
+
+} } // namespace JSC::Profiler
+
+#endif // ProfilerBytecode_h
+
diff --git a/Source/JavaScriptCore/profiler/ProfilerBytecodeSequence.cpp b/Source/JavaScriptCore/profiler/ProfilerBytecodeSequence.cpp
new file mode 100644
index 000000000..a98b8bace
--- /dev/null
+++ b/Source/JavaScriptCore/profiler/ProfilerBytecodeSequence.cpp
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2012 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "ProfilerBytecodeSequence.h"
+
+#include "CodeBlock.h"
+#include "JSGlobalObject.h"
+#include "Operands.h"
+#include "Operations.h"
+#include <wtf/StringPrintStream.h>
+
+namespace JSC { namespace Profiler {
+
+BytecodeSequence::BytecodeSequence(CodeBlock* codeBlock)
+{
+ StringPrintStream out;
+
+#if ENABLE(VALUE_PROFILER)
+ for (unsigned i = 0; i < codeBlock->numberOfArgumentValueProfiles(); ++i) {
+ CString description = codeBlock->valueProfileForArgument(i)->briefDescription();
+ if (!description.length())
+ continue;
+ out.reset();
+ out.print("arg", i, " (r", argumentToOperand(i), "): ", description);
+ m_header.append(out.toCString());
+ }
+#endif // ENABLE(VALUE_PROFILER)
+
+ for (unsigned bytecodeIndex = 0; bytecodeIndex < codeBlock->instructions().size();) {
+ out.reset();
+ codeBlock->dumpBytecode(out, bytecodeIndex);
+ m_sequence.append(Bytecode(bytecodeIndex, codeBlock->vm()->interpreter->getOpcodeID(codeBlock->instructions()[bytecodeIndex].u.opcode), out.toCString()));
+ bytecodeIndex += opcodeLength(
+ codeBlock->vm()->interpreter->getOpcodeID(
+ codeBlock->instructions()[bytecodeIndex].u.opcode));
+ }
+}
+
+BytecodeSequence::~BytecodeSequence()
+{
+}
+
+unsigned BytecodeSequence::indexForBytecodeIndex(unsigned bytecodeIndex) const
+{
+ return binarySearch<Bytecode, unsigned>(m_sequence, m_sequence.size(), bytecodeIndex, getBytecodeIndexForBytecode) - m_sequence.begin();
+}
+
+const Bytecode& BytecodeSequence::forBytecodeIndex(unsigned bytecodeIndex) const
+{
+ return at(indexForBytecodeIndex(bytecodeIndex));
+}
+
+void BytecodeSequence::addSequenceProperties(ExecState* exec, JSObject* result) const
+{
+ JSArray* header = constructEmptyArray(exec, 0);
+ for (unsigned i = 0; i < m_header.size(); ++i)
+ header->putDirectIndex(exec, i, jsString(exec, String::fromUTF8(m_header[i])));
+ result->putDirect(exec->vm(), exec->propertyNames().header, header);
+
+ JSArray* sequence = constructEmptyArray(exec, 0);
+ for (unsigned i = 0; i < m_sequence.size(); ++i)
+ sequence->putDirectIndex(exec, i, m_sequence[i].toJS(exec));
+ result->putDirect(exec->vm(), exec->propertyNames().bytecode, sequence);
+}
+
+} } // namespace JSC::Profiler
+
diff --git a/Source/JavaScriptCore/profiler/ProfilerBytecodeSequence.h b/Source/JavaScriptCore/profiler/ProfilerBytecodeSequence.h
new file mode 100644
index 000000000..1d5c82a18
--- /dev/null
+++ b/Source/JavaScriptCore/profiler/ProfilerBytecodeSequence.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2012 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef ProfilerBytecodeSequence_h
+#define ProfilerBytecodeSequence_h
+
+#include "JSCJSValue.h"
+#include "ProfilerBytecode.h"
+#include <wtf/PrintStream.h>
+#include <wtf/Vector.h>
+#include <wtf/text/CString.h>
+#include <wtf/text/WTFString.h>
+
+namespace JSC {
+
+class CodeBlock;
+
+namespace Profiler {
+
+class BytecodeSequence {
+public:
+ BytecodeSequence(CodeBlock*);
+ ~BytecodeSequence();
+
+ // Note that this data structure is not indexed by bytecode index.
+ unsigned size() const { return m_sequence.size(); }
+ const Bytecode& at(unsigned i) const { return m_sequence[i]; }
+
+ unsigned indexForBytecodeIndex(unsigned bytecodeIndex) const;
+ const Bytecode& forBytecodeIndex(unsigned bytecodeIndex) const;
+
+protected:
+ void addSequenceProperties(ExecState*, JSObject*) const;
+
+private:
+ Vector<CString> m_header;
+ Vector<Bytecode> m_sequence;
+};
+
+} } // namespace JSC::Profiler
+
+#endif // ProfilerBytecodeSequence_h
+
diff --git a/Source/JavaScriptCore/profiler/ProfilerBytecodes.cpp b/Source/JavaScriptCore/profiler/ProfilerBytecodes.cpp
new file mode 100644
index 000000000..3ae35dcc0
--- /dev/null
+++ b/Source/JavaScriptCore/profiler/ProfilerBytecodes.cpp
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2012 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "ProfilerBytecodes.h"
+
+#include "CodeBlock.h"
+#include "JSGlobalObject.h"
+#include "ObjectConstructor.h"
+#include "Operations.h"
+#include <wtf/StringPrintStream.h>
+
+namespace JSC { namespace Profiler {
+
+Bytecodes::Bytecodes(size_t id, CodeBlock* codeBlock)
+ : BytecodeSequence(codeBlock)
+ , m_id(id)
+ , m_inferredName(codeBlock->inferredName())
+ , m_sourceCode(codeBlock->sourceCodeForTools())
+ , m_hash(codeBlock->hash())
+ , m_instructionCount(codeBlock->instructionCount())
+{
+}
+
+Bytecodes::~Bytecodes() { }
+
+void Bytecodes::dump(PrintStream& out) const
+{
+ out.print("#", m_hash, "(", m_id, ")");
+}
+
+JSValue Bytecodes::toJS(ExecState* exec) const
+{
+ JSObject* result = constructEmptyObject(exec);
+
+ result->putDirect(exec->vm(), exec->propertyNames().bytecodesID, jsNumber(m_id));
+ result->putDirect(exec->vm(), exec->propertyNames().inferredName, jsString(exec, m_inferredName));
+ result->putDirect(exec->vm(), exec->propertyNames().sourceCode, jsString(exec, m_sourceCode));
+ result->putDirect(exec->vm(), exec->propertyNames().hash, jsString(exec, String::fromUTF8(toCString(m_hash))));
+ result->putDirect(exec->vm(), exec->propertyNames().instructionCount, jsNumber(m_instructionCount));
+ addSequenceProperties(exec, result);
+
+ return result;
+}
+
+} } // namespace JSC::Profiler
+
diff --git a/Source/JavaScriptCore/profiler/ProfilerBytecodes.h b/Source/JavaScriptCore/profiler/ProfilerBytecodes.h
new file mode 100644
index 000000000..47d856cb4
--- /dev/null
+++ b/Source/JavaScriptCore/profiler/ProfilerBytecodes.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2012 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef ProfilerBytecodes_h
+#define ProfilerBytecodes_h
+
+#include "CodeBlockHash.h"
+#include "JSCJSValue.h"
+#include "ProfilerBytecodeSequence.h"
+#include <wtf/PrintStream.h>
+#include <wtf/text/WTFString.h>
+
+namespace JSC { namespace Profiler {
+
+class Bytecodes : public BytecodeSequence {
+public:
+ Bytecodes(size_t id, CodeBlock*);
+ ~Bytecodes();
+
+ size_t id() const { return m_id; }
+ const String& inferredName() const { return m_inferredName; }
+ const String& sourceCode() const { return m_sourceCode; }
+ unsigned instructionCount() const { return m_instructionCount; }
+ CodeBlockHash hash() const { return m_hash; }
+
+ void dump(PrintStream&) const;
+
+ JSValue toJS(ExecState*) const;
+
+private:
+ size_t m_id;
+ String m_inferredName;
+ String m_sourceCode;
+ CodeBlockHash m_hash;
+ unsigned m_instructionCount;
+};
+
+} } // namespace JSC::Profiler
+
+#endif // ProfilerBytecodes_h
+
diff --git a/Source/JavaScriptCore/profiler/ProfilerCompilation.cpp b/Source/JavaScriptCore/profiler/ProfilerCompilation.cpp
new file mode 100644
index 000000000..f82414ffa
--- /dev/null
+++ b/Source/JavaScriptCore/profiler/ProfilerCompilation.cpp
@@ -0,0 +1,138 @@
+/*
+ * Copyright (C) 2012, 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "ProfilerCompilation.h"
+
+#include "JSGlobalObject.h"
+#include "ObjectConstructor.h"
+#include "Operations.h"
+#include "ProfilerDatabase.h"
+#include <wtf/StringPrintStream.h>
+
+namespace JSC { namespace Profiler {
+
+Compilation::Compilation(Bytecodes* bytecodes, CompilationKind kind)
+ : m_bytecodes(bytecodes)
+ , m_kind(kind)
+ , m_numInlinedGetByIds(0)
+ , m_numInlinedPutByIds(0)
+ , m_numInlinedCalls(0)
+{
+}
+
+Compilation::~Compilation() { }
+
+void Compilation::addProfiledBytecodes(Database& database, CodeBlock* profiledBlock)
+{
+ Bytecodes* bytecodes = database.ensureBytecodesFor(profiledBlock);
+
+ // First make sure that we haven't already added profiled bytecodes for this code
+ // block. We do this using an O(N) search because I suspect that this list will
+ // tend to be fairly small, and the additional space costs of having a HashMap/Set
+ // would be greater than the time cost of occasionally doing this search.
+
+ for (unsigned i = m_profiledBytecodes.size(); i--;) {
+ if (m_profiledBytecodes[i].bytecodes() == bytecodes)
+ return;
+ }
+
+ m_profiledBytecodes.append(ProfiledBytecodes(bytecodes, profiledBlock));
+}
+
+void Compilation::addDescription(const CompiledBytecode& compiledBytecode)
+{
+ m_descriptions.append(compiledBytecode);
+}
+
+ExecutionCounter* Compilation::executionCounterFor(const OriginStack& origin)
+{
+ HashMap<OriginStack, OwnPtr<ExecutionCounter> >::iterator iter = m_counters.find(origin);
+ if (iter != m_counters.end())
+ return iter->value.get();
+
+ OwnPtr<ExecutionCounter> counter = adoptPtr(new ExecutionCounter());
+ ExecutionCounter* result = counter.get();
+ m_counters.add(origin, counter.release());
+ return result;
+}
+
+void Compilation::addOSRExitSite(const Vector<const void*>& codeAddresses)
+{
+ m_osrExitSites.append(OSRExitSite(codeAddresses));
+}
+
+OSRExit* Compilation::addOSRExit(unsigned id, const OriginStack& originStack, ExitKind exitKind, bool isWatchpoint)
+{
+ m_osrExits.append(OSRExit(id, originStack, exitKind, isWatchpoint));
+ return &m_osrExits.last();
+}
+
+JSValue Compilation::toJS(ExecState* exec) const
+{
+ JSObject* result = constructEmptyObject(exec);
+
+ result->putDirect(exec->vm(), exec->propertyNames().bytecodesID, jsNumber(m_bytecodes->id()));
+ result->putDirect(exec->vm(), exec->propertyNames().compilationKind, jsString(exec, String::fromUTF8(toCString(m_kind))));
+
+ JSArray* profiledBytecodes = constructEmptyArray(exec, 0);
+ for (unsigned i = 0; i < m_profiledBytecodes.size(); ++i)
+ profiledBytecodes->putDirectIndex(exec, i, m_profiledBytecodes[i].toJS(exec));
+ result->putDirect(exec->vm(), exec->propertyNames().profiledBytecodes, profiledBytecodes);
+
+ JSArray* descriptions = constructEmptyArray(exec, 0);
+ for (unsigned i = 0; i < m_descriptions.size(); ++i)
+ descriptions->putDirectIndex(exec, i, m_descriptions[i].toJS(exec));
+ result->putDirect(exec->vm(), exec->propertyNames().descriptions, descriptions);
+
+ JSArray* counters = constructEmptyArray(exec, 0);
+ HashMap<OriginStack, OwnPtr<ExecutionCounter> >::const_iterator end = m_counters.end();
+ for (HashMap<OriginStack, OwnPtr<ExecutionCounter> >::const_iterator iter = m_counters.begin(); iter != end; ++iter) {
+ JSObject* counterEntry = constructEmptyObject(exec);
+ counterEntry->putDirect(exec->vm(), exec->propertyNames().origin, iter->key.toJS(exec));
+ counterEntry->putDirect(exec->vm(), exec->propertyNames().executionCount, jsNumber(iter->value->count()));
+ counters->push(exec, counterEntry);
+ }
+ result->putDirect(exec->vm(), exec->propertyNames().counters, counters);
+
+ JSArray* exitSites = constructEmptyArray(exec, 0);
+ for (unsigned i = 0; i < m_osrExitSites.size(); ++i)
+ exitSites->putDirectIndex(exec, i, m_osrExitSites[i].toJS(exec));
+ result->putDirect(exec->vm(), exec->propertyNames().osrExitSites, exitSites);
+
+ JSArray* exits = constructEmptyArray(exec, 0);
+ for (unsigned i = 0; i < m_osrExits.size(); ++i)
+ exits->putDirectIndex(exec, i, m_osrExits[i].toJS(exec));
+ result->putDirect(exec->vm(), exec->propertyNames().osrExits, exits);
+
+ result->putDirect(exec->vm(), exec->propertyNames().numInlinedGetByIds, jsNumber(m_numInlinedGetByIds));
+ result->putDirect(exec->vm(), exec->propertyNames().numInlinedPutByIds, jsNumber(m_numInlinedPutByIds));
+ result->putDirect(exec->vm(), exec->propertyNames().numInlinedCalls, jsNumber(m_numInlinedCalls));
+
+ return result;
+}
+
+} } // namespace JSC::Profiler
+
diff --git a/Source/JavaScriptCore/profiler/ProfilerCompilation.h b/Source/JavaScriptCore/profiler/ProfilerCompilation.h
new file mode 100644
index 000000000..b3183fa02
--- /dev/null
+++ b/Source/JavaScriptCore/profiler/ProfilerCompilation.h
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2012, 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef ProfilerCompilation_h
+#define ProfilerCompilation_h
+
+#include "ExitKind.h"
+#include "JSCJSValue.h"
+#include "ProfilerCompilationKind.h"
+#include "ProfilerCompiledBytecode.h"
+#include "ProfilerExecutionCounter.h"
+#include "ProfilerOSRExit.h"
+#include "ProfilerOSRExitSite.h"
+#include "ProfilerOriginStack.h"
+#include "ProfilerProfiledBytecodes.h"
+#include <wtf/RefCounted.h>
+#include <wtf/SegmentedVector.h>
+
+namespace JSC { namespace Profiler {
+
+class Bytecodes;
+class Database;
+
+// Represents the act of executing some bytecodes in some engine, and does
+// all of the counting for those executions.
+
+class Compilation : public RefCounted<Compilation> {
+public:
+ Compilation(Bytecodes*, CompilationKind);
+ ~Compilation();
+
+ void addProfiledBytecodes(Database&, CodeBlock*);
+ unsigned profiledBytecodesSize() const { return m_profiledBytecodes.size(); }
+ const ProfiledBytecodes& profiledBytecodesAt(unsigned i) const { return m_profiledBytecodes[i]; }
+
+ void noticeInlinedGetById() { m_numInlinedGetByIds++; }
+ void noticeInlinedPutById() { m_numInlinedPutByIds++; }
+ void noticeInlinedCall() { m_numInlinedCalls++; }
+
+ Bytecodes* bytecodes() const { return m_bytecodes; }
+ CompilationKind kind() const { return m_kind; }
+
+ void addDescription(const CompiledBytecode&);
+ ExecutionCounter* executionCounterFor(const OriginStack&);
+ void addOSRExitSite(const Vector<const void*>& codeAddresses);
+ OSRExit* addOSRExit(unsigned id, const OriginStack&, ExitKind, bool isWatchpoint);
+
+ JSValue toJS(ExecState*) const;
+
+private:
+ Bytecodes* m_bytecodes;
+ CompilationKind m_kind;
+ Vector<ProfiledBytecodes> m_profiledBytecodes;
+ Vector<CompiledBytecode> m_descriptions;
+ HashMap<OriginStack, OwnPtr<ExecutionCounter> > m_counters;
+ Vector<OSRExitSite> m_osrExitSites;
+ SegmentedVector<OSRExit> m_osrExits;
+ unsigned m_numInlinedGetByIds;
+ unsigned m_numInlinedPutByIds;
+ unsigned m_numInlinedCalls;
+};
+
+} } // namespace JSC::Profiler
+
+#endif // ProfilerCompilation_h
+
diff --git a/Source/JavaScriptCore/profiler/ProfilerCompilationKind.cpp b/Source/JavaScriptCore/profiler/ProfilerCompilationKind.cpp
new file mode 100644
index 000000000..78ce70586
--- /dev/null
+++ b/Source/JavaScriptCore/profiler/ProfilerCompilationKind.cpp
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2012 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "ProfilerCompilationKind.h"
+
+#include <wtf/PrintStream.h>
+
+namespace WTF {
+
+void printInternal(PrintStream& out, JSC::Profiler::CompilationKind kind)
+{
+ switch (kind) {
+ case JSC::Profiler::LLInt:
+ out.print("LLInt");
+ return;
+ case JSC::Profiler::Baseline:
+ out.print("Baseline");
+ return;
+ case JSC::Profiler::DFG:
+ out.print("DFG");
+ return;
+ default:
+ CRASH();
+ return;
+ }
+}
+
+} // namespace WTF
+
diff --git a/Source/JavaScriptCore/profiler/ProfilerCompilationKind.h b/Source/JavaScriptCore/profiler/ProfilerCompilationKind.h
new file mode 100644
index 000000000..4806d39b9
--- /dev/null
+++ b/Source/JavaScriptCore/profiler/ProfilerCompilationKind.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2012 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef ProfilerCompilationKind_h
+#define ProfilerCompilationKind_h
+
+namespace JSC { namespace Profiler {
+
+enum CompilationKind {
+ LLInt,
+ Baseline,
+ DFG
+};
+
+} } // namespace JSC::Profiler
+
+namespace WTF {
+
+class PrintStream;
+void printInternal(PrintStream&, JSC::Profiler::CompilationKind);
+
+} // namespace WTF
+
+#endif // ProfilerCompilationKind_h
+
diff --git a/Source/JavaScriptCore/profiler/ProfilerCompiledBytecode.cpp b/Source/JavaScriptCore/profiler/ProfilerCompiledBytecode.cpp
new file mode 100644
index 000000000..455a48ed9
--- /dev/null
+++ b/Source/JavaScriptCore/profiler/ProfilerCompiledBytecode.cpp
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2012 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "ProfilerCompiledBytecode.h"
+
+#include "JSGlobalObject.h"
+#include "ObjectConstructor.h"
+#include "Operations.h"
+
+namespace JSC { namespace Profiler {
+
+CompiledBytecode::CompiledBytecode(const OriginStack& origin, const CString& description)
+ : m_origin(origin)
+ , m_description(description)
+{
+}
+
+CompiledBytecode::~CompiledBytecode()
+{
+}
+
+JSValue CompiledBytecode::toJS(ExecState* exec) const
+{
+ JSObject* result = constructEmptyObject(exec);
+
+ result->putDirect(exec->vm(), exec->propertyNames().origin, m_origin.toJS(exec));
+ result->putDirect(exec->vm(), exec->propertyNames().description, jsString(exec, String::fromUTF8(m_description)));
+
+ return result;
+}
+
+} } // namespace JSC::Profiler
+
diff --git a/Source/JavaScriptCore/profiler/ProfilerCompiledBytecode.h b/Source/JavaScriptCore/profiler/ProfilerCompiledBytecode.h
new file mode 100644
index 000000000..84044445a
--- /dev/null
+++ b/Source/JavaScriptCore/profiler/ProfilerCompiledBytecode.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2012 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef ProfilerCompiledBytecode_h
+#define ProfilerCompiledBytecode_h
+
+#include "JSCJSValue.h"
+#include "ProfilerOriginStack.h"
+#include <wtf/text/CString.h>
+
+namespace JSC { namespace Profiler {
+
+class CompiledBytecode {
+public:
+ // It's valid to have an empty OriginStack, which indicates that this is some
+ // sort of non-bytecode-related machine code.
+ CompiledBytecode(const OriginStack&, const CString& description);
+ ~CompiledBytecode();
+
+ const OriginStack& originStack() const { return m_origin; }
+ const CString& description() const { return m_description; }
+
+ JSValue toJS(ExecState*) const;
+
+private:
+ OriginStack m_origin;
+ CString m_description;
+};
+
+} } // namespace JSC::Profiler
+
+#endif // ProfilerCompiledBytecode_h
+
diff --git a/Source/JavaScriptCore/profiler/ProfilerDatabase.cpp b/Source/JavaScriptCore/profiler/ProfilerDatabase.cpp
new file mode 100644
index 000000000..a2fffd955
--- /dev/null
+++ b/Source/JavaScriptCore/profiler/ProfilerDatabase.cpp
@@ -0,0 +1,187 @@
+/*
+ * Copyright (C) 2012, 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "ProfilerDatabase.h"
+
+#include "CodeBlock.h"
+#include "JSONObject.h"
+#include "ObjectConstructor.h"
+#include "Operations.h"
+
+namespace JSC { namespace Profiler {
+
+#if COMPILER(MINGW) || COMPILER(MSVC7_OR_LOWER) || OS(WINCE)
+static int databaseCounter;
+#else
+static volatile int databaseCounter;
+#endif
+static SpinLock registrationLock = SPINLOCK_INITIALIZER;
+static int didRegisterAtExit;
+static Database* firstDatabase;
+
+Database::Database(VM& vm)
+ : m_databaseID(atomicIncrement(&databaseCounter))
+ , m_vm(vm)
+ , m_shouldSaveAtExit(false)
+ , m_nextRegisteredDatabase(0)
+{
+}
+
+Database::~Database()
+{
+ if (m_shouldSaveAtExit) {
+ removeDatabaseFromAtExit();
+ performAtExitSave();
+ }
+}
+
+Bytecodes* Database::ensureBytecodesFor(CodeBlock* codeBlock)
+{
+ codeBlock = codeBlock->baselineVersion();
+
+ HashMap<CodeBlock*, Bytecodes*>::iterator iter = m_bytecodesMap.find(codeBlock);
+ if (iter != m_bytecodesMap.end())
+ return iter->value;
+
+ m_bytecodes.append(Bytecodes(m_bytecodes.size(), codeBlock));
+ Bytecodes* result = &m_bytecodes.last();
+
+ m_bytecodesMap.add(codeBlock, result);
+
+ return result;
+}
+
+void Database::notifyDestruction(CodeBlock* codeBlock)
+{
+ m_bytecodesMap.remove(codeBlock);
+}
+
+PassRefPtr<Compilation> Database::newCompilation(Bytecodes* bytecodes, CompilationKind kind)
+{
+ RefPtr<Compilation> compilation = adoptRef(new Compilation(bytecodes, kind));
+ m_compilations.append(compilation);
+ return compilation.release();
+}
+
+PassRefPtr<Compilation> Database::newCompilation(CodeBlock* codeBlock, CompilationKind kind)
+{
+ return newCompilation(ensureBytecodesFor(codeBlock), kind);
+}
+
+JSValue Database::toJS(ExecState* exec) const
+{
+ JSObject* result = constructEmptyObject(exec);
+
+ JSArray* bytecodes = constructEmptyArray(exec, 0);
+ for (unsigned i = 0; i < m_bytecodes.size(); ++i)
+ bytecodes->putDirectIndex(exec, i, m_bytecodes[i].toJS(exec));
+ result->putDirect(exec->vm(), exec->propertyNames().bytecodes, bytecodes);
+
+ JSArray* compilations = constructEmptyArray(exec, 0);
+ for (unsigned i = 0; i < m_compilations.size(); ++i)
+ compilations->putDirectIndex(exec, i, m_compilations[i]->toJS(exec));
+ result->putDirect(exec->vm(), exec->propertyNames().compilations, compilations);
+
+ return result;
+}
+
+String Database::toJSON() const
+{
+ JSGlobalObject* globalObject = JSGlobalObject::create(
+ m_vm, JSGlobalObject::createStructure(m_vm, jsNull()));
+
+ return JSONStringify(globalObject->globalExec(), toJS(globalObject->globalExec()), 0);
+}
+
+bool Database::save(const char* filename) const
+{
+ OwnPtr<FilePrintStream> out = FilePrintStream::open(filename, "w");
+ if (!out)
+ return false;
+
+ out->print(toJSON());
+ return true;
+}
+
+void Database::registerToSaveAtExit(const char* filename)
+{
+ m_atExitSaveFilename = filename;
+
+ if (m_shouldSaveAtExit)
+ return;
+
+ addDatabaseToAtExit();
+ m_shouldSaveAtExit = true;
+}
+
+void Database::addDatabaseToAtExit()
+{
+ if (atomicIncrement(&didRegisterAtExit) == 1)
+ atexit(atExitCallback);
+
+ TCMalloc_SpinLockHolder holder(&registrationLock);
+ m_nextRegisteredDatabase = firstDatabase;
+ firstDatabase = this;
+}
+
+void Database::removeDatabaseFromAtExit()
+{
+ TCMalloc_SpinLockHolder holder(&registrationLock);
+ for (Database** current = &firstDatabase; *current; current = &(*current)->m_nextRegisteredDatabase) {
+ if (*current != this)
+ continue;
+ *current = m_nextRegisteredDatabase;
+ m_nextRegisteredDatabase = 0;
+ m_shouldSaveAtExit = false;
+ break;
+ }
+}
+
+void Database::performAtExitSave() const
+{
+ save(m_atExitSaveFilename.data());
+}
+
+Database* Database::removeFirstAtExitDatabase()
+{
+ TCMalloc_SpinLockHolder holder(&registrationLock);
+ Database* result = firstDatabase;
+ if (result) {
+ firstDatabase = result->m_nextRegisteredDatabase;
+ result->m_nextRegisteredDatabase = 0;
+ result->m_shouldSaveAtExit = false;
+ }
+ return result;
+}
+
+void Database::atExitCallback()
+{
+ while (Database* database = removeFirstAtExitDatabase())
+ database->performAtExitSave();
+}
+
+} } // namespace JSC::Profiler
+
diff --git a/Source/JavaScriptCore/profiler/ProfilerDatabase.h b/Source/JavaScriptCore/profiler/ProfilerDatabase.h
new file mode 100644
index 000000000..172c8eeac
--- /dev/null
+++ b/Source/JavaScriptCore/profiler/ProfilerDatabase.h
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2012, 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef ProfilerDatabase_h
+#define ProfilerDatabase_h
+
+#include "JSCJSValue.h"
+#include "ProfilerBytecodes.h"
+#include "ProfilerCompilation.h"
+#include "ProfilerCompilationKind.h"
+#include <wtf/FastAllocBase.h>
+#include <wtf/HashMap.h>
+#include <wtf/Noncopyable.h>
+#include <wtf/PassRefPtr.h>
+#include <wtf/SegmentedVector.h>
+#include <wtf/text/WTFString.h>
+
+namespace JSC { namespace Profiler {
+
+class Database {
+ WTF_MAKE_FAST_ALLOCATED; WTF_MAKE_NONCOPYABLE(Database);
+public:
+ JS_EXPORT_PRIVATE Database(VM&);
+ JS_EXPORT_PRIVATE ~Database();
+
+ int databaseID() const { return m_databaseID; }
+
+ Bytecodes* ensureBytecodesFor(CodeBlock*);
+ void notifyDestruction(CodeBlock*);
+
+ PassRefPtr<Compilation> newCompilation(CodeBlock*, CompilationKind);
+ PassRefPtr<Compilation> newCompilation(Bytecodes*, CompilationKind);
+
+ // Converts the database to a JavaScript object that is suitable for JSON stringification.
+ // Note that it's probably a good idea to use an ExecState* associated with a global
+ // object that is "clean" - i.e. array and object prototypes haven't had strange things
+ // done to them. And yes, it should be appropriate to just use a globalExec here.
+ JS_EXPORT_PRIVATE JSValue toJS(ExecState*) const;
+
+ // Converts the database to a JavaScript object using a private temporary global object,
+ // and then returns the JSON representation of that object.
+ JS_EXPORT_PRIVATE String toJSON() const;
+
+ // Saves the JSON representation (from toJSON()) to the given file. Returns false if the
+ // save failed.
+ JS_EXPORT_PRIVATE bool save(const char* filename) const;
+
+ void registerToSaveAtExit(const char* filename);
+
+private:
+
+ void addDatabaseToAtExit();
+ void removeDatabaseFromAtExit();
+ void performAtExitSave() const;
+ static Database* removeFirstAtExitDatabase();
+ static void atExitCallback();
+
+ int m_databaseID;
+ VM& m_vm;
+ SegmentedVector<Bytecodes> m_bytecodes;
+ HashMap<CodeBlock*, Bytecodes*> m_bytecodesMap;
+ Vector<RefPtr<Compilation> > m_compilations;
+ bool m_shouldSaveAtExit;
+ CString m_atExitSaveFilename;
+ Database* m_nextRegisteredDatabase;
+};
+
+} } // namespace JSC::Profiler
+
+#endif // ProfilerDatabase_h
+
diff --git a/Source/JavaScriptCore/profiler/ProfilerExecutionCounter.h b/Source/JavaScriptCore/profiler/ProfilerExecutionCounter.h
new file mode 100644
index 000000000..2884bc5dc
--- /dev/null
+++ b/Source/JavaScriptCore/profiler/ProfilerExecutionCounter.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2012 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef ProfilerExecutionCounter_h
+#define ProfilerExecutionCounter_h
+
+#include <wtf/FastAllocBase.h>
+#include <wtf/Noncopyable.h>
+
+namespace JSC { namespace Profiler {
+
+class ExecutionCounter {
+ WTF_MAKE_FAST_ALLOCATED; WTF_MAKE_NONCOPYABLE(ExecutionCounter);
+public:
+ ExecutionCounter() : m_counter(0) { }
+
+ uint64_t* address() { return &m_counter; }
+
+ uint64_t count() const { return m_counter; }
+
+private:
+ uint64_t m_counter;
+};
+
+} } // namespace JSC::Profiler
+
+#endif // ProfilerExecutionCounter_h
+
diff --git a/Source/JavaScriptCore/profiler/ProfilerOSRExit.cpp b/Source/JavaScriptCore/profiler/ProfilerOSRExit.cpp
new file mode 100644
index 000000000..0024791b4
--- /dev/null
+++ b/Source/JavaScriptCore/profiler/ProfilerOSRExit.cpp
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2012 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "ProfilerOSRExit.h"
+
+#include "JSGlobalObject.h"
+#include "ObjectConstructor.h"
+#include "Operations.h"
+
+namespace JSC { namespace Profiler {
+
+OSRExit::OSRExit(unsigned id, const OriginStack& origin, ExitKind kind, bool isWatchpoint)
+ : m_id(id)
+ , m_origin(origin)
+ , m_exitKind(kind)
+ , m_isWatchpoint(isWatchpoint)
+ , m_counter(0)
+{
+}
+
+OSRExit::~OSRExit()
+{
+}
+
+JSValue OSRExit::toJS(ExecState* exec) const
+{
+ JSObject* result = constructEmptyObject(exec);
+ result->putDirect(exec->vm(), exec->propertyNames().id, jsNumber(m_id));
+ result->putDirect(exec->vm(), exec->propertyNames().origin, m_origin.toJS(exec));
+ result->putDirect(exec->vm(), exec->propertyNames().exitKind, jsString(exec, exitKindToString(m_exitKind)));
+ result->putDirect(exec->vm(), exec->propertyNames().isWatchpoint, jsBoolean(m_isWatchpoint));
+ result->putDirect(exec->vm(), exec->propertyNames().count, jsNumber(m_counter));
+ return result;
+}
+
+} } // namespace JSC::Profiler
+
diff --git a/Source/JavaScriptCore/profiler/ProfilerOSRExit.h b/Source/JavaScriptCore/profiler/ProfilerOSRExit.h
new file mode 100644
index 000000000..2a23d0b2c
--- /dev/null
+++ b/Source/JavaScriptCore/profiler/ProfilerOSRExit.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2012 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef ProfilerOSRExit_h
+#define ProfilerOSRExit_h
+
+#include "ExitKind.h"
+#include "JSCJSValue.h"
+#include "ProfilerOriginStack.h"
+
+namespace JSC { namespace Profiler {
+
+class OSRExit {
+public:
+ OSRExit(unsigned id, const OriginStack&, ExitKind, bool isWatchpoint);
+ ~OSRExit();
+
+ unsigned id() const { return m_id; }
+ const OriginStack& origin() const { return m_origin; }
+ ExitKind exitKind() const { return m_exitKind; }
+ bool isWatchpoint() const { return m_isWatchpoint; }
+
+ uint64_t* counterAddress() { return &m_counter; }
+ uint64_t count() const { return m_counter; }
+
+ JSValue toJS(ExecState*) const;
+
+private:
+ unsigned m_id;
+ OriginStack m_origin;
+ ExitKind m_exitKind;
+ bool m_isWatchpoint;
+ uint64_t m_counter;
+};
+
+} } // namespace JSC::Profiler
+
+#endif // ProfilerOSRExit_h
+
diff --git a/Source/JavaScriptCore/profiler/ProfilerOSRExitSite.cpp b/Source/JavaScriptCore/profiler/ProfilerOSRExitSite.cpp
new file mode 100644
index 000000000..d54f7a275
--- /dev/null
+++ b/Source/JavaScriptCore/profiler/ProfilerOSRExitSite.cpp
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2012 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "ProfilerOSRExitSite.h"
+
+#include "JSGlobalObject.h"
+#include "JSScope.h"
+#include "JSString.h"
+#include "Operations.h"
+#include <wtf/StringPrintStream.h>
+
+namespace JSC { namespace Profiler {
+
+JSValue OSRExitSite::toJS(ExecState* exec) const
+{
+ JSArray* result = constructEmptyArray(exec, 0);
+ for (unsigned i = 0; i < m_codeAddresses.size(); ++i)
+ result->putDirectIndex(exec, i, jsString(exec, toString(RawPointer(m_codeAddresses[i]))));
+ return result;
+}
+
+} } // namespace JSC::Profiler
+
diff --git a/Source/JavaScriptCore/profiler/ProfilerOSRExitSite.h b/Source/JavaScriptCore/profiler/ProfilerOSRExitSite.h
new file mode 100644
index 000000000..fa418e9b8
--- /dev/null
+++ b/Source/JavaScriptCore/profiler/ProfilerOSRExitSite.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2012 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef ProfilerOSRExitSite_h
+#define ProfilerOSRExitSite_h
+
+#include "JSCJSValue.h"
+#include <wtf/Vector.h>
+
+namespace JSC { namespace Profiler {
+
+class OSRExitSite {
+public:
+ explicit OSRExitSite(const Vector<const void*>& codeAddresses)
+ : m_codeAddresses(codeAddresses)
+ {
+ }
+
+ const Vector<const void*>& codeAddress() const { return m_codeAddresses; }
+
+ JSValue toJS(ExecState*) const;
+
+private:
+ Vector<const void*> m_codeAddresses;
+};
+
+} } // namespace JSC::Profiler
+
+#endif // ProfilerOSRExitSite_h
+
diff --git a/Source/JavaScriptCore/profiler/ProfilerOrigin.cpp b/Source/JavaScriptCore/profiler/ProfilerOrigin.cpp
new file mode 100644
index 000000000..1ac29d1cc
--- /dev/null
+++ b/Source/JavaScriptCore/profiler/ProfilerOrigin.cpp
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2012 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "ProfilerOrigin.h"
+
+#include "JSGlobalObject.h"
+#include "ObjectConstructor.h"
+#include "Operations.h"
+#include "ProfilerBytecodes.h"
+#include "ProfilerDatabase.h"
+
+namespace JSC { namespace Profiler {
+
+Origin::Origin(Database& database, CodeBlock* codeBlock, unsigned bytecodeIndex)
+ : m_bytecodes(database.ensureBytecodesFor(codeBlock))
+ , m_bytecodeIndex(bytecodeIndex)
+{
+}
+
+void Origin::dump(PrintStream& out) const
+{
+ out.print(*m_bytecodes, ":bc#", m_bytecodeIndex);
+}
+
+JSValue Origin::toJS(ExecState* exec) const
+{
+ JSObject* result = constructEmptyObject(exec);
+ result->putDirect(exec->vm(), exec->propertyNames().bytecodesID, jsNumber(m_bytecodes->id()));
+ result->putDirect(exec->vm(), exec->propertyNames().bytecodeIndex, jsNumber(m_bytecodeIndex));
+ return result;
+}
+
+} } // namespace JSC::Profiler
+
diff --git a/Source/JavaScriptCore/profiler/ProfilerOrigin.h b/Source/JavaScriptCore/profiler/ProfilerOrigin.h
new file mode 100644
index 000000000..09b388451
--- /dev/null
+++ b/Source/JavaScriptCore/profiler/ProfilerOrigin.h
@@ -0,0 +1,120 @@
+/*
+ * Copyright (C) 2012 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef ProfilerOrigin_h
+#define ProfilerOrigin_h
+
+#include "CodeBlockHash.h"
+#include "JSCJSValue.h"
+#include <wtf/HashMap.h>
+#include <wtf/PrintStream.h>
+
+namespace JSC {
+
+class CodeBlock;
+
+namespace Profiler {
+
+class Bytecodes;
+class Database;
+
+class Origin {
+public:
+ Origin()
+ : m_bytecodeIndex(std::numeric_limits<unsigned>::max())
+ {
+ }
+
+ Origin(WTF::HashTableDeletedValueType)
+ : m_bytecodeIndex(std::numeric_limits<unsigned>::max() - 1)
+ {
+ }
+
+ Origin(Bytecodes* bytecodes, unsigned bytecodeIndex)
+ : m_bytecodes(bytecodes)
+ , m_bytecodeIndex(bytecodeIndex)
+ {
+ ASSERT(m_bytecodeIndex < std::numeric_limits<unsigned>::max() - 1);
+ }
+
+ Origin(Database&, CodeBlock*, unsigned bytecodeIndex);
+
+ bool operator!() const { return m_bytecodeIndex == std::numeric_limits<unsigned>::max(); }
+
+ Bytecodes* bytecodes() const { return m_bytecodes; }
+ unsigned bytecodeIndex() const { return m_bytecodeIndex; }
+
+ bool operator==(const Origin&) const;
+ bool operator!=(const Origin& other) const { return !(*this == other); }
+ unsigned hash() const;
+
+ bool isHashTableDeletedValue() const;
+
+ void dump(PrintStream&) const;
+ JSValue toJS(ExecState*) const;
+
+private:
+ Bytecodes* m_bytecodes;
+ unsigned m_bytecodeIndex;
+};
+
+inline bool Origin::operator==(const Origin& other) const
+{
+ return m_bytecodes == other.m_bytecodes
+ && m_bytecodeIndex == other.m_bytecodeIndex;
+}
+
+inline unsigned Origin::hash() const
+{
+ return WTF::PtrHash<Bytecodes*>::hash(m_bytecodes) + m_bytecodeIndex;
+}
+
+inline bool Origin::isHashTableDeletedValue() const
+{
+ return m_bytecodeIndex == std::numeric_limits<unsigned>::max();
+}
+
+struct OriginHash {
+ static unsigned hash(const Origin& key) { return key.hash(); }
+ static bool equal(const Origin& a, const Origin& b) { return a == b; }
+ static const bool safeToCompareToEmptyOrDeleted = true;
+};
+
+} } // namespace JSC::Profiler
+
+namespace WTF {
+
+template<typename T> struct DefaultHash;
+template<> struct DefaultHash<JSC::Profiler::Origin> {
+ typedef JSC::Profiler::OriginHash Hash;
+};
+
+template<typename T> struct HashTraits;
+template<> struct HashTraits<JSC::Profiler::Origin> : SimpleClassHashTraits<JSC::Profiler::Origin> { };
+
+} // namespace WTF
+
+#endif // ProfilerOrigin_h
+
diff --git a/Source/JavaScriptCore/profiler/ProfilerOriginStack.cpp b/Source/JavaScriptCore/profiler/ProfilerOriginStack.cpp
new file mode 100644
index 000000000..018ceeb8c
--- /dev/null
+++ b/Source/JavaScriptCore/profiler/ProfilerOriginStack.cpp
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2012 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "ProfilerOriginStack.h"
+
+#include "CodeOrigin.h"
+#include "JSGlobalObject.h"
+#include "Operations.h"
+#include "ProfilerDatabase.h"
+
+namespace JSC { namespace Profiler {
+
+OriginStack::OriginStack(WTF::HashTableDeletedValueType)
+{
+ m_stack.append(Origin(WTF::HashTableDeletedValue));
+}
+
+OriginStack::OriginStack(const Origin& origin)
+{
+ m_stack.append(origin);
+}
+
+OriginStack::OriginStack(Database& database, CodeBlock* codeBlock, const CodeOrigin& codeOrigin)
+{
+ Vector<CodeOrigin> stack = codeOrigin.inlineStack();
+
+ append(Origin(database, codeBlock, stack[0].bytecodeIndex));
+
+ for (unsigned i = 1; i < stack.size(); ++i) {
+ append(Origin(
+ database.ensureBytecodesFor(stack[i].inlineCallFrame->baselineCodeBlock()),
+ stack[i].bytecodeIndex));
+ }
+}
+
+OriginStack::~OriginStack() { }
+
+void OriginStack::append(const Origin& origin)
+{
+ m_stack.append(origin);
+}
+
+bool OriginStack::operator==(const OriginStack& other) const
+{
+ if (m_stack.size() != other.m_stack.size())
+ return false;
+
+ for (unsigned i = m_stack.size(); i--;) {
+ if (m_stack[i] != other.m_stack[i])
+ return false;
+ }
+
+ return true;
+}
+
+unsigned OriginStack::hash() const
+{
+ unsigned result = m_stack.size();
+
+ for (unsigned i = m_stack.size(); i--;) {
+ result *= 3;
+ result += m_stack[i].hash();
+ }
+
+ return result;
+}
+
+void OriginStack::dump(PrintStream& out) const
+{
+ for (unsigned i = 0; i < m_stack.size(); ++i) {
+ if (i)
+ out.print(" --> ");
+ out.print(m_stack[i]);
+ }
+}
+
+JSValue OriginStack::toJS(ExecState* exec) const
+{
+ JSArray* result = constructEmptyArray(exec, 0);
+
+ for (unsigned i = 0; i < m_stack.size(); ++i)
+ result->putDirectIndex(exec, i, m_stack[i].toJS(exec));
+
+ return result;
+}
+
+} } // namespace JSC::Profiler
+
diff --git a/Source/JavaScriptCore/profiler/ProfilerOriginStack.h b/Source/JavaScriptCore/profiler/ProfilerOriginStack.h
new file mode 100644
index 000000000..415e8d9b0
--- /dev/null
+++ b/Source/JavaScriptCore/profiler/ProfilerOriginStack.h
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2012 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef ProfilerOriginStack_h
+#define ProfilerOriginStack_h
+
+#include "JSCJSValue.h"
+#include "ProfilerOrigin.h"
+#include <wtf/HashMap.h>
+#include <wtf/PrintStream.h>
+#include <wtf/Vector.h>
+
+namespace JSC {
+
+class CodeBlock;
+struct CodeOrigin;
+
+namespace Profiler {
+
+class Database;
+
+class OriginStack {
+public:
+ OriginStack() { }
+
+ OriginStack(WTF::HashTableDeletedValueType);
+
+ explicit OriginStack(const Origin&);
+
+ explicit OriginStack(Database&, CodeBlock*, const CodeOrigin&);
+
+ ~OriginStack();
+
+ void append(const Origin&);
+
+ bool operator!() const { return m_stack.isEmpty(); }
+
+ unsigned size() const { return m_stack.size(); }
+ const Origin& fromBottom(unsigned i) const { return m_stack[i]; }
+ const Origin& fromTop(unsigned i) const { return m_stack[m_stack.size() - i - 1]; }
+
+ bool operator==(const OriginStack&) const;
+ unsigned hash() const;
+
+ bool isHashTableDeletedValue() const;
+
+ void dump(PrintStream&) const;
+ JSValue toJS(ExecState*) const;
+
+private:
+ Vector<Origin, 1> m_stack;
+};
+
+inline bool OriginStack::isHashTableDeletedValue() const
+{
+ return m_stack.size() == 1 && m_stack[0].isHashTableDeletedValue();
+}
+
+struct OriginStackHash {
+ static unsigned hash(const OriginStack& key) { return key.hash(); }
+ static bool equal(const OriginStack& a, const OriginStack& b) { return a == b; }
+ static const bool safeToCompareToEmptyOrDeleted = true;
+};
+
+} } // namespace JSC::Profiler
+
+namespace WTF {
+
+template<typename T> struct DefaultHash;
+template<> struct DefaultHash<JSC::Profiler::OriginStack> {
+ typedef JSC::Profiler::OriginStackHash Hash;
+};
+
+template<typename T> struct HashTraits;
+template<> struct HashTraits<JSC::Profiler::OriginStack> : SimpleClassHashTraits<JSC::Profiler::OriginStack> { };
+
+} // namespace WTF
+
+#endif // ProfilerOriginStack_h
+
diff --git a/Source/JavaScriptCore/profiler/ProfilerProfiledBytecodes.cpp b/Source/JavaScriptCore/profiler/ProfilerProfiledBytecodes.cpp
new file mode 100644
index 000000000..6ca6c9f15
--- /dev/null
+++ b/Source/JavaScriptCore/profiler/ProfilerProfiledBytecodes.cpp
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2012 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "ProfilerProfiledBytecodes.h"
+
+#include "JSGlobalObject.h"
+#include "ObjectConstructor.h"
+#include "Operations.h"
+
+namespace JSC { namespace Profiler {
+
+ProfiledBytecodes::ProfiledBytecodes(Bytecodes* bytecodes, CodeBlock* profiledBlock)
+ : BytecodeSequence(profiledBlock)
+ , m_bytecodes(bytecodes)
+{
+}
+
+ProfiledBytecodes::~ProfiledBytecodes()
+{
+}
+
+JSValue ProfiledBytecodes::toJS(ExecState* exec) const
+{
+ JSObject* result = constructEmptyObject(exec);
+
+ result->putDirect(exec->vm(), exec->propertyNames().bytecodesID, jsNumber(m_bytecodes->id()));
+ addSequenceProperties(exec, result);
+
+ return result;
+}
+
+} } // namespace JSC::Profiler
+
diff --git a/Source/JavaScriptCore/profiler/ProfilerProfiledBytecodes.h b/Source/JavaScriptCore/profiler/ProfilerProfiledBytecodes.h
new file mode 100644
index 000000000..d7cb6ffa8
--- /dev/null
+++ b/Source/JavaScriptCore/profiler/ProfilerProfiledBytecodes.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2012 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef ProfilerProfiledBytecodes_h
+#define ProfilerProfiledBytecodes_h
+
+#include "ProfilerBytecodeSequence.h"
+#include "ProfilerBytecodes.h"
+#include "ProfilerOriginStack.h"
+
+namespace JSC { namespace Profiler {
+
+class ProfiledBytecodes : public BytecodeSequence {
+public:
+ ProfiledBytecodes(Bytecodes*, CodeBlock*);
+ ~ProfiledBytecodes();
+
+ const Bytecodes* bytecodes() const { return m_bytecodes; }
+
+ JSValue toJS(ExecState*) const;
+
+private:
+ Bytecodes* m_bytecodes;
+};
+
+} } // namespace JSC::Profiler
+
+#endif // ProfilerProfiledBytecodes_h
+