JSC should scale the optimization threshold for a code block according to the cost...
[WebKit-https.git] / Source / JavaScriptCore / profiler / ProfilerDatabase.cpp
1 /*
2  * Copyright (C) 2012 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 #include "config.h"
27 #include "ProfilerDatabase.h"
28
29 #include "CodeBlock.h"
30 #include "JSONObject.h"
31 #include <wtf/StringPrintStream.h>
32
33 namespace JSC { namespace Profiler {
34
35 Database::Database(JSGlobalData& globalData)
36     : m_globalData(globalData)
37 {
38 }
39
40 Database::~Database()
41 {
42 }
43
44 Bytecodes* Database::addBytecodes(CodeBlockHash hash, const String& sourceCode)
45 {
46     m_bytecodes.append(Bytecodes(m_bytecodes.size(), sourceCode, hash));
47     return &m_bytecodes.last();
48 }
49
50 Bytecodes* Database::ensureBytecodesFor(CodeBlock* codeBlock)
51 {
52     StringPrintStream out;
53     
54     codeBlock = codeBlock->baselineVersion();
55     
56     HashMap<CodeBlock*, Bytecodes*>::iterator iter = m_bytecodesMap.find(codeBlock);
57     if (iter != m_bytecodesMap.end())
58         return iter->value;
59     
60     Bytecodes* result = addBytecodes(codeBlock->hash(), codeBlock->sourceCodeForTools());
61     
62     for (unsigned bytecodeIndex = 0; bytecodeIndex < codeBlock->instructions().size();) {
63         out.reset();
64         codeBlock->dumpBytecode(out, bytecodeIndex);
65         result->append(Bytecode(bytecodeIndex, m_globalData.interpreter->getOpcodeID(codeBlock->instructions()[bytecodeIndex].u.opcode), out.toCString()));
66         
67         bytecodeIndex += opcodeLength(
68             m_globalData.interpreter->getOpcodeID(
69                 codeBlock->instructions()[bytecodeIndex].u.opcode));
70     }
71     
72     m_bytecodesMap.add(codeBlock, result);
73     
74     return result;
75 }
76
77 void Database::notifyDestruction(CodeBlock* codeBlock)
78 {
79     m_bytecodesMap.remove(codeBlock);
80 }
81
82 Compilation* Database::newCompilation(Bytecodes* bytecodes, CompilationKind kind)
83 {
84     OwnPtr<Compilation> compilation = adoptPtr(new Compilation(bytecodes, kind));
85     Compilation* result = compilation.get();
86     m_compilations.append(compilation.release());
87     return result;
88 }
89
90 Compilation* Database::newCompilation(CodeBlock* codeBlock, CompilationKind kind)
91 {
92     return newCompilation(ensureBytecodesFor(codeBlock), kind);
93 }
94
95 JSValue Database::toJS(ExecState* exec) const
96 {
97     JSObject* result = constructEmptyObject(exec);
98     
99     JSArray* bytecodes = constructEmptyArray(exec, 0);
100     for (unsigned i = 0; i < m_bytecodes.size(); ++i)
101         bytecodes->putDirectIndex(exec, i, m_bytecodes[i].toJS(exec));
102     result->putDirect(exec->globalData(), exec->propertyNames().bytecodes, bytecodes);
103     
104     JSArray* compilations = constructEmptyArray(exec, 0);
105     for (unsigned i = 0; i < m_compilations.size(); ++i)
106         compilations->putDirectIndex(exec, i, m_compilations[i]->toJS(exec));
107     result->putDirect(exec->globalData(), exec->propertyNames().compilations, compilations);
108     
109     return result;
110 }
111
112 String Database::toJSON() const
113 {
114     JSGlobalObject* globalObject = JSGlobalObject::create(
115         m_globalData, JSGlobalObject::createStructure(m_globalData, jsNull()));
116     
117     return JSONStringify(globalObject->globalExec(), toJS(globalObject->globalExec()), 0);
118 }
119
120 bool Database::save(const char* filename) const
121 {
122     OwnPtr<FilePrintStream> out = FilePrintStream::open(filename, "w");
123     if (!out)
124         return false;
125     
126     out->print(toJSON());
127     return true;
128 }
129
130 } } // namespace JSC::Profiler
131