Commit d2deec81 authored by fpizlo@apple.com's avatar fpizlo@apple.com

Profiler should say things about OSR exits

https://bugs.webkit.org/show_bug.cgi?id=104497

Reviewed by Oliver Hunt.

Source/JavaScriptCore: 

This adds support for profiling OSR exits. For each exit that is taken, the profiler
records the machine code address that the exit occurred on, the exit kind, the origin
stack, and the number of times that it happened.

* CMakeLists.txt:
* GNUmakefile.list.am:
* JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
* JavaScriptCore.xcodeproj/project.pbxproj:
* Target.pri:
* assembler/AbstractMacroAssembler.h:
(Jump):
(JSC::AbstractMacroAssembler::Jump::label):
* bytecode/CodeBlock.h:
(JSC::CodeBlock::saveCompilation):
(CodeBlock):
(JSC::CodeBlock::compilation):
(DFGData):
* bytecode/DFGExitProfile.h:
(DFG):
* bytecode/ExitKind.cpp: Added.
(JSC):
(JSC::exitKindToString):
(JSC::exitKindIsCountable):
(WTF):
(WTF::printInternal):
* bytecode/ExitKind.h: Added.
(JSC):
(WTF):
* dfg/DFGGraph.h:
(Graph):
* dfg/DFGJITCompiler.cpp:
(JSC::DFG::JITCompiler::linkOSRExits):
(JSC::DFG::JITCompiler::link):
(JSC::DFG::JITCompiler::compile):
(JSC::DFG::JITCompiler::compileFunction):
* dfg/DFGJITCompiler.h:
(JITCompiler):
* dfg/DFGOSRExitCompiler.cpp:
* jit/JIT.cpp:
(JSC::JIT::JIT):
(JSC::JIT::privateCompile):
* jit/JIT.h:
(JIT):
* jit/JumpReplacementWatchpoint.h:
(JSC::JumpReplacementWatchpoint::sourceLabel):
(JumpReplacementWatchpoint):
* profiler/ProfilerCompilation.cpp:
(JSC::Profiler::Compilation::addOSRExitSite):
(Profiler):
(JSC::Profiler::Compilation::addOSRExit):
(JSC::Profiler::Compilation::toJS):
* profiler/ProfilerCompilation.h:
(Compilation):
* profiler/ProfilerDatabase.cpp:
(JSC::Profiler::Database::newCompilation):
* profiler/ProfilerDatabase.h:
(Database):
* profiler/ProfilerOSRExit.cpp: Added.
(Profiler):
(JSC::Profiler::OSRExit::OSRExit):
(JSC::Profiler::OSRExit::~OSRExit):
(JSC::Profiler::OSRExit::toJS):
* profiler/ProfilerOSRExit.h: Added.
(Profiler):
(OSRExit):
(JSC::Profiler::OSRExit::id):
(JSC::Profiler::OSRExit::origin):
(JSC::Profiler::OSRExit::exitKind):
(JSC::Profiler::OSRExit::isWatchpoint):
(JSC::Profiler::OSRExit::counterAddress):
(JSC::Profiler::OSRExit::count):
* profiler/ProfilerOSRExitSite.cpp: Added.
(Profiler):
(JSC::Profiler::OSRExitSite::toJS):
* profiler/ProfilerOSRExitSite.h: Added.
(Profiler):
(OSRExitSite):
(JSC::Profiler::OSRExitSite::OSRExitSite):
(JSC::Profiler::OSRExitSite::codeAddress):
* runtime/CommonIdentifiers.h:

Tools: 

Adds support for displaying OSR exit information for full summary (just displays the
counts and the number of recompilations), bytecode display (says which bytecodes
exited), and DFG display (annotates disassembly with taken OSR exits and their
counts).

* Scripts/display-profiler-output:



