1/* 2 * Copyright (C) 2012, 2013 Apple Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 26#ifndef ProfilerDatabase_h 27#define ProfilerDatabase_h 28 29#include "JSCJSValue.h" 30#include "ProfilerBytecodes.h" 31#include "ProfilerCompilation.h" 32#include "ProfilerCompilationKind.h" 33#include <wtf/FastMalloc.h> 34#include <wtf/HashMap.h> 35#include <wtf/Noncopyable.h> 36#include <wtf/PassRefPtr.h> 37#include <wtf/SegmentedVector.h> 38#include <wtf/ThreadingPrimitives.h> 39#include <wtf/text/WTFString.h> 40 41namespace JSC { namespace Profiler { 42 43class Database { 44 WTF_MAKE_FAST_ALLOCATED; WTF_MAKE_NONCOPYABLE(Database); 45public: 46 JS_EXPORT_PRIVATE Database(VM&); 47 JS_EXPORT_PRIVATE ~Database(); 48 49 int databaseID() const { return m_databaseID; } 50 51 Bytecodes* ensureBytecodesFor(CodeBlock*); 52 void notifyDestruction(CodeBlock*); 53 54 void addCompilation(PassRefPtr<Compilation>); 55 56 // Converts the database to a JavaScript object that is suitable for JSON stringification. 57 // Note that it's probably a good idea to use an ExecState* associated with a global 58 // object that is "clean" - i.e. array and object prototypes haven't had strange things 59 // done to them. And yes, it should be appropriate to just use a globalExec here. 60 JS_EXPORT_PRIVATE JSValue toJS(ExecState*) const; 61 62 // Converts the database to a JavaScript object using a private temporary global object, 63 // and then returns the JSON representation of that object. 64 JS_EXPORT_PRIVATE String toJSON() const; 65 66 // Saves the JSON representation (from toJSON()) to the given file. Returns false if the 67 // save failed. 68 JS_EXPORT_PRIVATE bool save(const char* filename) const; 69 70 void registerToSaveAtExit(const char* filename); 71 72private: 73 // Use a full-blown adaptive mutex because: 74 // - There is only one ProfilerDatabase per VM. The size overhead of the system's 75 // mutex is negligible if you only have one of them. 76 // - It's locked infrequently - once per bytecode generation, compilation, and 77 // code block collection - so the fact that the fast path still requires a 78 // function call is neglible. 79 // - It tends to be held for a while. Currently, we hold it while generating 80 // Profiler::Bytecodes for a CodeBlock. That's uncommon and shouldn't affect 81 // performance, but if we did have contention, we would want a sensible, 82 // power-aware backoff. An adaptive mutex will do this as a matter of course, 83 // but a spinlock won't. 84 typedef Mutex Lock; 85 typedef MutexLocker Locker; 86 87 88 void addDatabaseToAtExit(); 89 void removeDatabaseFromAtExit(); 90 void performAtExitSave() const; 91 static Database* removeFirstAtExitDatabase(); 92 static void atExitCallback(); 93 94 int m_databaseID; 95 VM& m_vm; 96 SegmentedVector<Bytecodes> m_bytecodes; 97 HashMap<CodeBlock*, Bytecodes*> m_bytecodesMap; 98 Vector<RefPtr<Compilation>> m_compilations; 99 bool m_shouldSaveAtExit; 100 CString m_atExitSaveFilename; 101 Database* m_nextRegisteredDatabase; 102 Lock m_lock; 103}; 104 105} } // namespace JSC::Profiler 106 107#endif // ProfilerDatabase_h 108 109