]>
git.saurik.com Git - apple/javascriptcore.git/blob - profiler/ProfilerCompilation.cpp
2 * Copyright (C) 2012, 2013 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 "Operations.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_numInlinedGetByIds(0)
41 , m_numInlinedPutByIds(0)
42 , m_numInlinedCalls(0)
46 Compilation::~Compilation() { }
48 void Compilation::addProfiledBytecodes(Database
& database
, CodeBlock
* profiledBlock
)
50 Bytecodes
* bytecodes
= database
.ensureBytecodesFor(profiledBlock
);
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.
57 for (unsigned i
= m_profiledBytecodes
.size(); i
--;) {
58 if (m_profiledBytecodes
[i
].bytecodes() == bytecodes
)
62 m_profiledBytecodes
.append(ProfiledBytecodes(bytecodes
, profiledBlock
));
65 void Compilation::addDescription(const CompiledBytecode
& compiledBytecode
)
67 m_descriptions
.append(compiledBytecode
);
70 ExecutionCounter
* Compilation::executionCounterFor(const OriginStack
& origin
)
72 HashMap
<OriginStack
, OwnPtr
<ExecutionCounter
> >::iterator iter
= m_counters
.find(origin
);
73 if (iter
!= m_counters
.end())
74 return iter
->value
.get();
76 OwnPtr
<ExecutionCounter
> counter
= adoptPtr(new ExecutionCounter());
77 ExecutionCounter
* result
= counter
.get();
78 m_counters
.add(origin
, counter
.release());
82 void Compilation::addOSRExitSite(const Vector
<const void*>& codeAddresses
)
84 m_osrExitSites
.append(OSRExitSite(codeAddresses
));
87 OSRExit
* Compilation::addOSRExit(unsigned id
, const OriginStack
& originStack
, ExitKind exitKind
, bool isWatchpoint
)
89 m_osrExits
.append(OSRExit(id
, originStack
, exitKind
, isWatchpoint
));
90 return &m_osrExits
.last();
93 JSValue
Compilation::toJS(ExecState
* exec
) const
95 JSObject
* result
= constructEmptyObject(exec
);
97 result
->putDirect(exec
->vm(), exec
->propertyNames().bytecodesID
, jsNumber(m_bytecodes
->id()));
98 result
->putDirect(exec
->vm(), exec
->propertyNames().compilationKind
, jsString(exec
, String::fromUTF8(toCString(m_kind
))));
100 JSArray
* profiledBytecodes
= constructEmptyArray(exec
, 0);
101 for (unsigned i
= 0; i
< m_profiledBytecodes
.size(); ++i
)
102 profiledBytecodes
->putDirectIndex(exec
, i
, m_profiledBytecodes
[i
].toJS(exec
));
103 result
->putDirect(exec
->vm(), exec
->propertyNames().profiledBytecodes
, profiledBytecodes
);
105 JSArray
* descriptions
= constructEmptyArray(exec
, 0);
106 for (unsigned i
= 0; i
< m_descriptions
.size(); ++i
)
107 descriptions
->putDirectIndex(exec
, i
, m_descriptions
[i
].toJS(exec
));
108 result
->putDirect(exec
->vm(), exec
->propertyNames().descriptions
, descriptions
);
110 JSArray
* counters
= constructEmptyArray(exec
, 0);
111 HashMap
<OriginStack
, OwnPtr
<ExecutionCounter
> >::const_iterator end
= m_counters
.end();
112 for (HashMap
<OriginStack
, OwnPtr
<ExecutionCounter
> >::const_iterator iter
= m_counters
.begin(); iter
!= end
; ++iter
) {
113 JSObject
* counterEntry
= constructEmptyObject(exec
);
114 counterEntry
->putDirect(exec
->vm(), exec
->propertyNames().origin
, iter
->key
.toJS(exec
));
115 counterEntry
->putDirect(exec
->vm(), exec
->propertyNames().executionCount
, jsNumber(iter
->value
->count()));
116 counters
->push(exec
, counterEntry
);
118 result
->putDirect(exec
->vm(), exec
->propertyNames().counters
, counters
);
120 JSArray
* exitSites
= constructEmptyArray(exec
, 0);
121 for (unsigned i
= 0; i
< m_osrExitSites
.size(); ++i
)
122 exitSites
->putDirectIndex(exec
, i
, m_osrExitSites
[i
].toJS(exec
));
123 result
->putDirect(exec
->vm(), exec
->propertyNames().osrExitSites
, exitSites
);
125 JSArray
* exits
= constructEmptyArray(exec
, 0);
126 for (unsigned i
= 0; i
< m_osrExits
.size(); ++i
)
127 exits
->putDirectIndex(exec
, i
, m_osrExits
[i
].toJS(exec
));
128 result
->putDirect(exec
->vm(), exec
->propertyNames().osrExits
, exits
);
130 result
->putDirect(exec
->vm(), exec
->propertyNames().numInlinedGetByIds
, jsNumber(m_numInlinedGetByIds
));
131 result
->putDirect(exec
->vm(), exec
->propertyNames().numInlinedPutByIds
, jsNumber(m_numInlinedPutByIds
));
132 result
->putDirect(exec
->vm(), exec
->propertyNames().numInlinedCalls
, jsNumber(m_numInlinedCalls
));
137 } } // namespace JSC::Profiler