git-svn-id: http://svn.webkit.org/repository/webkit/trunk@137175 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 28215dbd
......@@ -50,6 +50,7 @@ set(JavaScriptCore_SOURCES
bytecode/CodeType.cpp
bytecode/DFGExitProfile.cpp
bytecode/ExecutionCounter.cpp
bytecode/ExitKind.cpp
bytecode/GetByIdStatus.cpp
bytecode/JumpTable.cpp
bytecode/LazyOperandValueProfile.cpp
......@@ -190,6 +191,8 @@ set(JavaScriptCore_SOURCES
profiler/ProfilerOrigin.h
profiler/ProfilerOriginStack.cpp
profiler/ProfilerOriginStack.h
profiler/ProfilerOSRExit.cpp
profiler/ProfilerOSRExitSite.cpp
profiler/Profile.cpp
profiler/ProfileGenerator.cpp
profiler/ProfileNode.cpp
......
2012-12-09 Filip Pizlo <fpizlo@apple.com>
Profiler should say things about OSR exits
https://bugs.webkit.org/show_bug.cgi?id=104497
Reviewed by Oliver Hunt.
This adds support for profiling OSR exits. For each exit that is taken, the profiler
records the machine code address that the exit occurred on, the exit kind, the origin
stack, and the number of times that it happened.
* CMakeLists.txt:
* GNUmakefile.list.am:
* JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
* JavaScriptCore.xcodeproj/project.pbxproj:
* Target.pri:
* assembler/AbstractMacroAssembler.h:
(Jump):
(JSC::AbstractMacroAssembler::Jump::label):
* bytecode/CodeBlock.h:
(JSC::CodeBlock::saveCompilation):
(CodeBlock):
(JSC::CodeBlock::compilation):
(DFGData):
* bytecode/DFGExitProfile.h:
(DFG):
* bytecode/ExitKind.cpp: Added.
(JSC):
(JSC::exitKindToString):
(JSC::exitKindIsCountable):
(WTF):
(WTF::printInternal):
* bytecode/ExitKind.h: Added.
(JSC):
(WTF):
* dfg/DFGGraph.h:
(Graph):
* dfg/DFGJITCompiler.cpp:
(JSC::DFG::JITCompiler::linkOSRExits):
(JSC::DFG::JITCompiler::link):
(JSC::DFG::JITCompiler::compile):
(JSC::DFG::JITCompiler::compileFunction):
* dfg/DFGJITCompiler.h:
(JITCompiler):
* dfg/DFGOSRExitCompiler.cpp:
* jit/JIT.cpp:
(JSC::JIT::JIT):
(JSC::JIT::privateCompile):
* jit/JIT.h:
(JIT):
* jit/JumpReplacementWatchpoint.h:
(JSC::JumpReplacementWatchpoint::sourceLabel):
(JumpReplacementWatchpoint):
* profiler/ProfilerCompilation.cpp:
(JSC::Profiler::Compilation::addOSRExitSite):
(Profiler):
(JSC::Profiler::Compilation::addOSRExit):
(JSC::Profiler::Compilation::toJS):
* profiler/ProfilerCompilation.h:
(Compilation):
* profiler/ProfilerDatabase.cpp:
(JSC::Profiler::Database::newCompilation):
* profiler/ProfilerDatabase.h:
(Database):
* profiler/ProfilerOSRExit.cpp: Added.
(Profiler):
(JSC::Profiler::OSRExit::OSRExit):
(JSC::Profiler::OSRExit::~OSRExit):
(JSC::Profiler::OSRExit::toJS):
* profiler/ProfilerOSRExit.h: Added.
(Profiler):
(OSRExit):
(JSC::Profiler::OSRExit::id):
(JSC::Profiler::OSRExit::origin):
(JSC::Profiler::OSRExit::exitKind):
(JSC::Profiler::OSRExit::isWatchpoint):
(JSC::Profiler::OSRExit::counterAddress):
(JSC::Profiler::OSRExit::count):
* profiler/ProfilerOSRExitSite.cpp: Added.
(Profiler):
(JSC::Profiler::OSRExitSite::toJS):
* profiler/ProfilerOSRExitSite.h: Added.
(Profiler):
(OSRExitSite):
(JSC::Profiler::OSRExitSite::OSRExitSite):
(JSC::Profiler::OSRExitSite::codeAddress):
* runtime/CommonIdentifiers.h:
2012-12-10 Alexis Menard <alexis@webkit.org>
[CSS3 Backgrounds and Borders] Remove CSS3_BACKGROUND feature flag.
......
......@@ -110,6 +110,8 @@ javascriptcore_sources += \
Source/JavaScriptCore/bytecode/EvalCodeCache.h \
Source/JavaScriptCore/bytecode/ExecutionCounter.cpp \
Source/JavaScriptCore/bytecode/ExecutionCounter.h \
Source/JavaScriptCore/bytecode/ExitKind.cpp \
Source/JavaScriptCore/bytecode/ExitKind.h \
Source/JavaScriptCore/bytecode/ExpressionRangeInfo.h \
Source/JavaScriptCore/bytecode/GetByIdStatus.cpp \
Source/JavaScriptCore/bytecode/GetByIdStatus.h \
......@@ -490,6 +492,10 @@ javascriptcore_sources += \
Source/JavaScriptCore/profiler/ProfilerOrigin.h \
Source/JavaScriptCore/profiler/ProfilerOriginStack.cpp \
Source/JavaScriptCore/profiler/ProfilerOriginStack.h \
Source/JavaScriptCore/profiler/ProfilerOSRExit.cpp \
Source/JavaScriptCore/profiler/ProfilerOSRExit.h \
Source/JavaScriptCore/profiler/ProfilerOSRExitSite.cpp \
Source/JavaScriptCore/profiler/ProfilerOSRExitSite.h \
Source/JavaScriptCore/profiler/Profile.cpp \
Source/JavaScriptCore/profiler/ProfileGenerator.cpp \
Source/JavaScriptCore/profiler/ProfileGenerator.h \
......
......@@ -1593,6 +1593,22 @@
RelativePath="..\..\profiler\ProfilerOriginStack.h"
>
</File>
<File
RelativePath="..\..\profiler\ProfilerOSRExit.cpp"
>
</File>
<File
RelativePath="..\..\profiler\ProfilerOSRExit.h"
>
</File>
<File
RelativePath="..\..\profiler\ProfilerOSRExitSite.cpp"
>
</File>
<File
RelativePath="..\..\profiler\ProfilerOSRExitSite.h"
>
</File>
<File
RelativePath="..\..\profiler\Profile.cpp"
>
......@@ -1749,6 +1765,14 @@
RelativePath="..\..\bytecode\ExpressionRangeInfo.h"
>
</File>
<File
RelativePath="..\..\bytecode\ExitKind.h"
>
</File>
<File
RelativePath="..\..\bytecode\ExitKind.cpp"
>
</File>
<File
RelativePath="..\..\bytecode\GetByIdStatus.cpp"
>
......
......@@ -201,6 +201,12 @@
0FA581BC150E953000B9A2D9 /* DFGNodeType.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FA581B9150E952A00B9A2D9 /* DFGNodeType.h */; settings = {ATTRIBUTES = (Private, ); }; };
0FAF7EFD165BA91B000C8455 /* JITDisassembler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FAF7EFA165BA919000C8455 /* JITDisassembler.cpp */; };
0FAF7EFE165BA91F000C8455 /* JITDisassembler.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FAF7EFB165BA919000C8455 /* JITDisassembler.h */; settings = {ATTRIBUTES = (Private, ); }; };
0FB105851675480F00F8AB6E /* ExitKind.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FB105821675480C00F8AB6E /* ExitKind.cpp */; };
0FB105861675481200F8AB6E /* ExitKind.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FB105831675480C00F8AB6E /* ExitKind.h */; settings = {ATTRIBUTES = (Private, ); }; };
0FB1058B1675483100F8AB6E /* ProfilerOSRExit.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FB105871675482E00F8AB6E /* ProfilerOSRExit.cpp */; };
0FB1058C1675483300F8AB6E /* ProfilerOSRExit.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FB105881675482E00F8AB6E /* ProfilerOSRExit.h */; settings = {ATTRIBUTES = (Private, ); }; };
0FB1058D1675483700F8AB6E /* ProfilerOSRExitSite.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FB105891675482E00F8AB6E /* ProfilerOSRExitSite.cpp */; };
0FB1058E1675483A00F8AB6E /* ProfilerOSRExitSite.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FB1058A1675482E00F8AB6E /* ProfilerOSRExitSite.h */; settings = {ATTRIBUTES = (Private, ); }; };
0FB5467714F59B5C002C2989 /* LazyOperandValueProfile.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FB5467614F59AD1002C2989 /* LazyOperandValueProfile.h */; settings = {ATTRIBUTES = (Private, ); }; };
0FB5467914F5C46B002C2989 /* LazyOperandValueProfile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FB5467814F5C468002C2989 /* LazyOperandValueProfile.cpp */; };
0FB5467B14F5C7E1002C2989 /* MethodOfGettingAValueProfile.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FB5467A14F5C7D4002C2989 /* MethodOfGettingAValueProfile.h */; settings = {ATTRIBUTES = (Private, ); }; };
......@@ -1025,6 +1031,12 @@
0FA581B9150E952A00B9A2D9 /* DFGNodeType.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGNodeType.h; path = dfg/DFGNodeType.h; sourceTree = "<group>"; };
0FAF7EFA165BA919000C8455 /* JITDisassembler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JITDisassembler.cpp; sourceTree = "<group>"; };
0FAF7EFB165BA919000C8455 /* JITDisassembler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JITDisassembler.h; sourceTree = "<group>"; };
0FB105821675480C00F8AB6E /* ExitKind.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ExitKind.cpp; sourceTree = "<group>"; };
0FB105831675480C00F8AB6E /* ExitKind.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ExitKind.h; sourceTree = "<group>"; };
0FB105871675482E00F8AB6E /* ProfilerOSRExit.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ProfilerOSRExit.cpp; path = profiler/ProfilerOSRExit.cpp; sourceTree = "<group>"; };
0FB105881675482E00F8AB6E /* ProfilerOSRExit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ProfilerOSRExit.h; path = profiler/ProfilerOSRExit.h; sourceTree = "<group>"; };
0FB105891675482E00F8AB6E /* ProfilerOSRExitSite.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ProfilerOSRExitSite.cpp; path = profiler/ProfilerOSRExitSite.cpp; sourceTree = "<group>"; };
0FB1058A1675482E00F8AB6E /* ProfilerOSRExitSite.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ProfilerOSRExitSite.h; path = profiler/ProfilerOSRExitSite.h; sourceTree = "<group>"; };
0FB5467614F59AD1002C2989 /* LazyOperandValueProfile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LazyOperandValueProfile.h; sourceTree = "<group>"; };
0FB5467814F5C468002C2989 /* LazyOperandValueProfile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LazyOperandValueProfile.cpp; sourceTree = "<group>"; };
0FB5467A14F5C7D4002C2989 /* MethodOfGettingAValueProfile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MethodOfGettingAValueProfile.h; sourceTree = "<group>"; };
......@@ -2554,6 +2566,14 @@
isa = PBXGroup;
children = (
95E3BC040E1AE68200B2D1C1 /* CallIdentifier.h */,
95AB832E0DA42CAD00BC83F3 /* LegacyProfiler.cpp */,
95AB832F0DA42CAD00BC83F3 /* LegacyProfiler.h */,
95742F630DD11F5A000917FB /* Profile.cpp */,
95742F640DD11F5A000917FB /* Profile.h */,
95CD45740E1C4FDD0085358E /* ProfileGenerator.cpp */,
95CD45750E1C4FDD0085358E /* ProfileGenerator.h */,
95AB83540DA43B4400BC83F3 /* ProfileNode.cpp */,
95AB83550DA43B4400BC83F3 /* ProfileNode.h */,
0FF72992166AD347000F5BA3 /* ProfilerBytecode.cpp */,
0FF72993166AD347000F5BA3 /* ProfilerBytecode.h */,
0FF72994166AD347000F5BA3 /* ProfilerBytecodes.cpp */,
......@@ -2571,14 +2591,10 @@
0FF729A0166AD347000F5BA3 /* ProfilerOrigin.h */,
0FF729A1166AD347000F5BA3 /* ProfilerOriginStack.cpp */,
0FF729A2166AD347000F5BA3 /* ProfilerOriginStack.h */,
95742F630DD11F5A000917FB /* Profile.cpp */,
95742F640DD11F5A000917FB /* Profile.h */,
95CD45740E1C4FDD0085358E /* ProfileGenerator.cpp */,
95CD45750E1C4FDD0085358E /* ProfileGenerator.h */,
95AB83540DA43B4400BC83F3 /* ProfileNode.cpp */,
95AB83550DA43B4400BC83F3 /* ProfileNode.h */,
95AB832E0DA42CAD00BC83F3 /* LegacyProfiler.cpp */,
95AB832F0DA42CAD00BC83F3 /* LegacyProfiler.h */,
0FB105871675482E00F8AB6E /* ProfilerOSRExit.cpp */,
0FB105881675482E00F8AB6E /* ProfilerOSRExit.h */,
0FB105891675482E00F8AB6E /* ProfilerOSRExitSite.cpp */,
0FB1058A1675482E00F8AB6E /* ProfilerOSRExitSite.h */,
);
name = profiler;
sourceTree = "<group>";
......@@ -2647,6 +2663,8 @@
969A07920ED1D3AE00F1F681 /* EvalCodeCache.h */,
0F56A1D415001CF2002992B1 /* ExecutionCounter.cpp */,
0F56A1D115000F31002992B1 /* ExecutionCounter.h */,
0FB105821675480C00F8AB6E /* ExitKind.cpp */,
0FB105831675480C00F8AB6E /* ExitKind.h */,
0F0B83AA14BCF5B900885B4F /* ExpressionRangeInfo.h */,
0F93329514CA7DC10085F3C6 /* GetByIdStatus.cpp */,
0F93329614CA7DC10085F3C6 /* GetByIdStatus.h */,
......@@ -3143,6 +3161,9 @@
0FF729BE166AD360000F5BA3 /* ProfilerExecutionCounter.h in Headers */,
0FF729BF166AD360000F5BA3 /* ProfilerOrigin.h in Headers */,
0FF729C0166AD360000F5BA3 /* ProfilerOriginStack.h in Headers */,
0FB105861675481200F8AB6E /* ExitKind.h in Headers */,
0FB1058C1675483300F8AB6E /* ProfilerOSRExit.h in Headers */,
0FB1058E1675483A00F8AB6E /* ProfilerOSRExitSite.h in Headers */,
0FF60AC216740F8300029779 /* ReduceWhitespace.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
......@@ -3740,6 +3761,9 @@
0FF729B2166AD35C000F5BA3 /* ProfilerDatabase.cpp in Sources */,
0FF729B3166AD35C000F5BA3 /* ProfilerOrigin.cpp in Sources */,
0FF729B4166AD35C000F5BA3 /* ProfilerOriginStack.cpp in Sources */,
0FB105851675480F00F8AB6E /* ExitKind.cpp in Sources */,
0FB1058B1675483100F8AB6E /* ProfilerOSRExit.cpp in Sources */,
0FB1058D1675483700F8AB6E /* ProfilerOSRExitSite.cpp in Sources */,
0FF60AC316740F8800029779 /* ReduceWhitespace.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
......
......@@ -60,6 +60,7 @@ SOURCES += \
bytecode/CodeType.cpp \
bytecode/DFGExitProfile.cpp \
bytecode/ExecutionCounter.cpp \
bytecode/ExitKind.cpp \
bytecode/GetByIdStatus.cpp \
bytecode/JumpTable.cpp \
bytecode/LazyOperandValueProfile.cpp \
......@@ -200,6 +201,8 @@ SOURCES += \
profiler/ProfilerOrigin.h \
profiler/ProfilerOriginStack.cpp \
profiler/ProfilerOriginStack.h \
profiler/ProfilerOSRExit.cpp \
profiler/ProfilerOSRExitSite.cpp \
profiler/Profile.cpp \
profiler/ProfileGenerator.cpp \
profiler/ProfileNode.cpp \
......
......@@ -528,6 +528,13 @@ public:
{
}
#endif
Label label() const
{
Label result;
result.m_label = m_label;
return result;
}
void link(AbstractMacroAssembler<AssemblerType>* masm) const
{
......
......@@ -62,6 +62,7 @@
#include "LazyOperandValueProfile.h"
#include "LineInfo.h"
#include "Nodes.h"
#include "ProfilerCompilation.h"
#include "RegExpObject.h"
#include "ResolveOperation.h"
#include "StructureStubInfo.h"
......@@ -324,6 +325,19 @@ namespace JSC {
m_dfgData = adoptPtr(new DFGData);
}
void saveCompilation(PassRefPtr<Profiler::Compilation> compilation)
{
createDFGDataIfNecessary();
m_dfgData->compilation = compilation;
}
Profiler::Compilation* compilation()
{
if (!m_dfgData)
return 0;
return m_dfgData->compilation.get();
}
DFG::OSREntryData* appendDFGOSREntryData(unsigned bytecodeIndex, unsigned machineCodeOffset)
{
createDFGDataIfNecessary();
......@@ -1275,6 +1289,7 @@ namespace JSC {
Vector<WriteBarrier<JSCell> > weakReferences;
DFG::VariableEventStream variableEventStream;
DFG::MinifiedGraph minifiedDFG;
RefPtr<Profiler::Compilation> compilation;
bool mayBeExecuting;
bool isJettisoned;
bool livenessHasBeenProved; // Initialized and used on every GC.
......
/*
* Copyright (C) 2011 Apple Inc. All rights reserved.
* Copyright (C) 2011, 2012 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
......@@ -26,73 +26,13 @@
#ifndef DFGExitProfile_h
#define DFGExitProfile_h
#include "ExitKind.h"
#include <wtf/HashSet.h>
#include <wtf/OwnPtr.h>
#include <wtf/Vector.h>
namespace JSC { namespace DFG {
enum ExitKind {
ExitKindUnset,
BadType, // We exited because a type prediction was wrong.
BadCache, // We exited because an inline cache was wrong.
BadWeakConstantCache, // We exited because a cache on a weak constant (usually a prototype) was wrong.
BadIndexingType, // We exited because an indexing type was wrong.
Overflow, // We exited because of overflow.
NegativeZero, // We exited because we encountered negative zero.
OutOfBounds, // We had an out-of-bounds access to an array.
InadequateCoverage, // We exited because we ended up in code that didn't have profiling coverage.
ArgumentsEscaped, // We exited because arguments escaped but we didn't expect them to.
Uncountable, // We exited for none of the above reasons, and we should not count it. Most uses of this should be viewed as a FIXME.
UncountableWatchpoint // We exited because of a watchpoint, which isn't counted because watchpoints do tracking themselves.
};
inline const char* exitKindToString(ExitKind kind)
{
switch (kind) {
case ExitKindUnset:
return "Unset";
case BadType:
return "BadType";
case BadCache:
return "BadCache";
case BadWeakConstantCache:
return "BadWeakConstantCache";
case BadIndexingType:
return "BadIndexingType";
case Overflow:
return "Overflow";
case NegativeZero:
return "NegativeZero";
case OutOfBounds:
return "OutOfBounds";
case InadequateCoverage:
return "InadequateCoverage";
case ArgumentsEscaped:
return "ArgumentsEscaped";
case Uncountable:
return "Uncountable";
case UncountableWatchpoint:
return "UncountableWatchpoint";
default:
return "Unknown";
}
}
inline bool exitKindIsCountable(ExitKind kind)
{
switch (kind) {
case ExitKindUnset:
ASSERT_NOT_REACHED();
case BadType:
case Uncountable:
case UncountableWatchpoint:
return false;
default:
return true;
}
}
class FrequentExitSite {
public:
FrequentExitSite()
......
/*
* Copyright (C) 2012 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
#include "ExitKind.h"
#include <wtf/Assertions.h>
#include <wtf/PrintStream.h>
namespace JSC {
const char* exitKindToString(ExitKind kind)
{
switch (kind) {
case ExitKindUnset:
return "Unset";
case BadType:
return "BadType";
case BadCache:
return "BadCache";
case BadWeakConstantCache:
return "BadWeakConstantCache";
case BadIndexingType:
return "BadIndexingType";
case Overflow:
return "Overflow";
case NegativeZero:
return "NegativeZero";
case OutOfBounds:
return "OutOfBounds";
case InadequateCoverage:
return "InadequateCoverage";
case ArgumentsEscaped:
return "ArgumentsEscaped";
case Uncountable:
return "Uncountable";
case UncountableWatchpoint:
return "UncountableWatchpoint";
default:
return "Unknown";
}
}
bool exitKindIsCountable(ExitKind kind)
{
switch (kind) {
case ExitKindUnset:
ASSERT_NOT_REACHED();
case BadType:
case Uncountable:
case UncountableWatchpoint:
return false;
default:
return true;
}
}
} // namespace JSC
namespace WTF {
void printInternal(PrintStream& out, JSC::ExitKind kind)
{
out.print(exitKindToString(kind));
}
} // namespace WTF
/*
* Copyright (C) 2012 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef ExitKind_h
#define ExitKind_h
namespace JSC {
enum ExitKind {
ExitKindUnset,
BadType, // We exited because a type prediction was wrong.
BadCache, // We exited because an inline cache was wrong.
BadWeakConstantCache, // We exited because a cache on a weak constant (usually a prototype) was wrong.
BadIndexingType, // We exited because an indexing type was wrong.
Overflow, // We exited because of overflow.
NegativeZero, // We exited because we encountered negative zero.
OutOfBounds, // We had an out-of-bounds access to an array.
InadequateCoverage, // We exited because we ended up in code that didn't have profiling coverage.
ArgumentsEscaped, // We exited because arguments escaped but we didn't expect them to.
Uncountable, // We exited for none of the above reasons, and we should not count it. Most uses of this should be viewed as a FIXME.
UncountableWatchpoint // We exited because of a watchpoint, which isn't counted because watchpoints do tracking themselves.
};
const char* exitKindToString(ExitKind);
bool exitKindIsCountable(ExitKind);
} // namespace JSC
namespace WTF {
class PrintStream;
void printInternal(PrintStream&, JSC::ExitKind);
} // namespace WTF
#endif // ExitKind_h
......@@ -671,7 +671,7 @@ public:
JSGlobalData& m_globalData;
CodeBlock* m_codeBlock;
Profiler::Compilation* m_compilation;
RefPtr<Profiler::Compilation> m_compilation;
CodeBlock* m_profiledBlock;
Vector< OwnPtr<BasicBlock> , 8> m_blocks;
......
......@@ -51,6 +51,16 @@ JITCompiler::JITCompiler(Graph& dfg)
void JITCompiler::linkOSRExits()
{
if (m_graph.m_compilation) {
for (unsigned i = 0; i < codeBlock()->numberOfOSRExits(); ++i) {
OSRExit& exit = codeBlock()->osrExit(i);
if (exit.m_watchpointIndex == std::numeric_limits<unsigned>::max())
m_exitSiteLabels.append(exit.m_check.initialJump().label());
else
m_exitSiteLabels.append(codeBlock()->watchpoint(exit.m_watchpointIndex).sourceLabel());
}
}
for (unsigned i = 0; i < codeBlock()->numberOfOSRExits(); ++i) {
OSRExit& exit = codeBlock()->osrExit(i);
ASSERT(!exit.m_check.isSet() == (exit.m_watchpointIndex != std::numeric_limits<unsigned>::max()));
......@@ -206,6 +216,17 @@ void JITCompiler::link(LinkBuffer& linkBuffer)
codeBlock()->watchpoint(exit.m_watchpointIndex).correctLabels(linkBuffer);
}
if (m_graph.m_compilation) {
ASSERT(m_exitSiteLabels.size() == codeBlock()->numberOfOSRExits());
for (unsigned i = 0; i < m_exitSiteLabels.size(); ++i) {
m_graph.m_compilation->addOSRExitSite(
linkBuffer.locationOf(m_exitSiteLabels[i]).executableAddress());
}
} else
ASSERT(!m_exitSiteLabels.size());
codeBlock()->saveCompilation(m_graph.m_compilation);
codeBlock()->minifiedDFG().setOriginalGraphSize(m_graph.size());
codeBlock()->shrinkToFit(CodeBlock::LateShrink);
}
......@@ -239,7 +260,7 @@ bool JITCompiler::compile(JITCode& entry)
if (shouldShowDisassembly())
m_disassembler->dump(linkBuffer);
if (m_graph.m_compilation)
m_disassembler->reportToProfiler(m_graph.m_compilation, linkBuffer);
m_disassembler->reportToProfiler(m_graph.m_compilation.get(), linkBuffer);
entry = JITCode(
linkBuffer.finalizeCodeWithoutDisassembly(),
......@@ -332,7 +353,7 @@ bool JITCompiler::compileFunction(JITCode& entry, MacroAssemblerCodePtr& entryWi
if (shouldShowDisassembly())
m_disassembler->dump(linkBuffer);
if (m_graph.m_compilation)
m_disassembler->reportToProfiler(m_graph.m_compilation, linkBuffer);
m_disassembler->reportToProfiler(m_graph.m_compilation.get(), linkBuffer);