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 "ProfilerBytecodeSequence.h"
29 #include "CodeBlock.h"
30 #include "JSGlobalObject.h"
32 #include "JSCInlines.h"
33 #include <wtf/StringPrintStream.h>
35 namespace JSC
{ namespace Profiler
{
37 BytecodeSequence::BytecodeSequence(CodeBlock
* codeBlock
)
39 StringPrintStream out
;
41 for (unsigned i
= 0; i
< codeBlock
->numberOfArgumentValueProfiles(); ++i
) {
42 ConcurrentJITLocker
locker(codeBlock
->m_lock
);
43 CString description
= codeBlock
->valueProfileForArgument(i
)->briefDescription(locker
);
44 if (!description
.length())
47 out
.print("arg", i
, ": ", description
);
48 m_header
.append(out
.toCString());
51 StubInfoMap stubInfos
;
52 codeBlock
->getStubInfoMap(stubInfos
);
54 for (unsigned bytecodeIndex
= 0; bytecodeIndex
< codeBlock
->instructions().size();) {
56 codeBlock
->dumpBytecode(out
, bytecodeIndex
, stubInfos
);
57 m_sequence
.append(Bytecode(bytecodeIndex
, codeBlock
->vm()->interpreter
->getOpcodeID(codeBlock
->instructions()[bytecodeIndex
].u
.opcode
), out
.toCString()));
58 bytecodeIndex
+= opcodeLength(
59 codeBlock
->vm()->interpreter
->getOpcodeID(
60 codeBlock
->instructions()[bytecodeIndex
].u
.opcode
));
64 BytecodeSequence::~BytecodeSequence()
68 unsigned BytecodeSequence::indexForBytecodeIndex(unsigned bytecodeIndex
) const
70 return binarySearch
<Bytecode
, unsigned>(m_sequence
, m_sequence
.size(), bytecodeIndex
, getBytecodeIndexForBytecode
) - m_sequence
.begin();
73 const Bytecode
& BytecodeSequence::forBytecodeIndex(unsigned bytecodeIndex
) const
75 return at(indexForBytecodeIndex(bytecodeIndex
));
78 void BytecodeSequence::addSequenceProperties(ExecState
* exec
, JSObject
* result
) const
80 JSArray
* header
= constructEmptyArray(exec
, 0);
81 for (unsigned i
= 0; i
< m_header
.size(); ++i
)
82 header
->putDirectIndex(exec
, i
, jsString(exec
, String::fromUTF8(m_header
[i
])));
83 result
->putDirect(exec
->vm(), exec
->propertyNames().header
, header
);
85 JSArray
* sequence
= constructEmptyArray(exec
, 0);
86 for (unsigned i
= 0; i
< m_sequence
.size(); ++i
)
87 sequence
->putDirectIndex(exec
, i
, m_sequence
[i
].toJS(exec
));
88 result
->putDirect(exec
->vm(), exec
->propertyNames().bytecode
, sequence
);
91 } } // namespace JSC::Profiler