summaryrefslogtreecommitdiff
path: root/Source/JavaScriptCore/profiler/ProfilerDatabase.cpp
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/ProfilerDatabase.cpp
parent32761a6cee1d0dee366b885b7b9c777e67885688 (diff)
downloadWebKitGtk-tarball-master.tar.gz
Diffstat (limited to 'Source/JavaScriptCore/profiler/ProfilerDatabase.cpp')
-rw-r--r--Source/JavaScriptCore/profiler/ProfilerDatabase.cpp94
1 files changed, 72 insertions, 22 deletions
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;