summaryrefslogtreecommitdiff
path: root/Source/JavaScriptCore/profiler
diff options
context:
space:
mode:
authorLorry Tar Creator <lorry-tar-importer@lorry>2017-06-27 06:07:23 +0000
committerLorry Tar Creator <lorry-tar-importer@lorry>2017-06-27 06:07:23 +0000
commit1bf1084f2b10c3b47fd1a588d85d21ed0eb41d0c (patch)
tree46dcd36c86e7fbc6e5df36deb463b33e9967a6f7 /Source/JavaScriptCore/profiler
parent32761a6cee1d0dee366b885b7b9c777e67885688 (diff)
downloadWebKitGtk-tarball-master.tar.gz
Diffstat (limited to 'Source/JavaScriptCore/profiler')
-rw-r--r--Source/JavaScriptCore/profiler/CallIdentifier.h101
-rw-r--r--Source/JavaScriptCore/profiler/LegacyProfiler.cpp184
-rw-r--r--Source/JavaScriptCore/profiler/LegacyProfiler.h73
-rw-r--r--Source/JavaScriptCore/profiler/Profile.cpp102
-rw-r--r--Source/JavaScriptCore/profiler/ProfileGenerator.cpp219
-rw-r--r--Source/JavaScriptCore/profiler/ProfileGenerator.h79
-rw-r--r--Source/JavaScriptCore/profiler/ProfileNode.cpp247
-rw-r--r--Source/JavaScriptCore/profiler/ProfileNode.h140
-rw-r--r--Source/JavaScriptCore/profiler/ProfilerBytecode.cpp3
-rw-r--r--Source/JavaScriptCore/profiler/ProfilerBytecode.h13
-rw-r--r--Source/JavaScriptCore/profiler/ProfilerBytecodeSequence.cpp30
-rw-r--r--Source/JavaScriptCore/profiler/ProfilerBytecodeSequence.h6
-rw-r--r--Source/JavaScriptCore/profiler/ProfilerBytecodes.cpp2
-rw-r--r--Source/JavaScriptCore/profiler/ProfilerBytecodes.h6
-rw-r--r--Source/JavaScriptCore/profiler/ProfilerCompilation.cpp99
-rw-r--r--Source/JavaScriptCore/profiler/ProfilerCompilation.h25
-rw-r--r--Source/JavaScriptCore/profiler/ProfilerCompilationKind.cpp8
-rw-r--r--Source/JavaScriptCore/profiler/ProfilerCompilationKind.h12
-rw-r--r--Source/JavaScriptCore/profiler/ProfilerCompiledBytecode.cpp2
-rw-r--r--Source/JavaScriptCore/profiler/ProfilerCompiledBytecode.h6
-rw-r--r--Source/JavaScriptCore/profiler/ProfilerDatabase.cpp94
-rw-r--r--Source/JavaScriptCore/profiler/ProfilerDatabase.h34
-rw-r--r--Source/JavaScriptCore/profiler/ProfilerEvent.cpp63
-rw-r--r--Source/JavaScriptCore/profiler/ProfilerEvent.h74
-rw-r--r--Source/JavaScriptCore/profiler/ProfilerExecutionCounter.h6
-rw-r--r--Source/JavaScriptCore/profiler/ProfilerJettisonReason.cpp73
-rw-r--r--Source/JavaScriptCore/profiler/ProfilerJettisonReason.h (renamed from Source/JavaScriptCore/profiler/Profile.h)60
-rw-r--r--Source/JavaScriptCore/profiler/ProfilerOSRExit.cpp2
-rw-r--r--Source/JavaScriptCore/profiler/ProfilerOSRExit.h6
-rw-r--r--Source/JavaScriptCore/profiler/ProfilerOSRExitSite.cpp11
-rw-r--r--Source/JavaScriptCore/profiler/ProfilerOSRExitSite.h6
-rw-r--r--Source/JavaScriptCore/profiler/ProfilerOrigin.cpp2
-rw-r--r--Source/JavaScriptCore/profiler/ProfilerOrigin.h6
-rw-r--r--Source/JavaScriptCore/profiler/ProfilerOriginStack.cpp14
-rw-r--r--Source/JavaScriptCore/profiler/ProfilerOriginStack.h6
-rw-r--r--Source/JavaScriptCore/profiler/ProfilerProfiledBytecodes.cpp2
-rw-r--r--Source/JavaScriptCore/profiler/ProfilerProfiledBytecodes.h6
-rw-r--r--Source/JavaScriptCore/profiler/ProfilerUID.cpp56
-rw-r--r--Source/JavaScriptCore/profiler/ProfilerUID.h110
39 files changed, 648 insertions, 1340 deletions
diff --git a/Source/JavaScriptCore/profiler/CallIdentifier.h b/Source/JavaScriptCore/profiler/CallIdentifier.h
deleted file mode 100644
index bf9f904b0..000000000
--- a/Source/JavaScriptCore/profiler/CallIdentifier.h
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * Copyright (C) 2008 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 CallIdentifier_h
-#define CallIdentifier_h
-
-#include <wtf/text/CString.h>
-#include <wtf/text/StringHash.h>
-#include <wtf/text/WTFString.h>
-
-namespace JSC {
-
- struct CallIdentifier {
- WTF_MAKE_FAST_ALLOCATED;
- public:
- String m_name;
- String m_url;
- unsigned m_lineNumber;
-
- CallIdentifier()
- : m_lineNumber(0)
- {
- }
-
- CallIdentifier(const String& name, const String& url, int lineNumber)
- : m_name(name)
- , m_url(!url.isNull() ? url : "")
- , m_lineNumber(lineNumber)
- {
- }
-
- inline bool operator==(const CallIdentifier& ci) const { return ci.m_lineNumber == m_lineNumber && ci.m_name == m_name && ci.m_url == m_url; }
- inline bool operator!=(const CallIdentifier& ci) const { return !(*this == ci); }
-
- struct Hash {
- static unsigned hash(const CallIdentifier& key)
- {
- unsigned hashCodes[3] = {
- key.m_name.impl()->hash(),
- key.m_url.impl()->hash(),
- key.m_lineNumber
- };
- return StringHasher::hashMemory<sizeof(hashCodes)>(hashCodes);
- }
-
- static bool equal(const CallIdentifier& a, const CallIdentifier& b) { return a == b; }
- static const bool safeToCompareToEmptyOrDeleted = true;
- };
-
- unsigned hash() const { return Hash::hash(*this); }
-
-#ifndef NDEBUG
- operator const char*() const { return c_str(); }
- const char* c_str() const { return m_name.utf8().data(); }
-#endif
- };
-
-} // namespace JSC
-
-namespace WTF {
-
- template<> struct DefaultHash<JSC::CallIdentifier> { typedef JSC::CallIdentifier::Hash Hash; };
-
- template<> struct HashTraits<JSC::CallIdentifier> : GenericHashTraits<JSC::CallIdentifier> {
- static void constructDeletedValue(JSC::CallIdentifier& slot)
- {
- new (NotNull, &slot) JSC::CallIdentifier(String(), String(), std::numeric_limits<unsigned>::max());
- }
- static bool isDeletedValue(const JSC::CallIdentifier& value)
- {
- return value.m_name.isNull() && value.m_url.isNull() && value.m_lineNumber == std::numeric_limits<unsigned>::max();
- }
- };
-
-} // namespace WTF
-
-#endif // CallIdentifier_h
-
diff --git a/Source/JavaScriptCore/profiler/LegacyProfiler.cpp b/Source/JavaScriptCore/profiler/LegacyProfiler.cpp
deleted file mode 100644
index dd2acd9f0..000000000
--- a/Source/JavaScriptCore/profiler/LegacyProfiler.cpp
+++ /dev/null
@@ -1,184 +0,0 @@
-/*
- * 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
- * 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.
- * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- * its contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "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 OR ITS 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 "LegacyProfiler.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"
-
-namespace JSC {
-
-static const char* GlobalCodeExecution = "(program)";
-static const char* AnonymousFunction = "(anonymous function)";
-static unsigned ProfilesUID = 0;
-
-static CallIdentifier createCallIdentifierFromFunctionImp(ExecState*, JSObject*, const String& defaultSourceURL, int defaultLineNumber);
-
-LegacyProfiler* LegacyProfiler::s_sharedLegacyProfiler = 0;
-
-LegacyProfiler* LegacyProfiler::profiler()
-{
- if (!s_sharedLegacyProfiler)
- s_sharedLegacyProfiler = new LegacyProfiler();
- return s_sharedLegacyProfiler;
-}
-
-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->lexicalGlobalObject();
-
- for (size_t i = 0; i < m_currentProfiles.size(); ++i) {
- ProfileGenerator* profileGenerator = m_currentProfiles[i].get();
- if (profileGenerator->origin() == origin && profileGenerator->title() == title)
- return;
- }
-
- exec->vm().setEnabledProfiler(this);
- RefPtr<ProfileGenerator> profileGenerator = ProfileGenerator::create(exec, title, ++ProfilesUID);
- m_currentProfiles.append(profileGenerator);
-}
-
-PassRefPtr<Profile> LegacyProfiler::stopProfiling(ExecState* exec, const String& title)
-{
- 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)) {
- profileGenerator->stopProfiling();
- RefPtr<Profile> returnProfile = profileGenerator->profile();
-
- m_currentProfiles.remove(i);
- if (!m_currentProfiles.size())
- exec->vm().setEnabledProfiler(nullptr);
-
- return returnProfile;
- }
- }
-
- return 0;
-}
-
-void LegacyProfiler::stopProfiling(JSGlobalObject* origin)
-{
- for (ptrdiff_t i = m_currentProfiles.size() - 1; i >= 0; --i) {
- ProfileGenerator* profileGenerator = m_currentProfiles[i].get();
- if (profileGenerator->origin() == origin) {
- profileGenerator->stopProfiling();
- m_currentProfiles.remove(i);
- if (!m_currentProfiles.size())
- origin->vm().setEnabledProfiler(nullptr);
- }
- }
-}
-
-static inline void dispatchFunctionToProfiles(ExecState* callerOrHandlerCallFrame, const Vector<RefPtr<ProfileGenerator>>& profiles, ProfileGenerator::ProfileFunction function, const CallIdentifier& callIdentifier, unsigned currentProfileTargetGroup)
-{
- for (size_t i = 0; i < profiles.size(); ++i) {
- if (profiles[i]->profileGroup() == currentProfileTargetGroup || !profiles[i]->origin())
- (profiles[i].get()->*function)(callerOrHandlerCallFrame, callIdentifier);
- }
-}
-
-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 LegacyProfiler::willExecute(ExecState* callerCallFrame, const String& sourceURL, int startingLineNumber)
-{
- ASSERT(!m_currentProfiles.isEmpty());
-
- CallIdentifier callIdentifier = createCallIdentifier(callerCallFrame, JSValue(), sourceURL, startingLineNumber);
-
- dispatchFunctionToProfiles(callerCallFrame, m_currentProfiles, &ProfileGenerator::willExecute, callIdentifier, callerCallFrame->lexicalGlobalObject()->profileGroup());
-}
-
-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 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 LegacyProfiler::exceptionUnwind(ExecState* handlerCallFrame)
-{
- ASSERT(!m_currentProfiles.isEmpty());
-
- dispatchFunctionToProfiles(handlerCallFrame, m_currentProfiles, &ProfileGenerator::exceptionUnwind, createCallIdentifier(handlerCallFrame, JSValue(), "", 0), handlerCallFrame->lexicalGlobalObject()->profileGroup());
-}
-
-CallIdentifier LegacyProfiler::createCallIdentifier(ExecState* exec, JSValue functionValue, const String& defaultSourceURL, int defaultLineNumber)
-{
- if (!functionValue)
- return CallIdentifier(GlobalCodeExecution, defaultSourceURL, defaultLineNumber);
- if (!functionValue.isObject())
- return CallIdentifier("(unknown)", defaultSourceURL, defaultLineNumber);
- if (asObject(functionValue)->inherits(JSFunction::info()) || asObject(functionValue)->inherits(InternalFunction::info()))
- return createCallIdentifierFromFunctionImp(exec, asObject(functionValue), defaultSourceURL, defaultLineNumber);
- return CallIdentifier(makeString("(", asObject(functionValue)->methodTable()->className(asObject(functionValue)), " object)"), defaultSourceURL, defaultLineNumber);
-}
-
-CallIdentifier createCallIdentifierFromFunctionImp(ExecState* exec, JSObject* function, const String& defaultSourceURL, int defaultLineNumber)
-{
- const String& name = getCalculatedDisplayName(exec, function);
- JSFunction* jsFunction = jsDynamicCast<JSFunction*>(function);
- if (jsFunction && !jsFunction->isHostFunction())
- return CallIdentifier(name.isEmpty() ? AnonymousFunction : name, jsFunction->jsExecutable()->sourceURL(), jsFunction->jsExecutable()->lineNo());
- return CallIdentifier(name.isEmpty() ? AnonymousFunction : name, defaultSourceURL, defaultLineNumber);
-}
-
-} // namespace JSC
diff --git a/Source/JavaScriptCore/profiler/LegacyProfiler.h b/Source/JavaScriptCore/profiler/LegacyProfiler.h
deleted file mode 100644
index 607ddec9d..000000000
--- a/Source/JavaScriptCore/profiler/LegacyProfiler.h
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * 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
- * 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.
- * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- * its contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "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 OR ITS 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 LegacyProfiler_h
-#define LegacyProfiler_h
-
-#include "Profile.h"
-#include <wtf/PassRefPtr.h>
-#include <wtf/RefPtr.h>
-#include <wtf/Vector.h>
-
-namespace JSC {
-
-class ExecState;
-class VM;
-class JSGlobalObject;
-class JSObject;
-class JSValue;
-class ProfileGenerator;
-struct CallIdentifier;
-
-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*);
-
- 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);
-
- const Vector<RefPtr<ProfileGenerator>>& currentProfiles() { return m_currentProfiles; };
-
-private:
- Vector<RefPtr<ProfileGenerator>> m_currentProfiles;
- static LegacyProfiler* s_sharedLegacyProfiler;
-};
-
-} // namespace JSC
-
-#endif // LegacyProfiler_h
diff --git a/Source/JavaScriptCore/profiler/Profile.cpp b/Source/JavaScriptCore/profiler/Profile.cpp
deleted file mode 100644
index ed21e7879..000000000
--- a/Source/JavaScriptCore/profiler/Profile.cpp
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * Copyright (C) 2008 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 "Profile.h"
-
-#include "ProfileNode.h"
-#include <wtf/DataLog.h>
-
-namespace JSC {
-
-PassRefPtr<Profile> Profile::create(const String& title, unsigned uid)
-{
- return adoptRef(new Profile(title, uid));
-}
-
-Profile::Profile(const String& title, unsigned uid)
- : m_title(title)
- , m_uid(uid)
-{
- // FIXME: When multi-threading is supported this will be a vector and calls
- // into the profiler will need to know which thread it is executing on.
- m_head = ProfileNode::create(0, CallIdentifier("Thread_1", String(), 0), 0, 0);
-}
-
-Profile::~Profile()
-{
-}
-
-void Profile::forEach(void (ProfileNode::*function)())
-{
- ProfileNode* currentNode = m_head->firstChild();
- for (ProfileNode* nextNode = currentNode; nextNode; nextNode = nextNode->firstChild())
- currentNode = nextNode;
-
- if (!currentNode)
- currentNode = m_head.get();
-
- ProfileNode* endNode = m_head->traverseNextNodePostOrder();
- while (currentNode && currentNode != endNode) {
- (currentNode->*function)();
- currentNode = currentNode->traverseNextNodePostOrder();
- }
-}
-
-#ifndef NDEBUG
-void Profile::debugPrintData() const
-{
- dataLogF("Call graph:\n");
- m_head->debugPrintData(0);
-}
-
-typedef WTF::KeyValuePair<FunctionCallHashCount::ValueType, unsigned> NameCountPair;
-
-static inline bool functionNameCountPairComparator(const NameCountPair& a, const NameCountPair& b)
-{
- return a.value > b.value;
-}
-
-void Profile::debugPrintDataSampleStyle() const
-{
- typedef Vector<NameCountPair> NameCountPairVector;
-
- FunctionCallHashCount countedFunctions;
- dataLogF("Call graph:\n");
- m_head->debugPrintDataSampleStyle(0, countedFunctions);
-
- dataLogF("\nTotal number in stack:\n");
- NameCountPairVector sortedFunctions(countedFunctions.size());
- copyToVector(countedFunctions, sortedFunctions);
-
- std::sort(sortedFunctions.begin(), sortedFunctions.end(), functionNameCountPairComparator);
- for (NameCountPairVector::iterator it = sortedFunctions.begin(); it != sortedFunctions.end(); ++it)
- dataLogF(" %-12d%s\n", (*it).value, String((*it).key).utf8().data());
-
- dataLogF("\nSort by top of stack, same collapsed (when >= 5):\n");
-}
-#endif
-
-} // namespace JSC
diff --git a/Source/JavaScriptCore/profiler/ProfileGenerator.cpp b/Source/JavaScriptCore/profiler/ProfileGenerator.cpp
deleted file mode 100644
index 9361caf70..000000000
--- a/Source/JavaScriptCore/profiler/ProfileGenerator.cpp
+++ /dev/null
@@ -1,219 +0,0 @@
-/*
- * Copyright (C) 2008 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 "ProfileGenerator.h"
-
-#include "CallFrame.h"
-#include "CallFrameInlines.h"
-#include "CodeBlock.h"
-#include "JSGlobalObject.h"
-#include "JSStringRef.h"
-#include "JSFunction.h"
-#include "LegacyProfiler.h"
-#include "Operations.h"
-#include "Profile.h"
-#include "StackVisitor.h"
-#include "Tracing.h"
-
-namespace JSC {
-
-static const char* NonJSExecution = "(idle)";
-
-PassRefPtr<ProfileGenerator> ProfileGenerator::create(ExecState* exec, const String& title, unsigned uid)
-{
- return adoptRef(new ProfileGenerator(exec, title, uid));
-}
-
-ProfileGenerator::ProfileGenerator(ExecState* exec, const String& title, unsigned uid)
- : m_origin(exec ? exec->lexicalGlobalObject() : 0)
- , m_profileGroup(exec ? exec->lexicalGlobalObject()->profileGroup() : 0)
-{
- m_profile = Profile::create(title, uid);
- m_currentNode = m_head = m_profile->head();
- if (exec)
- addParentForConsoleStart(exec);
-}
-
-class AddParentForConsoleStartFunctor {
-public:
- AddParentForConsoleStartFunctor(ExecState* exec, RefPtr<ProfileNode>& head, RefPtr<ProfileNode>& currentNode)
- : m_exec(exec)
- , m_hasSkippedFirstFrame(false)
- , m_foundParent(false)
- , m_head(head)
- , m_currentNode(currentNode)
- {
- }
-
- bool foundParent() const { return m_foundParent; }
-
- StackVisitor::Status operator()(StackVisitor& visitor)
- {
- if (!m_hasSkippedFirstFrame) {
- m_hasSkippedFirstFrame = true;
- return StackVisitor::Continue;
- }
-
- unsigned line = 0;
- unsigned unusedColumn = 0;
- visitor->computeLineAndColumn(line, unusedColumn);
- m_currentNode = ProfileNode::create(m_exec, LegacyProfiler::createCallIdentifier(m_exec, visitor->callee(), visitor->sourceURL(), line), m_head.get(), m_head.get());
- m_head->insertNode(m_currentNode.get());
-
- m_foundParent = true;
- return StackVisitor::Done;
- }
-
-private:
- ExecState* m_exec;
- bool m_hasSkippedFirstFrame;
- bool m_foundParent;
- RefPtr<ProfileNode>& m_head;
- RefPtr<ProfileNode>& m_currentNode;
-};
-
-void ProfileGenerator::addParentForConsoleStart(ExecState* exec)
-{
- AddParentForConsoleStartFunctor functor(exec, m_head, m_currentNode);
- exec->iterate(functor);
-
- if (!functor.foundParent()) {
- m_currentNode = ProfileNode::create(exec, LegacyProfiler::createCallIdentifier(exec, JSValue(), String(), 0), m_head.get(), m_head.get());
- m_head->insertNode(m_currentNode.get());
- }
-}
-
-const String& ProfileGenerator::title() const
-{
- return m_profile->title();
-}
-
-void ProfileGenerator::willExecute(ExecState* callerCallFrame, const CallIdentifier& callIdentifier)
-{
- if (JAVASCRIPTCORE_PROFILE_WILL_EXECUTE_ENABLED()) {
- CString name = callIdentifier.m_name.utf8();
- CString url = callIdentifier.m_url.utf8();
- JAVASCRIPTCORE_PROFILE_WILL_EXECUTE(m_profileGroup, const_cast<char*>(name.data()), const_cast<char*>(url.data()), callIdentifier.m_lineNumber);
- }
-
- if (!m_origin)
- return;
-
- ASSERT(m_currentNode);
- m_currentNode = m_currentNode->willExecute(callerCallFrame, callIdentifier);
-}
-
-void ProfileGenerator::didExecute(ExecState* callerCallFrame, const CallIdentifier& callIdentifier)
-{
- if (JAVASCRIPTCORE_PROFILE_DID_EXECUTE_ENABLED()) {
- CString name = callIdentifier.m_name.utf8();
- CString url = callIdentifier.m_url.utf8();
- JAVASCRIPTCORE_PROFILE_DID_EXECUTE(m_profileGroup, const_cast<char*>(name.data()), const_cast<char*>(url.data()), callIdentifier.m_lineNumber);
- }
-
- if (!m_origin)
- return;
-
- ASSERT(m_currentNode);
- if (m_currentNode->callIdentifier() != callIdentifier) {
- RefPtr<ProfileNode> returningNode = ProfileNode::create(callerCallFrame, callIdentifier, m_head.get(), m_currentNode.get());
- returningNode->setStartTime(m_currentNode->startTime());
- returningNode->didExecute();
- m_currentNode->insertNode(returningNode.release());
- return;
- }
-
- m_currentNode = m_currentNode->didExecute();
-}
-
-void ProfileGenerator::exceptionUnwind(ExecState* handlerCallFrame, const CallIdentifier&)
-{
- // If the current node was called by the handler (==) or any
- // more nested function (>) the we have exited early from it.
- ASSERT(m_currentNode);
- while (m_currentNode->callerCallFrame() >= handlerCallFrame) {
- didExecute(m_currentNode->callerCallFrame(), m_currentNode->callIdentifier());
- ASSERT(m_currentNode);
- }
-}
-
-void ProfileGenerator::stopProfiling()
-{
- m_profile->forEach(&ProfileNode::stopProfiling);
-
- removeProfileStart();
- removeProfileEnd();
-
- ASSERT(m_currentNode);
-
- // Set the current node to the parent, because we are in a call that
- // will not get didExecute call.
- m_currentNode = m_currentNode->parent();
-
- if (double headSelfTime = m_head->selfTime()) {
- RefPtr<ProfileNode> idleNode = ProfileNode::create(0, CallIdentifier(NonJSExecution, String(), 0), m_head.get(), m_head.get());
-
- idleNode->setTotalTime(headSelfTime);
- idleNode->setSelfTime(headSelfTime);
-
- m_head->setSelfTime(0.0);
- m_head->addChild(idleNode.release());
- }
-}
-
-// The console.profile that started this ProfileGenerator will be the first child.
-void ProfileGenerator::removeProfileStart()
-{
- ProfileNode* currentNode = 0;
- for (ProfileNode* next = m_head.get(); next; next = next->firstChild())
- currentNode = next;
-
- if (currentNode->callIdentifier().m_name != "profile")
- return;
-
- // Attribute the time of the node aobut to be removed to the self time of its parent
- currentNode->parent()->setSelfTime(currentNode->parent()->selfTime() + currentNode->totalTime());
- currentNode->parent()->removeChild(currentNode);
-}
-
-// The console.profileEnd that stopped this ProfileGenerator will be the last child.
-void ProfileGenerator::removeProfileEnd()
-{
- ProfileNode* currentNode = 0;
- for (ProfileNode* next = m_head.get(); next; next = next->lastChild())
- currentNode = next;
-
- if (currentNode->callIdentifier().m_name != "profileEnd")
- return;
-
- // Attribute the time of the node aobut to be removed to the self time of its parent
- currentNode->parent()->setSelfTime(currentNode->parent()->selfTime() + currentNode->totalTime());
-
- ASSERT(currentNode->callIdentifier() == (currentNode->parent()->children()[currentNode->parent()->children().size() - 1])->callIdentifier());
- currentNode->parent()->removeChild(currentNode);
-}
-
-} // namespace JSC
diff --git a/Source/JavaScriptCore/profiler/ProfileGenerator.h b/Source/JavaScriptCore/profiler/ProfileGenerator.h
deleted file mode 100644
index 40cc8de01..000000000
--- a/Source/JavaScriptCore/profiler/ProfileGenerator.h
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright (C) 2008 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 ProfileGenerator_h
-#define ProfileGenerator_h
-
-#include "Profile.h"
-#include <wtf/PassRefPtr.h>
-#include <wtf/RefCounted.h>
-#include <wtf/RefPtr.h>
-
-namespace JSC {
-
- class ExecState;
- class JSGlobalObject;
- class Profile;
- class ProfileNode;
- struct CallIdentifier;
-
- class ProfileGenerator : public RefCounted<ProfileGenerator> {
- public:
- static PassRefPtr<ProfileGenerator> create(ExecState*, const WTF::String& title, unsigned uid);
-
- // Members
- const WTF::String& title() const;
- PassRefPtr<Profile> profile() const { return m_profile; }
- JSGlobalObject* origin() const { return m_origin; }
- unsigned profileGroup() const { return m_profileGroup; }
-
- // Collecting
- void willExecute(ExecState* callerCallFrame, const CallIdentifier&);
- void didExecute(ExecState* callerCallFrame, const CallIdentifier&);
-
- void exceptionUnwind(ExecState* handlerCallFrame, const CallIdentifier&);
-
- // Stopping Profiling
- void stopProfiling();
-
- typedef void (ProfileGenerator::*ProfileFunction)(ExecState* callerOrHandlerCallFrame, const CallIdentifier& callIdentifier);
-
- private:
- ProfileGenerator(ExecState*, const WTF::String& title, unsigned uid);
- void addParentForConsoleStart(ExecState*);
-
- void removeProfileStart();
- void removeProfileEnd();
-
- RefPtr<Profile> m_profile;
- JSGlobalObject* m_origin;
- unsigned m_profileGroup;
- RefPtr<ProfileNode> m_head;
- RefPtr<ProfileNode> m_currentNode;
- };
-
-} // namespace JSC
-
-#endif // ProfileGenerator_h
diff --git a/Source/JavaScriptCore/profiler/ProfileNode.cpp b/Source/JavaScriptCore/profiler/ProfileNode.cpp
deleted file mode 100644
index fe2342ea4..000000000
--- a/Source/JavaScriptCore/profiler/ProfileNode.cpp
+++ /dev/null
@@ -1,247 +0,0 @@
-/*
- * Copyright (C) 2008 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.
- * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- * its contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "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 OR ITS 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 "ProfileNode.h"
-
-#include "LegacyProfiler.h"
-#include <wtf/DateMath.h>
-#include <wtf/DataLog.h>
-#include <wtf/text/StringHash.h>
-
-#if OS(WINDOWS)
-#include <windows.h>
-#endif
-
-using namespace WTF;
-
-namespace JSC {
-
-static double getCount()
-{
-#if OS(WINDOWS)
- static LARGE_INTEGER frequency;
- if (!frequency.QuadPart)
- QueryPerformanceFrequency(&frequency);
- LARGE_INTEGER counter;
- QueryPerformanceCounter(&counter);
- return static_cast<double>(counter.QuadPart) / frequency.QuadPart;
-#else
- return currentTimeMS();
-#endif
-}
-
-ProfileNode::ProfileNode(ExecState* callerCallFrame, const CallIdentifier& callIdentifier, ProfileNode* headNode, ProfileNode* parentNode)
- : m_callerCallFrame(callerCallFrame)
- , m_callIdentifier(callIdentifier)
- , m_head(headNode)
- , m_parent(parentNode)
- , m_nextSibling(0)
- , m_startTime(0.0)
- , m_totalTime(0.0)
- , m_selfTime(0.0)
- , m_numberOfCalls(0)
-{
- startTimer();
-}
-
-ProfileNode::ProfileNode(ExecState* callerCallFrame, ProfileNode* headNode, ProfileNode* nodeToCopy)
- : m_callerCallFrame(callerCallFrame)
- , m_callIdentifier(nodeToCopy->callIdentifier())
- , m_head(headNode)
- , m_parent(nodeToCopy->parent())
- , m_nextSibling(0)
- , m_startTime(0.0)
- , m_totalTime(nodeToCopy->totalTime())
- , m_selfTime(nodeToCopy->selfTime())
- , m_numberOfCalls(nodeToCopy->numberOfCalls())
-{
-}
-
-ProfileNode* ProfileNode::willExecute(ExecState* callerCallFrame, const CallIdentifier& callIdentifier)
-{
- for (StackIterator currentChild = m_children.begin(); currentChild != m_children.end(); ++currentChild) {
- if ((*currentChild)->callIdentifier() == callIdentifier) {
- (*currentChild)->startTimer();
- return (*currentChild).get();
- }
- }
-
- RefPtr<ProfileNode> newChild = ProfileNode::create(callerCallFrame, callIdentifier, m_head ? m_head : this, this); // If this ProfileNode has no head it is the head.
- if (m_children.size())
- m_children.last()->setNextSibling(newChild.get());
- m_children.append(newChild.release());
- return m_children.last().get();
-}
-
-ProfileNode* ProfileNode::didExecute()
-{
- endAndRecordCall();
- return m_parent;
-}
-
-void ProfileNode::addChild(PassRefPtr<ProfileNode> prpChild)
-{
- RefPtr<ProfileNode> child = prpChild;
- child->setParent(this);
- if (m_children.size())
- m_children.last()->setNextSibling(child.get());
- m_children.append(child.release());
-}
-
-void ProfileNode::removeChild(ProfileNode* node)
-{
- if (!node)
- return;
-
- for (size_t i = 0; i < m_children.size(); ++i) {
- if (*node == m_children[i].get()) {
- m_children.remove(i);
- break;
- }
- }
-
- resetChildrensSiblings();
-}
-
-void ProfileNode::insertNode(PassRefPtr<ProfileNode> prpNode)
-{
- RefPtr<ProfileNode> node = prpNode;
-
- for (unsigned i = 0; i < m_children.size(); ++i)
- node->addChild(m_children[i].release());
-
- m_children.clear();
- m_children.append(node.release());
-}
-
-void ProfileNode::stopProfiling()
-{
- if (m_startTime)
- endAndRecordCall();
-
- ASSERT(m_selfTime == 0.0 && m_startTime == 0.0);
-
- // Because we iterate in post order all of our children have been stopped before us.
- for (unsigned i = 0; i < m_children.size(); ++i)
- m_selfTime += m_children[i]->totalTime();
-
- ASSERT(m_selfTime <= m_totalTime);
- m_selfTime = m_totalTime - m_selfTime;
-}
-
-ProfileNode* ProfileNode::traverseNextNodePostOrder() const
-{
- ProfileNode* next = m_nextSibling;
- if (!next)
- return m_parent;
- while (ProfileNode* firstChild = next->firstChild())
- next = firstChild;
- return next;
-}
-
-void ProfileNode::endAndRecordCall()
-{
- m_totalTime += m_startTime ? getCount() - m_startTime : 0.0;
- m_startTime = 0.0;
-
- ++m_numberOfCalls;
-}
-
-void ProfileNode::startTimer()
-{
- if (!m_startTime)
- m_startTime = getCount();
-}
-
-void ProfileNode::resetChildrensSiblings()
-{
- unsigned size = m_children.size();
- for (unsigned i = 0; i < size; ++i)
- m_children[i]->setNextSibling(i + 1 == size ? 0 : m_children[i + 1].get());
-}
-
-#ifndef NDEBUG
-void ProfileNode::debugPrintData(int indentLevel) const
-{
- // Print function names
- for (int i = 0; i < indentLevel; ++i)
- dataLogF(" ");
-
- dataLogF("Function Name %s %d SelfTime %.3fms/%.3f%% TotalTime %.3fms/%.3f%% Next Sibling %s\n",
- functionName().utf8().data(),
- m_numberOfCalls, m_selfTime, selfPercent(), m_totalTime, totalPercent(),
- m_nextSibling ? m_nextSibling->functionName().utf8().data() : "");
-
- ++indentLevel;
-
- // Print children's names and information
- for (StackIterator currentChild = m_children.begin(); currentChild != m_children.end(); ++currentChild)
- (*currentChild)->debugPrintData(indentLevel);
-}
-
-// print the profiled data in a format that matches the tool sample's output.
-double ProfileNode::debugPrintDataSampleStyle(int indentLevel, FunctionCallHashCount& countedFunctions) const
-{
- dataLogF(" ");
-
- // Print function names
- const char* name = functionName().utf8().data();
- double sampleCount = m_totalTime * 1000;
- if (indentLevel) {
- for (int i = 0; i < indentLevel; ++i)
- dataLogF(" ");
-
- countedFunctions.add(functionName().impl());
-
- dataLogF("%.0f %s\n", sampleCount ? sampleCount : 1, name);
- } else
- dataLogF("%s\n", name);
-
- ++indentLevel;
-
- // Print children's names and information
- double sumOfChildrensCount = 0.0;
- for (StackIterator currentChild = m_children.begin(); currentChild != m_children.end(); ++currentChild)
- sumOfChildrensCount += (*currentChild)->debugPrintDataSampleStyle(indentLevel, countedFunctions);
-
- sumOfChildrensCount *= 1000; //
- // Print remainder of samples to match sample's output
- if (sumOfChildrensCount < sampleCount) {
- dataLogF(" ");
- while (indentLevel--)
- dataLogF(" ");
-
- dataLogF("%.0f %s\n", sampleCount - sumOfChildrensCount, functionName().utf8().data());
- }
-
- return m_totalTime;
-}
-#endif
-
-} // namespace JSC
diff --git a/Source/JavaScriptCore/profiler/ProfileNode.h b/Source/JavaScriptCore/profiler/ProfileNode.h
deleted file mode 100644
index e21b42282..000000000
--- a/Source/JavaScriptCore/profiler/ProfileNode.h
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- * Copyright (C) 2008 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.
- * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- * its contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "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 OR ITS 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 ProfileNode_h
-#define ProfileNode_h
-
-#include "CallIdentifier.h"
-#include <wtf/HashCountedSet.h>
-#include <wtf/RefCounted.h>
-#include <wtf/RefPtr.h>
-#include <wtf/Vector.h>
-
-namespace JSC {
-
- class ExecState;
- class ProfileNode;
-
- typedef HashCountedSet<StringImpl*> FunctionCallHashCount;
-
- class ProfileNode : public RefCounted<ProfileNode> {
- public:
- static PassRefPtr<ProfileNode> create(ExecState* callerCallFrame, const CallIdentifier& callIdentifier, ProfileNode* headNode, ProfileNode* parentNode)
- {
- return adoptRef(new ProfileNode(callerCallFrame, callIdentifier, headNode, parentNode));
- }
-
- static PassRefPtr<ProfileNode> create(ExecState* callerCallFrame, ProfileNode* headNode, ProfileNode* node)
- {
- return adoptRef(new ProfileNode(callerCallFrame, headNode, node));
- }
-
- bool operator==(ProfileNode* node) { return m_callIdentifier == node->callIdentifier(); }
-
- ProfileNode* willExecute(ExecState* callerCallFrame, const CallIdentifier&);
- ProfileNode* didExecute();
-
- void stopProfiling();
-
- // CallIdentifier members
- ExecState* callerCallFrame() const { return m_callerCallFrame; }
- const CallIdentifier& callIdentifier() const { return m_callIdentifier; }
- unsigned long callUID() const { return m_callIdentifier.hash(); };
- const String& functionName() const { return m_callIdentifier.m_name; }
- const String& url() const { return m_callIdentifier.m_url; }
- unsigned lineNumber() const { return m_callIdentifier.m_lineNumber; }
-
- // Relationships
- ProfileNode* head() const { return m_head; }
- void setHead(ProfileNode* head) { m_head = head; }
-
- ProfileNode* parent() const { return m_parent; }
- void setParent(ProfileNode* parent) { m_parent = parent; }
-
- ProfileNode* nextSibling() const { return m_nextSibling; }
- void setNextSibling(ProfileNode* nextSibling) { m_nextSibling = nextSibling; }
-
- // Time members
- double startTime() const { return m_startTime; }
- void setStartTime(double startTime) { m_startTime = startTime; }
-
- double totalTime() const { return m_totalTime; }
- void setTotalTime(double time) { m_totalTime = time; }
-
- double selfTime() const { return m_selfTime; }
- void setSelfTime(double time) { m_selfTime = time; }
-
- double totalPercent() const { return (m_totalTime / (m_head ? m_head->totalTime() : totalTime())) * 100.0; }
- double selfPercent() const { return (m_selfTime / (m_head ? m_head->totalTime() : totalTime())) * 100.0; }
-
- unsigned numberOfCalls() const { return m_numberOfCalls; }
-
- // Children members
- const Vector<RefPtr<ProfileNode>>& children() const { return m_children; }
- ProfileNode* firstChild() const { return m_children.size() ? m_children.first().get() : 0; }
- ProfileNode* lastChild() const { return m_children.size() ? m_children.last().get() : 0; }
- void removeChild(ProfileNode*);
- void addChild(PassRefPtr<ProfileNode> prpChild);
- void insertNode(PassRefPtr<ProfileNode> prpNode);
-
- ProfileNode* traverseNextNodePostOrder() const;
-
- void endAndRecordCall();
-
-#ifndef NDEBUG
- const char* c_str() const { return m_callIdentifier; }
- void debugPrintData(int indentLevel) const;
- double debugPrintDataSampleStyle(int indentLevel, FunctionCallHashCount&) const;
-#endif
-
- private:
- typedef Vector<RefPtr<ProfileNode>>::const_iterator StackIterator;
-
- ProfileNode(ExecState* callerCallFrame, const CallIdentifier&, ProfileNode* headNode, ProfileNode* parentNode);
- ProfileNode(ExecState* callerCallFrame, ProfileNode* headNode, ProfileNode* nodeToCopy);
-
- void startTimer();
- void resetChildrensSiblings();
-
- ExecState* m_callerCallFrame;
- CallIdentifier m_callIdentifier;
- ProfileNode* m_head;
- ProfileNode* m_parent;
- ProfileNode* m_nextSibling;
-
- double m_startTime;
- double m_totalTime;
- double m_selfTime;
- unsigned m_numberOfCalls;
-
- Vector<RefPtr<ProfileNode>> m_children;
- };
-
-} // namespace JSC
-
-#endif // ProfileNode_h
diff --git a/Source/JavaScriptCore/profiler/ProfilerBytecode.cpp b/Source/JavaScriptCore/profiler/ProfilerBytecode.cpp
index ca602e42f..b76e78f98 100644
--- a/Source/JavaScriptCore/profiler/ProfilerBytecode.cpp
+++ b/Source/JavaScriptCore/profiler/ProfilerBytecode.cpp
@@ -28,7 +28,8 @@
#include "JSGlobalObject.h"
#include "ObjectConstructor.h"
-#include "Operations.h"
+#include "Opcode.h"
+#include "JSCInlines.h"
namespace JSC { namespace Profiler {
diff --git a/Source/JavaScriptCore/profiler/ProfilerBytecode.h b/Source/JavaScriptCore/profiler/ProfilerBytecode.h
index 8e99c9a09..72c66c5c3 100644
--- a/Source/JavaScriptCore/profiler/ProfilerBytecode.h
+++ b/Source/JavaScriptCore/profiler/ProfilerBytecode.h
@@ -23,14 +23,16 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef ProfilerBytecode_h
-#define ProfilerBytecode_h
+#pragma once
#include "JSCJSValue.h"
-#include "Opcode.h"
#include <wtf/text/CString.h>
-namespace JSC { namespace Profiler {
+namespace JSC {
+
+enum OpcodeID : unsigned;
+
+namespace Profiler {
class Bytecode {
public:
@@ -60,6 +62,3 @@ private:
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
index 838153bea..09b8213d9 100644
--- a/Source/JavaScriptCore/profiler/ProfilerBytecodeSequence.cpp
+++ b/Source/JavaScriptCore/profiler/ProfilerBytecodeSequence.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2012, 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2012-2014, 2016 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,9 +27,10 @@
#include "ProfilerBytecodeSequence.h"
#include "CodeBlock.h"
+#include "Interpreter.h"
+#include "JSCInlines.h"
#include "JSGlobalObject.h"
#include "Operands.h"
-#include "Operations.h"
#include <wtf/StringPrintStream.h>
namespace JSC { namespace Profiler {
@@ -39,18 +40,21 @@ BytecodeSequence::BytecodeSequence(CodeBlock* codeBlock)
StringPrintStream out;
for (unsigned i = 0; i < codeBlock->numberOfArgumentValueProfiles(); ++i) {
- ConcurrentJITLocker locker(codeBlock->m_lock);
+ ConcurrentJSLocker locker(codeBlock->m_lock);
CString description = codeBlock->valueProfileForArgument(i)->briefDescription(locker);
if (!description.length())
continue;
out.reset();
- out.print("arg", i, " (r", virtualRegisterForArgument(i).offset(), "): ", description);
+ out.print("arg", i, ": ", description);
m_header.append(out.toCString());
}
+ StubInfoMap stubInfos;
+ codeBlock->getStubInfoMap(stubInfos);
+
for (unsigned bytecodeIndex = 0; bytecodeIndex < codeBlock->instructions().size();) {
out.reset();
- codeBlock->dumpBytecode(out, bytecodeIndex);
+ codeBlock->dumpBytecode(out, bytecodeIndex, stubInfos);
m_sequence.append(Bytecode(bytecodeIndex, codeBlock->vm()->interpreter->getOpcodeID(codeBlock->instructions()[bytecodeIndex].u.opcode), out.toCString()));
bytecodeIndex += opcodeLength(
codeBlock->vm()->interpreter->getOpcodeID(
@@ -74,15 +78,23 @@ const Bytecode& BytecodeSequence::forBytecodeIndex(unsigned bytecodeIndex) const
void BytecodeSequence::addSequenceProperties(ExecState* exec, JSObject* result) const
{
+ VM& vm = exec->vm();
+ auto scope = DECLARE_THROW_SCOPE(vm);
JSArray* header = constructEmptyArray(exec, 0);
- for (unsigned i = 0; i < m_header.size(); ++i)
+ RETURN_IF_EXCEPTION(scope, void());
+ 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);
+ RETURN_IF_EXCEPTION(scope, void());
+ }
+ result->putDirect(vm, exec->propertyNames().header, header);
JSArray* sequence = constructEmptyArray(exec, 0);
- for (unsigned i = 0; i < m_sequence.size(); ++i)
+ RETURN_IF_EXCEPTION(scope, void());
+ 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);
+ RETURN_IF_EXCEPTION(scope, void());
+ }
+ result->putDirect(vm, exec->propertyNames().bytecode, sequence);
}
} } // namespace JSC::Profiler
diff --git a/Source/JavaScriptCore/profiler/ProfilerBytecodeSequence.h b/Source/JavaScriptCore/profiler/ProfilerBytecodeSequence.h
index 1d5c82a18..979f0c4a9 100644
--- a/Source/JavaScriptCore/profiler/ProfilerBytecodeSequence.h
+++ b/Source/JavaScriptCore/profiler/ProfilerBytecodeSequence.h
@@ -23,8 +23,7 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef ProfilerBytecodeSequence_h
-#define ProfilerBytecodeSequence_h
+#pragma once
#include "JSCJSValue.h"
#include "ProfilerBytecode.h"
@@ -60,6 +59,3 @@ private:
};
} } // namespace JSC::Profiler
-
-#endif // ProfilerBytecodeSequence_h
-
diff --git a/Source/JavaScriptCore/profiler/ProfilerBytecodes.cpp b/Source/JavaScriptCore/profiler/ProfilerBytecodes.cpp
index aa5a6d9c9..74c55abcf 100644
--- a/Source/JavaScriptCore/profiler/ProfilerBytecodes.cpp
+++ b/Source/JavaScriptCore/profiler/ProfilerBytecodes.cpp
@@ -29,7 +29,7 @@
#include "CodeBlock.h"
#include "JSGlobalObject.h"
#include "ObjectConstructor.h"
-#include "Operations.h"
+#include "JSCInlines.h"
#include <wtf/StringPrintStream.h>
namespace JSC { namespace Profiler {
diff --git a/Source/JavaScriptCore/profiler/ProfilerBytecodes.h b/Source/JavaScriptCore/profiler/ProfilerBytecodes.h
index e44598019..b85936da0 100644
--- a/Source/JavaScriptCore/profiler/ProfilerBytecodes.h
+++ b/Source/JavaScriptCore/profiler/ProfilerBytecodes.h
@@ -23,8 +23,7 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef ProfilerBytecodes_h
-#define ProfilerBytecodes_h
+#pragma once
#include "CodeBlockHash.h"
#include "JSCJSValue.h"
@@ -58,6 +57,3 @@ private:
};
} } // namespace JSC::Profiler
-
-#endif // ProfilerBytecodes_h
-
diff --git a/Source/JavaScriptCore/profiler/ProfilerCompilation.cpp b/Source/JavaScriptCore/profiler/ProfilerCompilation.cpp
index 55766ce5c..255f8319c 100644
--- a/Source/JavaScriptCore/profiler/ProfilerCompilation.cpp
+++ b/Source/JavaScriptCore/profiler/ProfilerCompilation.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2012, 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2012-2014, 2016 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -28,8 +28,9 @@
#include "JSGlobalObject.h"
#include "ObjectConstructor.h"
-#include "Operations.h"
+#include "JSCInlines.h"
#include "ProfilerDatabase.h"
+#include "Watchpoint.h"
#include <wtf/StringPrintStream.h>
namespace JSC { namespace Profiler {
@@ -37,9 +38,11 @@ namespace JSC { namespace Profiler {
Compilation::Compilation(Bytecodes* bytecodes, CompilationKind kind)
: m_bytecodes(bytecodes)
, m_kind(kind)
+ , m_jettisonReason(NotJettisoned)
, m_numInlinedGetByIds(0)
, m_numInlinedPutByIds(0)
, m_numInlinedCalls(0)
+ , m_uid(UID::create())
{
}
@@ -67,6 +70,11 @@ void Compilation::addDescription(const CompiledBytecode& compiledBytecode)
m_descriptions.append(compiledBytecode);
}
+void Compilation::addDescription(const OriginStack& stack, const CString& description)
+{
+ addDescription(CompiledBytecode(stack, description));
+}
+
ExecutionCounter* Compilation::executionCounterFor(const OriginStack& origin)
{
std::unique_ptr<ExecutionCounter>& counter = m_counters.add(origin, nullptr).iterator->value;
@@ -87,45 +95,92 @@ OSRExit* Compilation::addOSRExit(unsigned id, const OriginStack& originStack, Ex
return &m_osrExits.last();
}
+void Compilation::setJettisonReason(JettisonReason jettisonReason, const FireDetail* detail)
+{
+ if (m_jettisonReason != NotJettisoned)
+ return; // We only care about the original jettison reason.
+
+ m_jettisonReason = jettisonReason;
+ if (detail)
+ m_additionalJettisonReason = toCString(*detail);
+ else
+ m_additionalJettisonReason = CString();
+}
+
+void Compilation::dump(PrintStream& out) const
+{
+ out.print("Comp", m_uid);
+}
+
JSValue Compilation::toJS(ExecState* exec) const
{
+ VM& vm = exec->vm();
+ auto scope = DECLARE_THROW_SCOPE(vm);
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))));
+ RETURN_IF_EXCEPTION(scope, { });
+ result->putDirect(vm, exec->propertyNames().bytecodesID, jsNumber(m_bytecodes->id()));
+ result->putDirect(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);
+ RETURN_IF_EXCEPTION(scope, { });
+ for (unsigned i = 0; i < m_profiledBytecodes.size(); ++i) {
+ auto value = m_profiledBytecodes[i].toJS(exec);
+ RETURN_IF_EXCEPTION(scope, { });
+ profiledBytecodes->putDirectIndex(exec, i, value);
+ RETURN_IF_EXCEPTION(scope, { });
+ }
+ result->putDirect(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);
+ RETURN_IF_EXCEPTION(scope, { });
+ for (unsigned i = 0; i < m_descriptions.size(); ++i) {
+ auto value = m_descriptions[i].toJS(exec);
+ RETURN_IF_EXCEPTION(scope, { });
+ descriptions->putDirectIndex(exec, i, value);
+ RETURN_IF_EXCEPTION(scope, { });
+ }
+ result->putDirect(vm, exec->propertyNames().descriptions, descriptions);
JSArray* counters = constructEmptyArray(exec, 0);
+ RETURN_IF_EXCEPTION(scope, { });
for (auto it = m_counters.begin(), end = m_counters.end(); it != end; ++it) {
JSObject* counterEntry = constructEmptyObject(exec);
- counterEntry->putDirect(exec->vm(), exec->propertyNames().origin, it->key.toJS(exec));
- counterEntry->putDirect(exec->vm(), exec->propertyNames().executionCount, jsNumber(it->value->count()));
+ RETURN_IF_EXCEPTION(scope, { });
+ auto value = it->key.toJS(exec);
+ RETURN_IF_EXCEPTION(scope, { });
+ counterEntry->putDirect(vm, exec->propertyNames().origin, value);
+ counterEntry->putDirect(vm, exec->propertyNames().executionCount, jsNumber(it->value->count()));
counters->push(exec, counterEntry);
+ RETURN_IF_EXCEPTION(scope, { });
}
- result->putDirect(exec->vm(), exec->propertyNames().counters, counters);
+ result->putDirect(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);
+ RETURN_IF_EXCEPTION(scope, { });
+ for (unsigned i = 0; i < m_osrExitSites.size(); ++i) {
+ auto value = m_osrExitSites[i].toJS(exec);
+ RETURN_IF_EXCEPTION(scope, { });
+ exitSites->putDirectIndex(exec, i, value);
+ RETURN_IF_EXCEPTION(scope, { });
+ }
+ result->putDirect(vm, exec->propertyNames().osrExitSites, exitSites);
JSArray* exits = constructEmptyArray(exec, 0);
- for (unsigned i = 0; i < m_osrExits.size(); ++i)
+ RETURN_IF_EXCEPTION(scope, { });
+ 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);
+ RETURN_IF_EXCEPTION(scope, { });
+ }
+ result->putDirect(vm, exec->propertyNames().osrExits, exits);
+
+ result->putDirect(vm, exec->propertyNames().numInlinedGetByIds, jsNumber(m_numInlinedGetByIds));
+ result->putDirect(vm, exec->propertyNames().numInlinedPutByIds, jsNumber(m_numInlinedPutByIds));
+ result->putDirect(vm, exec->propertyNames().numInlinedCalls, jsNumber(m_numInlinedCalls));
+ result->putDirect(vm, exec->propertyNames().jettisonReason, jsString(exec, String::fromUTF8(toCString(m_jettisonReason))));
+ if (!m_additionalJettisonReason.isNull())
+ result->putDirect(vm, exec->propertyNames().additionalJettisonReason, jsString(exec, String::fromUTF8(m_additionalJettisonReason)));
- 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));
+ result->putDirect(vm, exec->propertyNames().uid, m_uid.toJS(exec));
return result;
}
diff --git a/Source/JavaScriptCore/profiler/ProfilerCompilation.h b/Source/JavaScriptCore/profiler/ProfilerCompilation.h
index dc2810525..1e058627c 100644
--- a/Source/JavaScriptCore/profiler/ProfilerCompilation.h
+++ b/Source/JavaScriptCore/profiler/ProfilerCompilation.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2012, 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2012-2014, 2016 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -23,22 +23,27 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef ProfilerCompilation_h
-#define ProfilerCompilation_h
+#pragma once
#include "ExitKind.h"
#include "JSCJSValue.h"
#include "ProfilerCompilationKind.h"
#include "ProfilerCompiledBytecode.h"
#include "ProfilerExecutionCounter.h"
+#include "ProfilerJettisonReason.h"
#include "ProfilerOSRExit.h"
#include "ProfilerOSRExitSite.h"
#include "ProfilerOriginStack.h"
#include "ProfilerProfiledBytecodes.h"
+#include "ProfilerUID.h"
#include <wtf/RefCounted.h>
#include <wtf/SegmentedVector.h>
-namespace JSC { namespace Profiler {
+namespace JSC {
+
+class FireDetail;
+
+namespace Profiler {
class Bytecodes;
class Database;
@@ -63,15 +68,23 @@ public:
CompilationKind kind() const { return m_kind; }
void addDescription(const CompiledBytecode&);
+ void addDescription(const OriginStack&, const CString& description);
ExecutionCounter* executionCounterFor(const OriginStack&);
void addOSRExitSite(const Vector<const void*>& codeAddresses);
OSRExit* addOSRExit(unsigned id, const OriginStack&, ExitKind, bool isWatchpoint);
+ void setJettisonReason(JettisonReason, const FireDetail*);
+
+ UID uid() const { return m_uid; }
+
+ void dump(PrintStream&) const;
JSValue toJS(ExecState*) const;
private:
Bytecodes* m_bytecodes;
CompilationKind m_kind;
+ JettisonReason m_jettisonReason;
+ CString m_additionalJettisonReason;
Vector<ProfiledBytecodes> m_profiledBytecodes;
Vector<CompiledBytecode> m_descriptions;
HashMap<OriginStack, std::unique_ptr<ExecutionCounter>> m_counters;
@@ -80,9 +93,7 @@ private:
unsigned m_numInlinedGetByIds;
unsigned m_numInlinedPutByIds;
unsigned m_numInlinedCalls;
+ UID m_uid;
};
} } // namespace JSC::Profiler
-
-#endif // ProfilerCompilation_h
-
diff --git a/Source/JavaScriptCore/profiler/ProfilerCompilationKind.cpp b/Source/JavaScriptCore/profiler/ProfilerCompilationKind.cpp
index 78ce70586..3fbe25192 100644
--- a/Source/JavaScriptCore/profiler/ProfilerCompilationKind.cpp
+++ b/Source/JavaScriptCore/profiler/ProfilerCompilationKind.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2012, 2014 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -42,6 +42,12 @@ void printInternal(PrintStream& out, JSC::Profiler::CompilationKind kind)
case JSC::Profiler::DFG:
out.print("DFG");
return;
+ case JSC::Profiler::FTL:
+ out.print("FTL");
+ return;
+ case JSC::Profiler::FTLForOSREntry:
+ out.print("FTLForOSREntry");
+ return;
default:
CRASH();
return;
diff --git a/Source/JavaScriptCore/profiler/ProfilerCompilationKind.h b/Source/JavaScriptCore/profiler/ProfilerCompilationKind.h
index 4806d39b9..aaefd4b46 100644
--- a/Source/JavaScriptCore/profiler/ProfilerCompilationKind.h
+++ b/Source/JavaScriptCore/profiler/ProfilerCompilationKind.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2012, 2014 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -23,15 +23,16 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef ProfilerCompilationKind_h
-#define ProfilerCompilationKind_h
+#pragma once
namespace JSC { namespace Profiler {
enum CompilationKind {
LLInt,
Baseline,
- DFG
+ DFG,
+ FTL,
+ FTLForOSREntry
};
} } // namespace JSC::Profiler
@@ -42,6 +43,3 @@ 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
index 455a48ed9..4891c315c 100644
--- a/Source/JavaScriptCore/profiler/ProfilerCompiledBytecode.cpp
+++ b/Source/JavaScriptCore/profiler/ProfilerCompiledBytecode.cpp
@@ -28,7 +28,7 @@
#include "JSGlobalObject.h"
#include "ObjectConstructor.h"
-#include "Operations.h"
+#include "JSCInlines.h"
namespace JSC { namespace Profiler {
diff --git a/Source/JavaScriptCore/profiler/ProfilerCompiledBytecode.h b/Source/JavaScriptCore/profiler/ProfilerCompiledBytecode.h
index 84044445a..5f8e4dfe5 100644
--- a/Source/JavaScriptCore/profiler/ProfilerCompiledBytecode.h
+++ b/Source/JavaScriptCore/profiler/ProfilerCompiledBytecode.h
@@ -23,8 +23,7 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef ProfilerCompiledBytecode_h
-#define ProfilerCompiledBytecode_h
+#pragma once
#include "JSCJSValue.h"
#include "ProfilerOriginStack.h"
@@ -50,6 +49,3 @@ private:
};
} } // namespace JSC::Profiler
-
-#endif // ProfilerCompiledBytecode_h
-
diff --git a/Source/JavaScriptCore/profiler/ProfilerDatabase.cpp b/Source/JavaScriptCore/profiler/ProfilerDatabase.cpp
index f83652dda..01cefc443 100644
--- a/Source/JavaScriptCore/profiler/ProfilerDatabase.cpp
+++ b/Source/JavaScriptCore/profiler/ProfilerDatabase.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2012, 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2012-2013, 2016 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -29,13 +29,14 @@
#include "CodeBlock.h"
#include "JSONObject.h"
#include "ObjectConstructor.h"
-#include "Operations.h"
+#include "JSCInlines.h"
+#include <wtf/CurrentTime.h>
namespace JSC { namespace Profiler {
static std::atomic<int> databaseCounter;
-static SpinLock registrationLock = SPINLOCK_INITIALIZER;
+static StaticLock registrationLock;
static std::atomic<int> didRegisterAtExit;
static Database* firstDatabase;
@@ -57,9 +58,13 @@ Database::~Database()
Bytecodes* Database::ensureBytecodesFor(CodeBlock* codeBlock)
{
- Locker locker(m_lock);
-
- codeBlock = codeBlock->baselineVersion();
+ LockHolder locker(m_lock);
+ return ensureBytecodesFor(locker, codeBlock);
+}
+
+Bytecodes* Database::ensureBytecodesFor(const LockHolder&, CodeBlock* codeBlock)
+{
+ codeBlock = codeBlock->baselineAlternative();
HashMap<CodeBlock*, Bytecodes*>::iterator iter = m_bytecodesMap.find(codeBlock);
if (iter != m_bytecodesMap.end())
@@ -75,50 +80,85 @@ Bytecodes* Database::ensureBytecodesFor(CodeBlock* codeBlock)
void Database::notifyDestruction(CodeBlock* codeBlock)
{
- Locker locker(m_lock);
+ LockHolder locker(m_lock);
m_bytecodesMap.remove(codeBlock);
+ m_compilationMap.remove(codeBlock);
}
-void Database::addCompilation(PassRefPtr<Compilation> compilation)
+void Database::addCompilation(CodeBlock* codeBlock, Ref<Compilation>&& compilation)
{
+ LockHolder locker(m_lock);
ASSERT(!isCompilationThread());
-
- m_compilations.append(compilation);
+
+ m_compilations.append(compilation.copyRef());
+ m_compilationMap.set(codeBlock, WTFMove(compilation));
}
JSValue Database::toJS(ExecState* exec) const
{
+ VM& vm = exec->vm();
+ auto scope = DECLARE_THROW_SCOPE(vm);
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);
+ RETURN_IF_EXCEPTION(scope, { });
+ for (unsigned i = 0; i < m_bytecodes.size(); ++i) {
+ auto value = m_bytecodes[i].toJS(exec);
+ RETURN_IF_EXCEPTION(scope, { });
+ bytecodes->putDirectIndex(exec, i, value);
+ RETURN_IF_EXCEPTION(scope, { });
+ }
+ result->putDirect(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_IF_EXCEPTION(scope, { });
+ for (unsigned i = 0; i < m_compilations.size(); ++i) {
+ auto value = m_compilations[i]->toJS(exec);
+ RETURN_IF_EXCEPTION(scope, { });
+ compilations->putDirectIndex(exec, i, value);
+ RETURN_IF_EXCEPTION(scope, { });
+ }
+ result->putDirect(vm, exec->propertyNames().compilations, compilations);
+
+ JSArray* events = constructEmptyArray(exec, 0);
+ RETURN_IF_EXCEPTION(scope, { });
+ for (unsigned i = 0; i < m_events.size(); ++i) {
+ auto value = m_events[i].toJS(exec);
+ RETURN_IF_EXCEPTION(scope, { });
+ events->putDirectIndex(exec, i, value);
+ RETURN_IF_EXCEPTION(scope, { });
+ }
+ result->putDirect(vm, exec->propertyNames().events, events);
return result;
}
String Database::toJSON() const
{
+ auto scope = DECLARE_THROW_SCOPE(m_vm);
JSGlobalObject* globalObject = JSGlobalObject::create(
m_vm, JSGlobalObject::createStructure(m_vm, jsNull()));
-
- return JSONStringify(globalObject->globalExec(), toJS(globalObject->globalExec()), 0);
+
+ auto value = toJS(globalObject->globalExec());
+ RETURN_IF_EXCEPTION(scope, String());
+ scope.release();
+ return JSONStringify(globalObject->globalExec(), value, 0);
}
bool Database::save(const char* filename) const
{
+ auto scope = DECLARE_CATCH_SCOPE(m_vm);
auto out = FilePrintStream::open(filename, "w");
if (!out)
return false;
- out->print(toJSON());
+ String data = toJSON();
+ if (UNLIKELY(scope.exception())) {
+ scope.clearException();
+ return false;
+ }
+ out->print(data);
return true;
}
@@ -133,19 +173,28 @@ void Database::registerToSaveAtExit(const char* filename)
m_shouldSaveAtExit = true;
}
+void Database::logEvent(CodeBlock* codeBlock, const char* summary, const CString& detail)
+{
+ LockHolder locker(m_lock);
+
+ Bytecodes* bytecodes = ensureBytecodesFor(locker, codeBlock);
+ Compilation* compilation = m_compilationMap.get(codeBlock);
+ m_events.append(Event(currentTime(), bytecodes, compilation, summary, detail));
+}
+
void Database::addDatabaseToAtExit()
{
if (++didRegisterAtExit == 1)
atexit(atExitCallback);
- TCMalloc_SpinLockHolder holder(&registrationLock);
+ LockHolder holder(registrationLock);
m_nextRegisteredDatabase = firstDatabase;
firstDatabase = this;
}
void Database::removeDatabaseFromAtExit()
{
- TCMalloc_SpinLockHolder holder(&registrationLock);
+ LockHolder holder(registrationLock);
for (Database** current = &firstDatabase; *current; current = &(*current)->m_nextRegisteredDatabase) {
if (*current != this)
continue;
@@ -158,12 +207,13 @@ void Database::removeDatabaseFromAtExit()
void Database::performAtExitSave() const
{
+ JSLockHolder lock(m_vm);
save(m_atExitSaveFilename.data());
}
Database* Database::removeFirstAtExitDatabase()
{
- TCMalloc_SpinLockHolder holder(&registrationLock);
+ LockHolder holder(registrationLock);
Database* result = firstDatabase;
if (result) {
firstDatabase = result->m_nextRegisteredDatabase;
diff --git a/Source/JavaScriptCore/profiler/ProfilerDatabase.h b/Source/JavaScriptCore/profiler/ProfilerDatabase.h
index 7d4f3cf2c..b9ef36c03 100644
--- a/Source/JavaScriptCore/profiler/ProfilerDatabase.h
+++ b/Source/JavaScriptCore/profiler/ProfilerDatabase.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2012, 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2012-2013, 2016 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -23,17 +23,17 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef ProfilerDatabase_h
-#define ProfilerDatabase_h
+#pragma once
#include "JSCJSValue.h"
#include "ProfilerBytecodes.h"
#include "ProfilerCompilation.h"
#include "ProfilerCompilationKind.h"
+#include "ProfilerEvent.h"
#include <wtf/FastMalloc.h>
#include <wtf/HashMap.h>
+#include <wtf/Lock.h>
#include <wtf/Noncopyable.h>
-#include <wtf/PassRefPtr.h>
#include <wtf/SegmentedVector.h>
#include <wtf/ThreadingPrimitives.h>
#include <wtf/text/WTFString.h>
@@ -51,7 +51,7 @@ public:
Bytecodes* ensureBytecodesFor(CodeBlock*);
void notifyDestruction(CodeBlock*);
- void addCompilation(PassRefPtr<Compilation>);
+ void addCompilation(CodeBlock*, Ref<Compilation>&&);
// 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
@@ -69,22 +69,11 @@ public:
void registerToSaveAtExit(const char* filename);
+ JS_EXPORT_PRIVATE void logEvent(CodeBlock* codeBlock, const char* summary, const CString& detail);
+
private:
- // Use a full-blown adaptive mutex because:
- // - There is only one ProfilerDatabase per VM. The size overhead of the system's
- // mutex is negligible if you only have one of them.
- // - It's locked infrequently - once per bytecode generation, compilation, and
- // code block collection - so the fact that the fast path still requires a
- // function call is neglible.
- // - It tends to be held for a while. Currently, we hold it while generating
- // Profiler::Bytecodes for a CodeBlock. That's uncommon and shouldn't affect
- // performance, but if we did have contention, we would want a sensible,
- // power-aware backoff. An adaptive mutex will do this as a matter of course,
- // but a spinlock won't.
- typedef Mutex Lock;
- typedef MutexLocker Locker;
+ Bytecodes* ensureBytecodesFor(const LockHolder&, CodeBlock*);
-
void addDatabaseToAtExit();
void removeDatabaseFromAtExit();
void performAtExitSave() const;
@@ -95,7 +84,9 @@ private:
VM& m_vm;
SegmentedVector<Bytecodes> m_bytecodes;
HashMap<CodeBlock*, Bytecodes*> m_bytecodesMap;
- Vector<RefPtr<Compilation>> m_compilations;
+ Vector<Ref<Compilation>> m_compilations;
+ HashMap<CodeBlock*, Ref<Compilation>> m_compilationMap;
+ Vector<Event> m_events;
bool m_shouldSaveAtExit;
CString m_atExitSaveFilename;
Database* m_nextRegisteredDatabase;
@@ -103,6 +94,3 @@ private:
};
} } // namespace JSC::Profiler
-
-#endif // ProfilerDatabase_h
-
diff --git a/Source/JavaScriptCore/profiler/ProfilerEvent.cpp b/Source/JavaScriptCore/profiler/ProfilerEvent.cpp
new file mode 100644
index 000000000..e84ef6f3c
--- /dev/null
+++ b/Source/JavaScriptCore/profiler/ProfilerEvent.cpp
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2016 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 "ProfilerEvent.h"
+
+#include "JSCInlines.h"
+#include "ObjectConstructor.h"
+#include "ProfilerBytecodes.h"
+#include "ProfilerCompilation.h"
+#include "ProfilerUID.h"
+
+namespace JSC { namespace Profiler {
+
+void Event::dump(PrintStream& out) const
+{
+ out.print(m_time, ": ", pointerDump(m_bytecodes));
+ if (m_compilation)
+ out.print(" ", *m_compilation);
+ out.print(": ", m_summary);
+ if (m_detail.length())
+ out.print(" (", m_detail, ")");
+}
+
+JSValue Event::toJS(ExecState* exec) const
+{
+ JSObject* result = constructEmptyObject(exec);
+
+ result->putDirect(exec->vm(), exec->propertyNames().time, jsNumber(m_time));
+ result->putDirect(exec->vm(), exec->propertyNames().bytecodesID, jsNumber(m_bytecodes->id()));
+ if (m_compilation)
+ result->putDirect(exec->vm(), exec->propertyNames().compilationUID, m_compilation->uid().toJS(exec));
+ result->putDirect(exec->vm(), exec->propertyNames().summary, jsString(exec, String::fromUTF8(m_summary)));
+ if (m_detail.length())
+ result->putDirect(exec->vm(), exec->propertyNames().detail, jsString(exec, String::fromUTF8(m_detail)));
+
+ return result;
+}
+
+} } // namespace JSC::Profiler
+
diff --git a/Source/JavaScriptCore/profiler/ProfilerEvent.h b/Source/JavaScriptCore/profiler/ProfilerEvent.h
new file mode 100644
index 000000000..11cb6dab2
--- /dev/null
+++ b/Source/JavaScriptCore/profiler/ProfilerEvent.h
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+
+#pragma once
+
+#include "JSCJSValue.h"
+#include <wtf/PrintStream.h>
+#include <wtf/text/CString.h>
+
+namespace JSC { namespace Profiler {
+
+class Bytecodes;
+class Compilation;
+
+class Event {
+public:
+ Event()
+ {
+ }
+
+ Event(double time, Bytecodes* bytecodes, Compilation* compilation, const char* summary, const CString& detail)
+ : m_time(time)
+ , m_bytecodes(bytecodes)
+ , m_compilation(compilation)
+ , m_summary(summary)
+ , m_detail(detail)
+ {
+ }
+
+ explicit operator bool() const
+ {
+ return m_bytecodes;
+ }
+
+ double time() const { return m_time; }
+ Bytecodes* bytecodes() const { return m_bytecodes; }
+ Compilation* compilation() const { return m_compilation; }
+ const char* summary() const { return m_summary; }
+ const CString& detail() const { return m_detail; }
+
+ void dump(PrintStream&) const;
+ JSValue toJS(ExecState*) const;
+
+private:
+ double m_time { 0 };
+ Bytecodes* m_bytecodes { nullptr };
+ Compilation* m_compilation { nullptr };
+ const char* m_summary { nullptr };
+ CString m_detail;
+};
+
+} } // namespace JSC::Profiler
diff --git a/Source/JavaScriptCore/profiler/ProfilerExecutionCounter.h b/Source/JavaScriptCore/profiler/ProfilerExecutionCounter.h
index 8989e38b5..e11747c3b 100644
--- a/Source/JavaScriptCore/profiler/ProfilerExecutionCounter.h
+++ b/Source/JavaScriptCore/profiler/ProfilerExecutionCounter.h
@@ -23,8 +23,7 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef ProfilerExecutionCounter_h
-#define ProfilerExecutionCounter_h
+#pragma once
#include <wtf/FastMalloc.h>
#include <wtf/Noncopyable.h>
@@ -45,6 +44,3 @@ private:
};
} } // namespace JSC::Profiler
-
-#endif // ProfilerExecutionCounter_h
-
diff --git a/Source/JavaScriptCore/profiler/ProfilerJettisonReason.cpp b/Source/JavaScriptCore/profiler/ProfilerJettisonReason.cpp
new file mode 100644
index 000000000..3751feda0
--- /dev/null
+++ b/Source/JavaScriptCore/profiler/ProfilerJettisonReason.cpp
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2014 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 "ProfilerJettisonReason.h"
+
+#include <wtf/PrintStream.h>
+
+namespace WTF {
+
+using namespace JSC::Profiler;
+
+void printInternal(PrintStream& out, JettisonReason reason)
+{
+ switch (reason) {
+ case NotJettisoned:
+ out.print("NotJettisoned");
+ return;
+ case JettisonDueToWeakReference:
+ out.print("WeakReference");
+ return;
+ case JettisonDueToDebuggerBreakpoint:
+ out.print("DebuggerBreakpoint");
+ return;
+ case JettisonDueToDebuggerStepping:
+ out.print("DebuggerStepping");
+ return;
+ case JettisonDueToBaselineLoopReoptimizationTrigger:
+ out.print("BaselineLoopReoptimizationTrigger");
+ return;
+ case JettisonDueToBaselineLoopReoptimizationTriggerOnOSREntryFail:
+ out.print("BaselineLoopReoptimizationTriggerOnOSREntryFail");
+ return;
+ case JettisonDueToOSRExit:
+ out.print("OSRExit");
+ return;
+ case JettisonDueToProfiledWatchpoint:
+ out.print("ProfiledWatchpoint");
+ return;
+ case JettisonDueToUnprofiledWatchpoint:
+ out.print("UnprofiledWatchpoint");
+ return;
+ case JettisonDueToOldAge:
+ out.print("JettisonDueToOldAge");
+ return;
+ }
+ RELEASE_ASSERT_NOT_REACHED();
+}
+
+} // namespace WTF
+
diff --git a/Source/JavaScriptCore/profiler/Profile.h b/Source/JavaScriptCore/profiler/ProfilerJettisonReason.h
index b1f093d69..745964fe1 100644
--- a/Source/JavaScriptCore/profiler/Profile.h
+++ b/Source/JavaScriptCore/profiler/ProfilerJettisonReason.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008 Apple Inc. All Rights Reserved.
+ * Copyright (C) 2014 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -20,49 +20,31 @@
* 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.
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-
-#ifndef Profile_h
-#define Profile_h
-#include "ProfileNode.h"
-#include <wtf/RefCounted.h>
-#include <wtf/RefPtr.h>
-#include <wtf/text/WTFString.h>
+#pragma once
-namespace JSC {
+namespace JSC { namespace Profiler {
- class Profile : public RefCounted<Profile> {
- public:
- static PassRefPtr<Profile> create(const String& title, unsigned uid);
- virtual ~Profile();
+enum JettisonReason {
+ NotJettisoned,
+ JettisonDueToWeakReference,
+ JettisonDueToDebuggerBreakpoint,
+ JettisonDueToDebuggerStepping,
+ JettisonDueToBaselineLoopReoptimizationTrigger,
+ JettisonDueToBaselineLoopReoptimizationTriggerOnOSREntryFail,
+ JettisonDueToOSRExit,
+ JettisonDueToProfiledWatchpoint,
+ JettisonDueToUnprofiledWatchpoint,
+ JettisonDueToOldAge
+};
- const String& title() const { return m_title; }
- ProfileNode* head() const { return m_head.get(); }
- void setHead(PassRefPtr<ProfileNode> head) { m_head = head; }
- double totalTime() const { return m_head->totalTime(); }
- unsigned int uid() const { return m_uid; }
+} } // namespace JSC::Profiler
- void forEach(void (ProfileNode::*)());
+namespace WTF {
-#ifndef NDEBUG
- void debugPrintData() const;
- void debugPrintDataSampleStyle() const;
-#endif
+class PrintStream;
+void printInternal(PrintStream&, JSC::Profiler::JettisonReason);
- protected:
- Profile(const String& title, unsigned uid);
-
- private:
- void removeProfileStart();
- void removeProfileEnd();
-
- String m_title;
- RefPtr<ProfileNode> m_head;
- unsigned int m_uid;
- };
-
-} // namespace JSC
-
-#endif // Profile_h
+} // namespace WTF
diff --git a/Source/JavaScriptCore/profiler/ProfilerOSRExit.cpp b/Source/JavaScriptCore/profiler/ProfilerOSRExit.cpp
index 0024791b4..2a5d5be40 100644
--- a/Source/JavaScriptCore/profiler/ProfilerOSRExit.cpp
+++ b/Source/JavaScriptCore/profiler/ProfilerOSRExit.cpp
@@ -28,7 +28,7 @@
#include "JSGlobalObject.h"
#include "ObjectConstructor.h"
-#include "Operations.h"
+#include "JSCInlines.h"
namespace JSC { namespace Profiler {
diff --git a/Source/JavaScriptCore/profiler/ProfilerOSRExit.h b/Source/JavaScriptCore/profiler/ProfilerOSRExit.h
index 2a23d0b2c..733df6370 100644
--- a/Source/JavaScriptCore/profiler/ProfilerOSRExit.h
+++ b/Source/JavaScriptCore/profiler/ProfilerOSRExit.h
@@ -23,8 +23,7 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef ProfilerOSRExit_h
-#define ProfilerOSRExit_h
+#pragma once
#include "ExitKind.h"
#include "JSCJSValue.h"
@@ -56,6 +55,3 @@ private:
};
} } // namespace JSC::Profiler
-
-#endif // ProfilerOSRExit_h
-
diff --git a/Source/JavaScriptCore/profiler/ProfilerOSRExitSite.cpp b/Source/JavaScriptCore/profiler/ProfilerOSRExitSite.cpp
index d54f7a275..8b5568f2c 100644
--- a/Source/JavaScriptCore/profiler/ProfilerOSRExitSite.cpp
+++ b/Source/JavaScriptCore/profiler/ProfilerOSRExitSite.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2012, 2016 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -29,16 +29,21 @@
#include "JSGlobalObject.h"
#include "JSScope.h"
#include "JSString.h"
-#include "Operations.h"
+#include "JSCInlines.h"
#include <wtf/StringPrintStream.h>
namespace JSC { namespace Profiler {
JSValue OSRExitSite::toJS(ExecState* exec) const
{
+ VM& vm = exec->vm();
+ auto scope = DECLARE_THROW_SCOPE(vm);
JSArray* result = constructEmptyArray(exec, 0);
- for (unsigned i = 0; i < m_codeAddresses.size(); ++i)
+ RETURN_IF_EXCEPTION(scope, { });
+ for (unsigned i = 0; i < m_codeAddresses.size(); ++i) {
result->putDirectIndex(exec, i, jsString(exec, toString(RawPointer(m_codeAddresses[i]))));
+ RETURN_IF_EXCEPTION(scope, { });
+ }
return result;
}
diff --git a/Source/JavaScriptCore/profiler/ProfilerOSRExitSite.h b/Source/JavaScriptCore/profiler/ProfilerOSRExitSite.h
index fa418e9b8..1776f1dd8 100644
--- a/Source/JavaScriptCore/profiler/ProfilerOSRExitSite.h
+++ b/Source/JavaScriptCore/profiler/ProfilerOSRExitSite.h
@@ -23,8 +23,7 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef ProfilerOSRExitSite_h
-#define ProfilerOSRExitSite_h
+#pragma once
#include "JSCJSValue.h"
#include <wtf/Vector.h>
@@ -47,6 +46,3 @@ private:
};
} } // namespace JSC::Profiler
-
-#endif // ProfilerOSRExitSite_h
-
diff --git a/Source/JavaScriptCore/profiler/ProfilerOrigin.cpp b/Source/JavaScriptCore/profiler/ProfilerOrigin.cpp
index 1ac29d1cc..7c28f7ba3 100644
--- a/Source/JavaScriptCore/profiler/ProfilerOrigin.cpp
+++ b/Source/JavaScriptCore/profiler/ProfilerOrigin.cpp
@@ -28,7 +28,7 @@
#include "JSGlobalObject.h"
#include "ObjectConstructor.h"
-#include "Operations.h"
+#include "JSCInlines.h"
#include "ProfilerBytecodes.h"
#include "ProfilerDatabase.h"
diff --git a/Source/JavaScriptCore/profiler/ProfilerOrigin.h b/Source/JavaScriptCore/profiler/ProfilerOrigin.h
index 09b388451..4844f03e0 100644
--- a/Source/JavaScriptCore/profiler/ProfilerOrigin.h
+++ b/Source/JavaScriptCore/profiler/ProfilerOrigin.h
@@ -23,8 +23,7 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef ProfilerOrigin_h
-#define ProfilerOrigin_h
+#pragma once
#include "CodeBlockHash.h"
#include "JSCJSValue.h"
@@ -115,6 +114,3 @@ 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
index 018ceeb8c..61dfb63c6 100644
--- a/Source/JavaScriptCore/profiler/ProfilerOriginStack.cpp
+++ b/Source/JavaScriptCore/profiler/ProfilerOriginStack.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2012, 2016 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,8 +27,9 @@
#include "ProfilerOriginStack.h"
#include "CodeOrigin.h"
+#include "InlineCallFrame.h"
#include "JSGlobalObject.h"
-#include "Operations.h"
+#include "JSCInlines.h"
#include "ProfilerDatabase.h"
namespace JSC { namespace Profiler {
@@ -51,7 +52,7 @@ OriginStack::OriginStack(Database& database, CodeBlock* codeBlock, const CodeOri
for (unsigned i = 1; i < stack.size(); ++i) {
append(Origin(
- database.ensureBytecodesFor(stack[i].inlineCallFrame->baselineCodeBlock()),
+ database.ensureBytecodesFor(stack[i].inlineCallFrame->baselineCodeBlock.get()),
stack[i].bytecodeIndex));
}
}
@@ -99,10 +100,15 @@ void OriginStack::dump(PrintStream& out) const
JSValue OriginStack::toJS(ExecState* exec) const
{
+ VM& vm = exec->vm();
+ auto scope = DECLARE_THROW_SCOPE(vm);
JSArray* result = constructEmptyArray(exec, 0);
+ RETURN_IF_EXCEPTION(scope, { });
- for (unsigned i = 0; i < m_stack.size(); ++i)
+ for (unsigned i = 0; i < m_stack.size(); ++i) {
result->putDirectIndex(exec, i, m_stack[i].toJS(exec));
+ RETURN_IF_EXCEPTION(scope, { });
+ }
return result;
}
diff --git a/Source/JavaScriptCore/profiler/ProfilerOriginStack.h b/Source/JavaScriptCore/profiler/ProfilerOriginStack.h
index 415e8d9b0..36bc13a57 100644
--- a/Source/JavaScriptCore/profiler/ProfilerOriginStack.h
+++ b/Source/JavaScriptCore/profiler/ProfilerOriginStack.h
@@ -23,8 +23,7 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef ProfilerOriginStack_h
-#define ProfilerOriginStack_h
+#pragma once
#include "JSCJSValue.h"
#include "ProfilerOrigin.h"
@@ -97,6 +96,3 @@ 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
index 6ca6c9f15..fe590ff78 100644
--- a/Source/JavaScriptCore/profiler/ProfilerProfiledBytecodes.cpp
+++ b/Source/JavaScriptCore/profiler/ProfilerProfiledBytecodes.cpp
@@ -28,7 +28,7 @@
#include "JSGlobalObject.h"
#include "ObjectConstructor.h"
-#include "Operations.h"
+#include "JSCInlines.h"
namespace JSC { namespace Profiler {
diff --git a/Source/JavaScriptCore/profiler/ProfilerProfiledBytecodes.h b/Source/JavaScriptCore/profiler/ProfilerProfiledBytecodes.h
index d7cb6ffa8..2ef9f449f 100644
--- a/Source/JavaScriptCore/profiler/ProfilerProfiledBytecodes.h
+++ b/Source/JavaScriptCore/profiler/ProfilerProfiledBytecodes.h
@@ -23,8 +23,7 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef ProfilerProfiledBytecodes_h
-#define ProfilerProfiledBytecodes_h
+#pragma once
#include "ProfilerBytecodeSequence.h"
#include "ProfilerBytecodes.h"
@@ -46,6 +45,3 @@ private:
};
} } // namespace JSC::Profiler
-
-#endif // ProfilerProfiledBytecodes_h
-
diff --git a/Source/JavaScriptCore/profiler/ProfilerUID.cpp b/Source/JavaScriptCore/profiler/ProfilerUID.cpp
new file mode 100644
index 000000000..228988bc5
--- /dev/null
+++ b/Source/JavaScriptCore/profiler/ProfilerUID.cpp
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2016 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 "ProfilerUID.h"
+
+#include "JSCInlines.h"
+#include <wtf/Lock.h>
+
+namespace JSC { namespace Profiler {
+
+UID UID::create()
+{
+ static StaticLock lock;
+ static uint64_t counter;
+
+ LockHolder locker(lock);
+ UID result;
+ result.m_uid = ++counter;
+ return result;
+}
+
+void UID::dump(PrintStream& out) const
+{
+ out.print(m_uid);
+}
+
+JSValue UID::toJS(ExecState* exec) const
+{
+ return jsString(exec, toString(*this));
+}
+
+} } // namespace JSC::Profiler
+
diff --git a/Source/JavaScriptCore/profiler/ProfilerUID.h b/Source/JavaScriptCore/profiler/ProfilerUID.h
new file mode 100644
index 000000000..97dc3206a
--- /dev/null
+++ b/Source/JavaScriptCore/profiler/ProfilerUID.h
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+
+#pragma once
+
+#include "JSCJSValue.h"
+#include <wtf/HashMap.h>
+#include <wtf/PrintStream.h>
+
+namespace JSC { namespace Profiler {
+
+class UID {
+public:
+ UID()
+ : m_uid(0)
+ {
+ }
+
+ static UID fromInt(uint64_t value)
+ {
+ UID result;
+ result.m_uid = value;
+ return result;
+ }
+
+ UID(WTF::HashTableDeletedValueType)
+ : m_uid(std::numeric_limits<uint64_t>::max())
+ {
+ }
+
+ static UID create();
+
+ uint64_t toInt() const
+ {
+ return m_uid;
+ }
+
+ bool operator==(const UID& other) const
+ {
+ return m_uid == other.m_uid;
+ }
+
+ bool operator!=(const UID& other) const
+ {
+ return !(*this == other);
+ }
+
+ explicit operator bool() const
+ {
+ return *this != UID();
+ }
+
+ bool isHashTableDeletedValue() const
+ {
+ return *this != UID(WTF::HashTableDeletedValue);
+ }
+
+ unsigned hash() const
+ {
+ return IntHash<uint64_t>::hash(m_uid);
+ }
+
+ void dump(PrintStream&) const;
+ JSValue toJS(ExecState*) const;
+
+private:
+ uint64_t m_uid;
+};
+
+struct UIDHash {
+ static unsigned hash(const UID& key) { return key.hash(); }
+ static bool equal(const UID& a, const UID& b) { return a == b; }
+ static const bool safeToCompareToEmptyOrDeleted = true;
+};
+
+} } // namespace JSC::Profiler
+
+namespace WTF {
+
+template<typename T> struct DefaultHash;
+template<> struct DefaultHash<JSC::Profiler::UID> {
+ typedef JSC::Profiler::UIDHash Hash;
+};
+
+template<typename T> struct HashTraits;
+template<> struct HashTraits<JSC::Profiler::UID> : SimpleClassHashTraits<JSC::Profiler::UID> { };
+
+} // namespace WTF