X-Git-Url: https://git.saurik.com/apple/javascriptcore.git/blobdiff_plain/93a3786624b2768d89bfa27e46598dc64e2fb70a..refs/heads/master:/profiler/LegacyProfiler.cpp diff --git a/profiler/LegacyProfiler.cpp b/profiler/LegacyProfiler.cpp index 1db2e62..787d362 100644 --- a/profiler/LegacyProfiler.cpp +++ b/profiler/LegacyProfiler.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008, 2012 Apple Inc. All rights reserved. + * Copyright (C) 2008, 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 @@ -10,7 +10,7 @@ * 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 + * 3. Neither the name of Apple 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. * @@ -36,11 +36,10 @@ #include "JSFunction.h" #include "JSGlobalObject.h" #include "Nodes.h" -#include "Operations.h" +#include "JSCInlines.h" #include "Profile.h" #include "ProfileGenerator.h" #include "ProfileNode.h" -#include namespace JSC { @@ -48,21 +47,19 @@ 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); +static CallIdentifier createCallIdentifierFromFunctionImp(ExecState*, JSObject*, const String& defaultSourceURL, unsigned defaultLineNumber, unsigned defaultColumnNumber); -LegacyProfiler* LegacyProfiler::s_sharedLegacyProfiler = 0; +LegacyProfiler* LegacyProfiler::s_sharedLegacyProfiler = nullptr; LegacyProfiler* LegacyProfiler::profiler() { if (!s_sharedLegacyProfiler) s_sharedLegacyProfiler = new LegacyProfiler(); return s_sharedLegacyProfiler; -} +} -void LegacyProfiler::startProfiling(ExecState* exec, const String& title) +void LegacyProfiler::startProfiling(ExecState* exec, const String& title, PassRefPtr stopwatch) { - ASSERT_ARG(title, !title.isNull()); - if (!exec) return; @@ -76,15 +73,15 @@ void LegacyProfiler::startProfiling(ExecState* exec, const String& title) return; } - exec->vm().m_enabledProfiler = this; - RefPtr profileGenerator = ProfileGenerator::create(exec, title, ++ProfilesUID); + exec->vm().setEnabledProfiler(this); + RefPtr profileGenerator = ProfileGenerator::create(exec, title, ++ProfilesUID, stopwatch); m_currentProfiles.append(profileGenerator); } -PassRefPtr LegacyProfiler::stopProfiling(ExecState* exec, const String& title) +RefPtr LegacyProfiler::stopProfiling(ExecState* exec, const String& title) { if (!exec) - return 0; + return nullptr; JSGlobalObject* origin = exec->lexicalGlobalObject(); for (ptrdiff_t i = m_currentProfiles.size() - 1; i >= 0; --i) { @@ -95,13 +92,13 @@ PassRefPtr LegacyProfiler::stopProfiling(ExecState* exec, const String& m_currentProfiles.remove(i); if (!m_currentProfiles.size()) - exec->vm().m_enabledProfiler = 0; - + exec->vm().setEnabledProfiler(nullptr); + return returnProfile; } } - return 0; + return nullptr; } void LegacyProfiler::stopProfiling(JSGlobalObject* origin) @@ -112,74 +109,100 @@ void LegacyProfiler::stopProfiling(JSGlobalObject* origin) profileGenerator->stopProfiling(); m_currentProfiles.remove(i); if (!m_currentProfiles.size()) - origin->vm().m_enabledProfiler = 0; + origin->vm().setEnabledProfiler(nullptr); } } } -static inline void dispatchFunctionToProfiles(ExecState* callerOrHandlerCallFrame, const Vector >& profiles, ProfileGenerator::ProfileFunction function, const CallIdentifier& callIdentifier, unsigned currentProfileTargetGroup) +static inline void callFunctionForProfilesWithGroup(std::function callback, const Vector>& profiles, unsigned targetProfileGroup) { - for (size_t i = 0; i < profiles.size(); ++i) { - if (profiles[i]->profileGroup() == currentProfileTargetGroup || !profiles[i]->origin()) - (profiles[i].get()->*function)(callerOrHandlerCallFrame, callIdentifier); + for (const RefPtr& profile : profiles) { + if (profile->profileGroup() == targetProfileGroup || !profile->origin()) + callback(profile.get()); } } +void LegacyProfiler::suspendProfiling(JSC::ExecState* exec) +{ + if (!exec) + return; + + callFunctionForProfilesWithGroup(std::bind(&ProfileGenerator::setIsSuspended, std::placeholders::_1, true), m_currentProfiles, exec->lexicalGlobalObject()->profileGroup()); +} + +void LegacyProfiler::unsuspendProfiling(JSC::ExecState* exec) +{ + if (!exec) + return; + + callFunctionForProfilesWithGroup(std::bind(&ProfileGenerator::setIsSuspended, std::placeholders::_1, false), m_currentProfiles, exec->lexicalGlobalObject()->profileGroup()); +} + void LegacyProfiler::willExecute(ExecState* callerCallFrame, JSValue function) { ASSERT(!m_currentProfiles.isEmpty()); - dispatchFunctionToProfiles(callerCallFrame, m_currentProfiles, &ProfileGenerator::willExecute, createCallIdentifier(callerCallFrame, function, "", 0), callerCallFrame->lexicalGlobalObject()->profileGroup()); + CallIdentifier callIdentifier = createCallIdentifier(callerCallFrame, function, StringImpl::empty(), 0, 0); + + callFunctionForProfilesWithGroup(std::bind(&ProfileGenerator::willExecute, std::placeholders::_1, callerCallFrame, callIdentifier), m_currentProfiles, callerCallFrame->lexicalGlobalObject()->profileGroup()); } -void LegacyProfiler::willExecute(ExecState* callerCallFrame, const String& sourceURL, int startingLineNumber) +void LegacyProfiler::willExecute(ExecState* callerCallFrame, const String& sourceURL, unsigned startingLineNumber, unsigned startingColumnNumber) { ASSERT(!m_currentProfiles.isEmpty()); - CallIdentifier callIdentifier = createCallIdentifier(callerCallFrame, JSValue(), sourceURL, startingLineNumber); + CallIdentifier callIdentifier = createCallIdentifier(callerCallFrame, JSValue(), sourceURL, startingLineNumber, startingColumnNumber); - dispatchFunctionToProfiles(callerCallFrame, m_currentProfiles, &ProfileGenerator::willExecute, callIdentifier, callerCallFrame->lexicalGlobalObject()->profileGroup()); + callFunctionForProfilesWithGroup(std::bind(&ProfileGenerator::willExecute, std::placeholders::_1, callerCallFrame, callIdentifier), m_currentProfiles, 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()); + CallIdentifier callIdentifier = createCallIdentifier(callerCallFrame, function, StringImpl::empty(), 0, 0); + + callFunctionForProfilesWithGroup(std::bind(&ProfileGenerator::didExecute, std::placeholders::_1, callerCallFrame, callIdentifier), m_currentProfiles, callerCallFrame->lexicalGlobalObject()->profileGroup()); } -void LegacyProfiler::didExecute(ExecState* callerCallFrame, const String& sourceURL, int startingLineNumber) +void LegacyProfiler::didExecute(ExecState* callerCallFrame, const String& sourceURL, unsigned startingLineNumber, unsigned startingColumnNumber) { ASSERT(!m_currentProfiles.isEmpty()); - dispatchFunctionToProfiles(callerCallFrame, m_currentProfiles, &ProfileGenerator::didExecute, createCallIdentifier(callerCallFrame, JSValue(), sourceURL, startingLineNumber), callerCallFrame->lexicalGlobalObject()->profileGroup()); + CallIdentifier callIdentifier = createCallIdentifier(callerCallFrame, JSValue(), sourceURL, startingLineNumber, startingColumnNumber); + + callFunctionForProfilesWithGroup(std::bind(&ProfileGenerator::didExecute, std::placeholders::_1, callerCallFrame, callIdentifier), m_currentProfiles, 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 callIdentifier = createCallIdentifier(handlerCallFrame, JSValue(), StringImpl::empty(), 0, 0); + + callFunctionForProfilesWithGroup(std::bind(&ProfileGenerator::exceptionUnwind, std::placeholders::_1, handlerCallFrame, callIdentifier), m_currentProfiles, handlerCallFrame->lexicalGlobalObject()->profileGroup()); } -CallIdentifier LegacyProfiler::createCallIdentifier(ExecState* exec, JSValue functionValue, const String& defaultSourceURL, int defaultLineNumber) +CallIdentifier LegacyProfiler::createCallIdentifier(ExecState* exec, JSValue functionValue, const String& defaultSourceURL, unsigned defaultLineNumber, unsigned defaultColumnNumber) { if (!functionValue) - return CallIdentifier(GlobalCodeExecution, defaultSourceURL, defaultLineNumber); + return CallIdentifier(ASCIILiteral(GlobalCodeExecution), defaultSourceURL, defaultLineNumber, defaultColumnNumber); if (!functionValue.isObject()) - return CallIdentifier("(unknown)", defaultSourceURL, defaultLineNumber); - if (asObject(functionValue)->inherits(&JSFunction::s_info) || asObject(functionValue)->inherits(&InternalFunction::s_info)) - return createCallIdentifierFromFunctionImp(exec, asObject(functionValue), defaultSourceURL, defaultLineNumber); - return CallIdentifier(makeString("(", asObject(functionValue)->methodTable()->className(asObject(functionValue)), " object)"), defaultSourceURL, defaultLineNumber); + return CallIdentifier(ASCIILiteral("(unknown)"), defaultSourceURL, defaultLineNumber, defaultColumnNumber); + if (asObject(functionValue)->inherits(JSFunction::info()) || asObject(functionValue)->inherits(InternalFunction::info())) + return createCallIdentifierFromFunctionImp(exec, asObject(functionValue), defaultSourceURL, defaultLineNumber, defaultColumnNumber); + if (asObject(functionValue)->inherits(JSCallee::info())) + return CallIdentifier(ASCIILiteral(GlobalCodeExecution), defaultSourceURL, defaultLineNumber, defaultColumnNumber); + return CallIdentifier(asObject(functionValue)->methodTable()->className(asObject(functionValue)), defaultSourceURL, defaultLineNumber, defaultColumnNumber); } -CallIdentifier createCallIdentifierFromFunctionImp(ExecState* exec, JSObject* function, const String& defaultSourceURL, int defaultLineNumber) +CallIdentifier createCallIdentifierFromFunctionImp(ExecState* exec, JSObject* function, const String& defaultSourceURL, unsigned defaultLineNumber, unsigned defaultColumnNumber) { const String& name = getCalculatedDisplayName(exec, function); JSFunction* jsFunction = jsDynamicCast(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); + if (jsFunction && !jsFunction->isHostOrBuiltinFunction()) + return CallIdentifier(name.isEmpty() ? ASCIILiteral(AnonymousFunction) : name, jsFunction->jsExecutable()->sourceURL(), jsFunction->jsExecutable()->firstLine(), jsFunction->jsExecutable()->startColumn()); + return CallIdentifier(name.isEmpty() ? ASCIILiteral(AnonymousFunction) : name, defaultSourceURL, defaultLineNumber, defaultColumnNumber); } } // namespace JSC