Change a couple of HashMap value types from OwnPtr to std::unique_ptr
[WebKit-https.git] / Source / JavaScriptCore / profiler / ProfilerCompilation.cpp
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 #include "config.h"
27 #include "ProfilerCompilation.h"
28
29 #include "JSGlobalObject.h"
30 #include "ObjectConstructor.h"
31 #include "Operations.h"
32 #include "ProfilerDatabase.h"
33 #include <wtf/StringPrintStream.h>
34
35 namespace JSC { namespace Profiler {
36
37 Compilation::Compilation(Bytecodes* bytecodes, CompilationKind kind)
38     : m_bytecodes(bytecodes)
39     , m_kind(kind)
40     , m_numInlinedGetByIds(0)
41     , m_numInlinedPutByIds(0)
42     , m_numInlinedCalls(0)
43 {
44 }
45
46 Compilation::~Compilation() { }
47
48 void Compilation::addProfiledBytecodes(Database& database, CodeBlock* profiledBlock)
49 {
50     Bytecodes* bytecodes = database.ensureBytecodesFor(profiledBlock);
51     
52     // First make sure that we haven't already added profiled bytecodes for this code
53     // block. We do this using an O(N) search because I suspect that this list will
54     // tend to be fairly small, and the additional space costs of having a HashMap/Set
55     // would be greater than the time cost of occasionally doing this search.
56     
57     for (unsigned i = m_profiledBytecodes.size(); i--;) {
58         if (m_profiledBytecodes[i].bytecodes() == bytecodes)
59             return;
60     }
61     
62     m_profiledBytecodes.append(ProfiledBytecodes(bytecodes, profiledBlock));
63 }
64
65 void Compilation::addDescription(const CompiledBytecode& compiledBytecode)
66 {
67     m_descriptions.append(compiledBytecode);
68 }
69
70 ExecutionCounter* Compilation::executionCounterFor(const OriginStack& origin)
71 {
72     std::unique_ptr<ExecutionCounter>& counter = m_counters.add(origin, nullptr).iterator->value;
73     if (!counter)
74         counter = std::make_unique<ExecutionCounter>();
75
76     return counter.get();
77 }
78
79 void Compilation::addOSRExitSite(const Vector<const void*>& codeAddresses)
80 {
81     m_osrExitSites.append(OSRExitSite(codeAddresses));
82 }
83
84 OSRExit* Compilation::addOSRExit(unsigned id, const OriginStack& originStack, ExitKind exitKind, bool isWatchpoint)
85 {
86     m_osrExits.append(OSRExit(id, originStack, exitKind, isWatchpoint));
87     return &m_osrExits.last();
88 }
89
90 JSValue Compilation::toJS(ExecState* exec) const
91 {
92     JSObject* result = constructEmptyObject(exec);
93     
94     result->putDirect(exec->vm(), exec->propertyNames().bytecodesID, jsNumber(m_bytecodes->id()));
95     result->putDirect(exec->vm(), exec->propertyNames().compilationKind, jsString(exec, String::fromUTF8(toCString(m_kind))));
96     
97     JSArray* profiledBytecodes = constructEmptyArray(exec, 0);
98     for (unsigned i = 0; i < m_profiledBytecodes.size(); ++i)
99         profiledBytecodes->putDirectIndex(exec, i, m_profiledBytecodes[i].toJS(exec));
100     result->putDirect(exec->vm(), exec->propertyNames().profiledBytecodes, profiledBytecodes);
101     
102     JSArray* descriptions = constructEmptyArray(exec, 0);
103     for (unsigned i = 0; i < m_descriptions.size(); ++i)
104         descriptions->putDirectIndex(exec, i, m_descriptions[i].toJS(exec));
105     result->putDirect(exec->vm(), exec->propertyNames().descriptions, descriptions);
106     
107     JSArray* counters = constructEmptyArray(exec, 0);
108     for (auto it = m_counters.begin(), end = m_counters.end(); it != end; ++it) {
109         JSObject* counterEntry = constructEmptyObject(exec);
110         counterEntry->putDirect(exec->vm(), exec->propertyNames().origin, it->key.toJS(exec));
111         counterEntry->putDirect(exec->vm(), exec->propertyNames().executionCount, jsNumber(it->value->count()));
112         counters->push(exec, counterEntry);
113     }
114     result->putDirect(exec->vm(), exec->propertyNames().counters, counters);
115     
116     JSArray* exitSites = constructEmptyArray(exec, 0);
117     for (unsigned i = 0; i < m_osrExitSites.size(); ++i)
118         exitSites->putDirectIndex(exec, i, m_osrExitSites[i].toJS(exec));
119     result->putDirect(exec->vm(), exec->propertyNames().osrExitSites, exitSites);
120     
121     JSArray* exits = constructEmptyArray(exec, 0);
122     for (unsigned i = 0; i < m_osrExits.size(); ++i)
123         exits->putDirectIndex(exec, i, m_osrExits[i].toJS(exec));
124     result->putDirect(exec->vm(), exec->propertyNames().osrExits, exits);
125     
126     result->putDirect(exec->vm(), exec->propertyNames().numInlinedGetByIds, jsNumber(m_numInlinedGetByIds));
127     result->putDirect(exec->vm(), exec->propertyNames().numInlinedPutByIds, jsNumber(m_numInlinedPutByIds));
128     result->putDirect(exec->vm(), exec->propertyNames().numInlinedCalls, jsNumber(m_numInlinedCalls));
129     
130     return result;
131 }
132
133 } } // namespace JSC::Profiler
134