]>
git.saurik.com Git - apple/javascriptcore.git/blob - profiler/ProfilerCompilation.cpp
2 * Copyright (C) 2012, 2013, 2014 Apple Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
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.
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.
27 #include "ProfilerCompilation.h"
29 #include "JSGlobalObject.h"
30 #include "ObjectConstructor.h"
31 #include "JSCInlines.h"
32 #include "ProfilerDatabase.h"
33 #include <wtf/StringPrintStream.h>
35 namespace JSC
{ namespace Profiler
{
37 Compilation::Compilation(Bytecodes
* bytecodes
, CompilationKind kind
)
38 : m_bytecodes(bytecodes
)
40 , m_jettisonReason(NotJettisoned
)
41 , m_numInlinedGetByIds(0)
42 , m_numInlinedPutByIds(0)
43 , m_numInlinedCalls(0)
47 Compilation::~Compilation() { }
49 void Compilation::addProfiledBytecodes(Database
& database
, CodeBlock
* profiledBlock
)
51 Bytecodes
* bytecodes
= database
.ensureBytecodesFor(profiledBlock
);
53 // First make sure that we haven't already added profiled bytecodes for this code
54 // block. We do this using an O(N) search because I suspect that this list will
55 // tend to be fairly small, and the additional space costs of having a HashMap/Set
56 // would be greater than the time cost of occasionally doing this search.
58 for (unsigned i
= m_profiledBytecodes
.size(); i
--;) {
59 if (m_profiledBytecodes
[i
].bytecodes() == bytecodes
)
63 m_profiledBytecodes
.append(ProfiledBytecodes(bytecodes
, profiledBlock
));
66 void Compilation::addDescription(const CompiledBytecode
& compiledBytecode
)
68 m_descriptions
.append(compiledBytecode
);
71 void Compilation::addDescription(const OriginStack
& stack
, const CString
& description
)
73 addDescription(CompiledBytecode(stack
, description
));
76 ExecutionCounter
* Compilation::executionCounterFor(const OriginStack
& origin
)
78 std::unique_ptr
<ExecutionCounter
>& counter
= m_counters
.add(origin
, nullptr).iterator
->value
;
80 counter
= std::make_unique
<ExecutionCounter
>();
85 void Compilation::addOSRExitSite(const Vector
<const void*>& codeAddresses
)
87 m_osrExitSites
.append(OSRExitSite(codeAddresses
));
90 OSRExit
* Compilation::addOSRExit(unsigned id
, const OriginStack
& originStack
, ExitKind exitKind
, bool isWatchpoint
)
92 m_osrExits
.append(OSRExit(id
, originStack
, exitKind
, isWatchpoint
));
93 return &m_osrExits
.last();
96 JSValue
Compilation::toJS(ExecState
* exec
) const
98 JSObject
* result
= constructEmptyObject(exec
);
100 result
->putDirect(exec
->vm(), exec
->propertyNames().bytecodesID
, jsNumber(m_bytecodes
->id()));
101 result
->putDirect(exec
->vm(), exec
->propertyNames().compilationKind
, jsString(exec
, String::fromUTF8(toCString(m_kind
))));
103 JSArray
* profiledBytecodes
= constructEmptyArray(exec
, 0);
104 for (unsigned i
= 0; i
< m_profiledBytecodes
.size(); ++i
)
105 profiledBytecodes
->putDirectIndex(exec
, i
, m_profiledBytecodes
[i
].toJS(exec
));
106 result
->putDirect(exec
->vm(), exec
->propertyNames().profiledBytecodes
, profiledBytecodes
);
108 JSArray
* descriptions
= constructEmptyArray(exec
, 0);
109 for (unsigned i
= 0; i
< m_descriptions
.size(); ++i
)
110 descriptions
->putDirectIndex(exec
, i
, m_descriptions
[i
].toJS(exec
));
111 result
->putDirect(exec
->vm(), exec
->propertyNames().descriptions
, descriptions
);
113 JSArray
* counters
= constructEmptyArray(exec
, 0);
114 for (auto it
= m_counters
.begin(), end
= m_counters
.end(); it
!= end
; ++it
) {
115 JSObject
* counterEntry
= constructEmptyObject(exec
);
116 counterEntry
->putDirect(exec
->vm(), exec
->propertyNames().origin
, it
->key
.toJS(exec
));
117 counterEntry
->putDirect(exec
->vm(), exec
->propertyNames().executionCount
, jsNumber(it
->value
->count()));
118 counters
->push(exec
, counterEntry
);
120 result
->putDirect(exec
->vm(), exec
->propertyNames().counters
, counters
);
122 JSArray
* exitSites
= constructEmptyArray(exec
, 0);
123 for (unsigned i
= 0; i
< m_osrExitSites
.size(); ++i
)
124 exitSites
->putDirectIndex(exec
, i
, m_osrExitSites
[i
].toJS(exec
));
125 result
->putDirect(exec
->vm(), exec
->propertyNames().osrExitSites
, exitSites
);
127 JSArray
* exits
= constructEmptyArray(exec
, 0);
128 for (unsigned i
= 0; i
< m_osrExits
.size(); ++i
)
129 exits
->putDirectIndex(exec
, i
, m_osrExits
[i
].toJS(exec
));
130 result
->putDirect(exec
->vm(), exec
->propertyNames().osrExits
, exits
);
132 result
->putDirect(exec
->vm(), exec
->propertyNames().numInlinedGetByIds
, jsNumber(m_numInlinedGetByIds
));
133 result
->putDirect(exec
->vm(), exec
->propertyNames().numInlinedPutByIds
, jsNumber(m_numInlinedPutByIds
));
134 result
->putDirect(exec
->vm(), exec
->propertyNames().numInlinedCalls
, jsNumber(m_numInlinedCalls
));
135 result
->putDirect(exec
->vm(), exec
->propertyNames().jettisonReason
, jsString(exec
, String::fromUTF8(toCString(m_jettisonReason
))));
140 } } // namespace JSC::Profiler