diff options
author | Lorry Tar Creator <lorry-tar-importer@lorry> | 2017-06-27 06:07:23 +0000 |
---|---|---|
committer | Lorry Tar Creator <lorry-tar-importer@lorry> | 2017-06-27 06:07:23 +0000 |
commit | 1bf1084f2b10c3b47fd1a588d85d21ed0eb41d0c (patch) | |
tree | 46dcd36c86e7fbc6e5df36deb463b33e9967a6f7 /Source/JavaScriptCore/profiler/ProfilerDatabase.cpp | |
parent | 32761a6cee1d0dee366b885b7b9c777e67885688 (diff) | |
download | WebKitGtk-tarball-master.tar.gz |
webkitgtk-2.16.5HEADwebkitgtk-2.16.5master
Diffstat (limited to 'Source/JavaScriptCore/profiler/ProfilerDatabase.cpp')
-rw-r--r-- | Source/JavaScriptCore/profiler/ProfilerDatabase.cpp | 94 |
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(®istrationLock); + LockHolder holder(registrationLock); m_nextRegisteredDatabase = firstDatabase; firstDatabase = this; } void Database::removeDatabaseFromAtExit() { - TCMalloc_SpinLockHolder holder(®istrationLock); + 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(®istrationLock); + LockHolder holder(registrationLock); Database* result = firstDatabase; if (result) { firstDatabase = result->m_nextRegisteredDatabase; |