Diff
Modified: trunk/Source/_javascript_Core/CMakeLists.txt (194293 => 194294)
--- trunk/Source/_javascript_Core/CMakeLists.txt 2015-12-18 21:52:07 UTC (rev 194293)
+++ trunk/Source/_javascript_Core/CMakeLists.txt 2015-12-18 22:03:30 UTC (rev 194294)
@@ -203,6 +203,7 @@
bytecode/UnlinkedCodeBlock.cpp
bytecode/UnlinkedFunctionExecutable.cpp
bytecode/UnlinkedInstructionStream.cpp
+ bytecode/ValueProfile.cpp
bytecode/ValueRecovery.cpp
bytecode/VariableWriteFireDetail.cpp
bytecode/VirtualRegister.cpp
Modified: trunk/Source/_javascript_Core/ChangeLog (194293 => 194294)
--- trunk/Source/_javascript_Core/ChangeLog 2015-12-18 21:52:07 UTC (rev 194293)
+++ trunk/Source/_javascript_Core/ChangeLog 2015-12-18 22:03:30 UTC (rev 194294)
@@ -1,3 +1,78 @@
+2015-12-18 Mark Lam <[email protected]>
+
+ Replace SpecialFastCase profiles with ResultProfiles.
+ https://bugs.webkit.org/show_bug.cgi?id=152433
+
+ Reviewed by Saam Barati.
+
+ This is in preparation for upcoming work to enhance the DFG predictions to deal
+ with untyped operands.
+
+ This patch also enhances some of the arithmetic slow paths (for the LLINT and
+ baseline JIT) to collect result profiling info. This profiling info is not put
+ to use yet.
+
+ * CMakeLists.txt:
+ * _javascript_Core.vcxproj/_javascript_Core.vcxproj:
+ * _javascript_Core.vcxproj/_javascript_Core.vcxproj.filters:
+ * _javascript_Core.xcodeproj/project.pbxproj:
+ * bytecode/CodeBlock.cpp:
+ (JSC::CodeBlock::dumpRareCaseProfile):
+ (JSC::CodeBlock::dumpResultProfile):
+ (JSC::CodeBlock::printLocationAndOp):
+ (JSC::CodeBlock::dumpBytecode):
+ (JSC::CodeBlock::shrinkToFit):
+ (JSC::CodeBlock::dumpValueProfiles):
+ (JSC::CodeBlock::rareCaseProfileCountForBytecodeOffset):
+ (JSC::CodeBlock::resultProfileForBytecodeOffset):
+ (JSC::CodeBlock::updateResultProfileForBytecodeOffset):
+ (JSC::CodeBlock::capabilityLevel):
+ * bytecode/CodeBlock.h:
+ (JSC::CodeBlock::couldTakeSlowCase):
+ (JSC::CodeBlock::addResultProfile):
+ (JSC::CodeBlock::numberOfResultProfiles):
+ (JSC::CodeBlock::specialFastCaseProfileCountForBytecodeOffset):
+ (JSC::CodeBlock::couldTakeSpecialFastCase):
+ (JSC::CodeBlock::addSpecialFastCaseProfile): Deleted.
+ (JSC::CodeBlock::numberOfSpecialFastCaseProfiles): Deleted.
+ (JSC::CodeBlock::specialFastCaseProfile): Deleted.
+ (JSC::CodeBlock::specialFastCaseProfileForBytecodeOffset): Deleted.
+ * bytecode/ValueProfile.cpp: Added.
+ (WTF::printInternal):
+ * bytecode/ValueProfile.h:
+ (JSC::getRareCaseProfileBytecodeOffset):
+ (JSC::ResultProfile::ResultProfile):
+ (JSC::ResultProfile::bytecodeOffset):
+ (JSC::ResultProfile::specialFastPathCount):
+ (JSC::ResultProfile::didObserveNonInt32):
+ (JSC::ResultProfile::didObserveDouble):
+ (JSC::ResultProfile::didObserveNonNegZeroDouble):
+ (JSC::ResultProfile::didObserveNegZeroDouble):
+ (JSC::ResultProfile::didObserveNonNumber):
+ (JSC::ResultProfile::didObserveInt32Overflow):
+ (JSC::ResultProfile::setObservedNonNegZeroDouble):
+ (JSC::ResultProfile::setObservedNegZeroDouble):
+ (JSC::ResultProfile::setObservedNonNumber):
+ (JSC::ResultProfile::setObservedInt32Overflow):
+ (JSC::ResultProfile::addressOfFlags):
+ (JSC::ResultProfile::addressOfSpecialFastPathCount):
+ (JSC::ResultProfile::hasBits):
+ (JSC::ResultProfile::setBit):
+ (JSC::getResultProfileBytecodeOffset):
+ * jit/JITArithmetic.cpp:
+ (JSC::JIT::emit_op_div):
+ (JSC::JIT::emit_op_mul):
+ * jit/JITDivGenerator.cpp:
+ (JSC::JITDivGenerator::generateFastPath):
+ * jit/JITDivGenerator.h:
+ (JSC::JITDivGenerator::JITDivGenerator):
+ * jit/JITMulGenerator.cpp:
+ (JSC::JITMulGenerator::generateFastPath):
+ * jit/JITMulGenerator.h:
+ (JSC::JITMulGenerator::JITMulGenerator):
+ * runtime/CommonSlowPaths.cpp:
+ (JSC::SLOW_PATH_DECL):
+
2015-12-18 Keith Miller <[email protected]>
verboseDFGByteCodeParsing option should show the bytecode it is parsing.
Modified: trunk/Source/_javascript_Core/_javascript_Core.vcxproj/_javascript_Core.vcxproj (194293 => 194294)
--- trunk/Source/_javascript_Core/_javascript_Core.vcxproj/_javascript_Core.vcxproj 2015-12-18 21:52:07 UTC (rev 194293)
+++ trunk/Source/_javascript_Core/_javascript_Core.vcxproj/_javascript_Core.vcxproj 2015-12-18 22:03:30 UTC (rev 194294)
@@ -362,6 +362,7 @@
<ClCompile Include="..\bytecode\UnlinkedCodeBlock.cpp" />
<ClCompile Include="..\bytecode\UnlinkedFunctionExecutable.cpp" />
<ClCompile Include="..\bytecode\UnlinkedInstructionStream.cpp" />
+ <ClCompile Include="..\bytecode\ValueProfile.cpp" />
<ClCompile Include="..\bytecode\ValueRecovery.cpp" />
<ClCompile Include="..\bytecode\VariableWriteFireDetail.cpp" />
<ClCompile Include="..\bytecode\VirtualRegister.cpp" />
Modified: trunk/Source/_javascript_Core/_javascript_Core.vcxproj/_javascript_Core.vcxproj.filters (194293 => 194294)
--- trunk/Source/_javascript_Core/_javascript_Core.vcxproj/_javascript_Core.vcxproj.filters 2015-12-18 21:52:07 UTC (rev 194293)
+++ trunk/Source/_javascript_Core/_javascript_Core.vcxproj/_javascript_Core.vcxproj.filters 2015-12-18 22:03:30 UTC (rev 194294)
@@ -1524,6 +1524,9 @@
<ClCompile Include="..\runtime\TestRunnerUtils.cpp">
<Filter>runtime</Filter>
</ClCompile>
+ <ClCompile Include="..\bytecode\ValueProfile.cpp">
+ <Filter>bytecode</Filter>
+ </ClCompile>
<ClCompile Include="..\bytecode\ValueRecovery.cpp">
<Filter>bytecode</Filter>
</ClCompile>
Modified: trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj (194293 => 194294)
--- trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj 2015-12-18 21:52:07 UTC (rev 194293)
+++ trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj 2015-12-18 22:03:30 UTC (rev 194294)
@@ -2054,6 +2054,7 @@
FE7C41961B97FC4B00F4D598 /* PingPongStackOverflowTest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FEDA50D41B97F442009A3B4F /* PingPongStackOverflowTest.cpp */; };
FEA08620182B7A0400F6D851 /* Breakpoint.h in Headers */ = {isa = PBXBuildFile; fileRef = FEA0861E182B7A0400F6D851 /* Breakpoint.h */; settings = {ATTRIBUTES = (Private, ); }; };
FEA08621182B7A0400F6D851 /* DebuggerPrimitives.h in Headers */ = {isa = PBXBuildFile; fileRef = FEA0861F182B7A0400F6D851 /* DebuggerPrimitives.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ FEA1E4391C213A2B00277A16 /* ValueProfile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FEA1E4381C213A2600277A16 /* ValueProfile.cpp */; settings = {ASSET_TAGS = (); }; };
FEB137571BB11EF900CD5100 /* MacroAssemblerARM64.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FEB137561BB11EEE00CD5100 /* MacroAssemblerARM64.cpp */; };
FEB51F6C1A97B688001F921C /* Regress141809.mm in Sources */ = {isa = PBXBuildFile; fileRef = FEB51F6B1A97B688001F921C /* Regress141809.mm */; };
FEB58C14187B8B160098EF0B /* ErrorHandlingScope.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FEB58C12187B8B160098EF0B /* ErrorHandlingScope.cpp */; };
@@ -4258,6 +4259,7 @@
FE98B5B61BB9AE110073E7A6 /* JITSubGenerator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JITSubGenerator.h; sourceTree = "<group>"; };
FEA0861E182B7A0400F6D851 /* Breakpoint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Breakpoint.h; sourceTree = "<group>"; };
FEA0861F182B7A0400F6D851 /* DebuggerPrimitives.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DebuggerPrimitives.h; sourceTree = "<group>"; };
+ FEA1E4381C213A2600277A16 /* ValueProfile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ValueProfile.cpp; sourceTree = "<group>"; };
FEB137561BB11EEE00CD5100 /* MacroAssemblerARM64.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MacroAssemblerARM64.cpp; sourceTree = "<group>"; };
FEB51F6A1A97B688001F921C /* Regress141809.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Regress141809.h; path = API/tests/Regress141809.h; sourceTree = "<group>"; };
FEB51F6B1A97B688001F921C /* Regress141809.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = Regress141809.mm; path = API/tests/Regress141809.mm; sourceTree = "<group>"; };
@@ -6520,6 +6522,7 @@
14142E501B796ECE00F4BF4B /* UnlinkedFunctionExecutable.h */,
B59F89381891ADB500D5CCDC /* UnlinkedInstructionStream.cpp */,
B59F89371891AD3300D5CCDC /* UnlinkedInstructionStream.h */,
+ FEA1E4381C213A2600277A16 /* ValueProfile.cpp */,
0F963B3613FC6FDE0002D9B2 /* ValueProfile.h */,
0F24E55717F74EDB00ABB217 /* ValueRecovery.cpp */,
0F426A451460CBAB00131F8F /* ValueRecovery.h */,
@@ -9244,6 +9247,7 @@
0FF4274A158EBE91004CB9FF /* udis86.c in Sources */,
0FF42740158EBE8B004CB9FF /* udis86_decode.c in Sources */,
0FF42743158EBE91004CB9FF /* udis86_input.c in Sources */,
+ FEA1E4391C213A2B00277A16 /* ValueProfile.cpp in Sources */,
0FF4274D158EBFE6004CB9FF /* udis86_itab_holder.c in Sources */,
0FF42745158EBE91004CB9FF /* udis86_syn-att.c in Sources */,
0FF42746158EBE91004CB9FF /* udis86_syn-intel.c in Sources */,
Modified: trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp (194293 => 194294)
--- trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp 2015-12-18 21:52:07 UTC (rev 194293)
+++ trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp 2015-12-18 22:03:30 UTC (rev 194294)
@@ -741,6 +741,15 @@
out.print(name, profile->m_counter);
}
+void CodeBlock::dumpResultProfile(PrintStream& out, ResultProfile* profile, bool& hasPrintedProfiling)
+{
+ if (!profile)
+ return;
+
+ beginDumpProfiling(out, hasPrintedProfiling);
+ out.print("results: ", *profile);
+}
+
void CodeBlock::printLocationAndOp(PrintStream& out, ExecState*, int location, const Instruction*&, const char* op)
{
out.printf("[%4d] %-17s ", location, op);
@@ -1651,7 +1660,7 @@
}
dumpRareCaseProfile(out, "rare case: ", rareCaseProfileForBytecodeOffset(location), hasPrintedProfiling);
- dumpRareCaseProfile(out, "special fast case: ", specialFastCaseProfileForBytecodeOffset(location), hasPrintedProfiling);
+ dumpResultProfile(out, resultProfileForBytecodeOffset(location), hasPrintedProfiling);
#if ENABLE(DFG_JIT)
Vector<DFG::FrequentExitSite> exitSites = exitProfile().exitSitesFor(location);
@@ -3131,7 +3140,7 @@
void CodeBlock::shrinkToFit(ShrinkMode shrinkMode)
{
m_rareCaseProfiles.shrinkToFit();
- m_specialFastCaseProfiles.shrinkToFit();
+ m_resultProfiles.shrinkToFit();
if (shrinkMode == EarlyShrink) {
m_constantRegisters.shrinkToFit();
@@ -3976,10 +3985,10 @@
RareCaseProfile* profile = ""
dataLogF(" bc = %d: %u\n", profile->m_bytecodeOffset, profile->m_counter);
}
- dataLog("SpecialFastCaseProfile for ", *this, ":\n");
- for (unsigned i = 0; i < numberOfSpecialFastCaseProfiles(); ++i) {
- RareCaseProfile* profile = ""
- dataLogF(" bc = %d: %u\n", profile->m_bytecodeOffset, profile->m_counter);
+ dataLog("ResultProfile for ", *this, ":\n");
+ for (unsigned i = 0; i < numberOfResultProfiles(); ++i) {
+ const ResultProfile& profile = ""
+ dataLog(" bc = ", profile.bytecodeOffset(), ": ", profile, "\n");
}
}
#endif // ENABLE(VERBOSE_VALUE_PROFILE)
@@ -4177,6 +4186,36 @@
return 0;
}
+ResultProfile* CodeBlock::resultProfileForBytecodeOffset(int bytecodeOffset)
+{
+ return tryBinarySearch<ResultProfile, int>(
+ m_resultProfiles, m_resultProfiles.size(), bytecodeOffset,
+ getResultProfileBytecodeOffset);
+}
+
+void CodeBlock::updateResultProfileForBytecodeOffset(int bytecodeOffset, JSValue result)
+{
+#if ENABLE(DFG_JIT)
+ ResultProfile* profile = ""
+ if (!profile)
+ profile = ""
+
+ if (result.isNumber()) {
+ if (!result.isInt32()) {
+ double doubleVal = result.asNumber();
+ if (!doubleVal && std::signbit(doubleVal))
+ profile->setObservedNegZeroDouble();
+ else
+ profile->setObservedNonNegZeroDouble();
+ }
+ } else
+ profile->setObservedNonNumber();
+#else
+ UNUSED_PARAM(bytecodeOffset);
+ UNUSED_PARAM(result);
+#endif
+}
+
#if ENABLE(JIT)
DFG::CapabilityLevel CodeBlock::capabilityLevel()
{
Modified: trunk/Source/_javascript_Core/bytecode/CodeBlock.h (194293 => 194294)
--- trunk/Source/_javascript_Core/bytecode/CodeBlock.h 2015-12-18 21:52:07 UTC (rev 194293)
+++ trunk/Source/_javascript_Core/bytecode/CodeBlock.h 2015-12-18 22:03:30 UTC (rev 194294)
@@ -452,25 +452,22 @@
return value >= Options::couldTakeSlowCaseMinimumCount();
}
- RareCaseProfile* addSpecialFastCaseProfile(int bytecodeOffset)
+ ResultProfile* addResultProfile(int bytecodeOffset)
{
- m_specialFastCaseProfiles.append(RareCaseProfile(bytecodeOffset));
- return &m_specialFastCaseProfiles.last();
+ m_resultProfiles.append(ResultProfile(bytecodeOffset));
+ return &m_resultProfiles.last();
}
- unsigned numberOfSpecialFastCaseProfiles() { return m_specialFastCaseProfiles.size(); }
- RareCaseProfile* specialFastCaseProfile(int index) { return &m_specialFastCaseProfiles[index]; }
- RareCaseProfile* specialFastCaseProfileForBytecodeOffset(int bytecodeOffset)
- {
- return tryBinarySearch<RareCaseProfile, int>(
- m_specialFastCaseProfiles, m_specialFastCaseProfiles.size(), bytecodeOffset,
- getRareCaseProfileBytecodeOffset);
- }
+ unsigned numberOfResultProfiles() { return m_resultProfiles.size(); }
+ ResultProfile* resultProfileForBytecodeOffset(int bytecodeOffset);
+
+ void updateResultProfileForBytecodeOffset(int bytecodeOffset, JSValue result);
+
unsigned specialFastCaseProfileCountForBytecodeOffset(int bytecodeOffset)
{
- RareCaseProfile* profile = ""
+ ResultProfile* profile = ""
if (!profile)
return 0;
- return profile->m_counter;
+ return profile->specialFastPathCount();
}
bool couldTakeSpecialFastCase(int bytecodeOffset)
@@ -994,7 +991,8 @@
void dumpValueProfiling(PrintStream&, const Instruction*&, bool& hasPrintedProfiling);
void dumpArrayProfiling(PrintStream&, const Instruction*&, bool& hasPrintedProfiling);
void dumpRareCaseProfile(PrintStream&, const char* name, RareCaseProfile*, bool& hasPrintedProfiling);
-
+ void dumpResultProfile(PrintStream&, ResultProfile*, bool& hasPrintedProfiling);
+
bool shouldVisitStrongly();
bool shouldJettisonDueToWeakReference();
bool shouldJettisonDueToOldAge();
@@ -1069,7 +1067,7 @@
Vector<ValueProfile> m_argumentValueProfiles;
Vector<ValueProfile> m_valueProfiles;
SegmentedVector<RareCaseProfile, 8> m_rareCaseProfiles;
- SegmentedVector<RareCaseProfile, 8> m_specialFastCaseProfiles;
+ SegmentedVector<ResultProfile, 8> m_resultProfiles;
Vector<ArrayAllocationProfile> m_arrayAllocationProfiles;
ArrayProfileVector m_arrayProfiles;
Vector<ObjectAllocationProfile> m_objectAllocationProfiles;
Added: trunk/Source/_javascript_Core/bytecode/ValueProfile.cpp (0 => 194294)
--- trunk/Source/_javascript_Core/bytecode/ValueProfile.cpp (rev 0)
+++ trunk/Source/_javascript_Core/bytecode/ValueProfile.cpp 2015-12-18 22:03:30 UTC (rev 194294)
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2015 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 "ValueProfile.h"
+
+namespace WTF {
+
+using namespace JSC;
+
+void printInternal(PrintStream& out, const ResultProfile& profile)
+{
+ const char* separator = "";
+
+ if (!profile.didObserveNonInt32()) {
+ out.print("Int32");
+ separator = "|";
+ } else {
+ if (profile.didObserveNegZeroDouble()) {
+ out.print(separator, "NegZeroDouble");
+ separator = "|";
+ }
+ if (profile.didObserveNonNegZeroDouble()) {
+ out.print("NonNegZeroDouble");
+ separator = "|";
+ }
+ if (profile.didObserveNonNumber()) {
+ out.print("NonNumber");
+ separator = "|";
+ }
+ if (profile.didObserveInt32Overflow()) {
+ out.print("Int32Overflow");
+ separator = "|";
+ }
+ }
+ if (profile.specialFastPathCount()) {
+ out.print(" special fast path: ");
+ out.print(profile.specialFastPathCount());
+ }
+}
+
+} // namespace WTF
Modified: trunk/Source/_javascript_Core/bytecode/ValueProfile.h (194293 => 194294)
--- trunk/Source/_javascript_Core/bytecode/ValueProfile.h 2015-12-18 21:52:07 UTC (rev 194293)
+++ trunk/Source/_javascript_Core/bytecode/ValueProfile.h 2015-12-18 22:03:30 UTC (rev 194294)
@@ -206,7 +206,62 @@
return rareCaseProfile->m_bytecodeOffset;
}
+struct ResultProfile {
+private:
+ static const int numberOfFlagBits = 4;
+
+public:
+ ResultProfile(int bytecodeOffset)
+ : m_bytecodeOffsetAndFlags(bytecodeOffset << numberOfFlagBits)
+ {
+ ASSERT(((bytecodeOffset << numberOfFlagBits) >> numberOfFlagBits) == bytecodeOffset);
+ }
+
+ enum ObservedResults {
+ NonNegZeroDouble = 1 << 0,
+ NegZeroDouble = 1 << 1,
+ NonNumber = 1 << 2,
+ Int32Overflow = 1 << 3,
+ };
+
+ int bytecodeOffset() const { return m_bytecodeOffsetAndFlags >> numberOfFlagBits; }
+ unsigned specialFastPathCount() const { return m_specialFastPathCount; }
+
+ bool didObserveNonInt32() const { return hasBits(NonNegZeroDouble | NegZeroDouble | NonNumber); }
+ bool didObserveDouble() const { return hasBits(NonNegZeroDouble | NegZeroDouble); }
+ bool didObserveNonNegZeroDouble() const { return hasBits(NonNegZeroDouble); }
+ bool didObserveNegZeroDouble() const { return hasBits(NegZeroDouble); }
+ bool didObserveNonNumber() const { return hasBits(NonNumber); }
+ bool didObserveInt32Overflow() const { return hasBits(Int32Overflow); }
+
+ void setObservedNonNegZeroDouble() { setBit(NonNegZeroDouble); }
+ void setObservedNegZeroDouble() { setBit(NegZeroDouble); }
+ void setObservedNonNumber() { setBit(NonNumber); }
+ void setObservedInt32Overflow() { setBit(Int32Overflow); }
+
+ void* addressOfFlags() { return &m_bytecodeOffsetAndFlags; }
+ void* addressOfSpecialFastPathCount() { return &m_specialFastPathCount; }
+
+private:
+ bool hasBits(int mask) const { return m_bytecodeOffsetAndFlags & mask; }
+ void setBit(int mask) { m_bytecodeOffsetAndFlags |= mask; }
+
+ int m_bytecodeOffsetAndFlags;
+ unsigned m_specialFastPathCount { 0 };
+};
+
+inline int getResultProfileBytecodeOffset(ResultProfile* profile)
+{
+ return profile->bytecodeOffset();
+}
+
} // namespace JSC
+namespace WTF {
+
+void printInternal(PrintStream&, const JSC::ResultProfile&);
+
+} // namespace WTF
+
#endif // ValueProfile_h
Modified: trunk/Source/_javascript_Core/jit/JITArithmetic.cpp (194293 => 194294)
--- trunk/Source/_javascript_Core/jit/JITArithmetic.cpp 2015-12-18 21:52:07 UTC (rev 194293)
+++ trunk/Source/_javascript_Core/jit/JITArithmetic.cpp 2015-12-18 22:03:30 UTC (rev 194294)
@@ -755,7 +755,9 @@
#endif
FPRReg scratchFPR = fpRegT2;
- uint32_t* profilingCounter = &m_codeBlock->addSpecialFastCaseProfile(m_bytecodeOffset)->m_counter;
+ ResultProfile* resultProfile = nullptr;
+ if (shouldEmitProfiling())
+ resultProfile = m_codeBlock->addResultProfile(m_bytecodeOffset);
SnippetOperand leftOperand(types.first());
SnippetOperand rightOperand(types.second());
@@ -782,7 +784,7 @@
emitGetVirtualRegister(op2, rightRegs);
JITDivGenerator gen(leftOperand, rightOperand, resultRegs, leftRegs, rightRegs,
- fpRegT0, fpRegT1, scratchGPR, scratchFPR, profilingCounter);
+ fpRegT0, fpRegT1, scratchGPR, scratchFPR, resultProfile);
gen.generateFastPath(*this);
@@ -828,9 +830,9 @@
FPRReg scratchFPR = fpRegT2;
#endif
- uint32_t* profilingCounter = nullptr;
+ ResultProfile* resultProfile = nullptr;
if (shouldEmitProfiling())
- profilingCounter = &m_codeBlock->addSpecialFastCaseProfile(m_bytecodeOffset)->m_counter;
+ resultProfile = m_codeBlock->addResultProfile(m_bytecodeOffset);
SnippetOperand leftOperand(types.first());
SnippetOperand rightOperand(types.second());
@@ -848,7 +850,7 @@
emitGetVirtualRegister(op2, rightRegs);
JITMulGenerator gen(leftOperand, rightOperand, resultRegs, leftRegs, rightRegs,
- fpRegT0, fpRegT1, scratchGPR, scratchFPR, profilingCounter);
+ fpRegT0, fpRegT1, scratchGPR, scratchFPR, resultProfile);
gen.generateFastPath(*this);
Modified: trunk/Source/_javascript_Core/jit/JITDivGenerator.cpp (194293 => 194294)
--- trunk/Source/_javascript_Core/jit/JITDivGenerator.cpp 2015-12-18 21:52:07 UTC (rev 194293)
+++ trunk/Source/_javascript_Core/jit/JITDivGenerator.cpp 2015-12-18 22:03:30 UTC (rev 194294)
@@ -106,8 +106,8 @@
notDoubleZero.link(&jit);
#endif
- if (m_profilingCounter)
- jit.add32(CCallHelpers::TrustedImm32(1), CCallHelpers::AbsoluteAddress(m_profilingCounter));
+ if (m_resultProfile)
+ jit.add32(CCallHelpers::TrustedImm32(1), CCallHelpers::AbsoluteAddress(m_resultProfile->addressOfSpecialFastPathCount()));
jit.boxDouble(m_leftFPR, m_result);
}
Modified: trunk/Source/_javascript_Core/jit/JITDivGenerator.h (194293 => 194294)
--- trunk/Source/_javascript_Core/jit/JITDivGenerator.h 2015-12-18 21:52:07 UTC (rev 194293)
+++ trunk/Source/_javascript_Core/jit/JITDivGenerator.h 2015-12-18 22:03:30 UTC (rev 194294)
@@ -38,7 +38,7 @@
JITDivGenerator(SnippetOperand leftOperand, SnippetOperand rightOperand,
JSValueRegs result, JSValueRegs left, JSValueRegs right,
FPRReg leftFPR, FPRReg rightFPR, GPRReg scratchGPR, FPRReg scratchFPR,
- uint32_t* profilingCounter = nullptr)
+ ResultProfile* resultProfile = nullptr)
: m_leftOperand(leftOperand)
, m_rightOperand(rightOperand)
, m_result(result)
@@ -48,7 +48,7 @@
, m_rightFPR(rightFPR)
, m_scratchGPR(scratchGPR)
, m_scratchFPR(scratchFPR)
- , m_profilingCounter(profilingCounter)
+ , m_resultProfile(resultProfile)
{
ASSERT(!m_leftOperand.isConstInt32() || !m_rightOperand.isConstInt32());
}
@@ -71,7 +71,7 @@
FPRReg m_rightFPR;
GPRReg m_scratchGPR;
FPRReg m_scratchFPR;
- uint32_t* m_profilingCounter;
+ ResultProfile* m_resultProfile;
bool m_didEmitFastPath { false };
CCallHelpers::JumpList m_endJumpList;
Modified: trunk/Source/_javascript_Core/jit/JITMulGenerator.cpp (194293 => 194294)
--- trunk/Source/_javascript_Core/jit/JITMulGenerator.cpp 2015-12-18 21:52:07 UTC (rev 194293)
+++ trunk/Source/_javascript_Core/jit/JITMulGenerator.cpp 2015-12-18 22:03:30 UTC (rev 194294)
@@ -91,7 +91,7 @@
rightNotInt = jit.branchIfNotInt32(m_right);
m_slowPathJumpList.append(jit.branchMul32(CCallHelpers::Overflow, m_right.payloadGPR(), m_left.payloadGPR(), m_scratchGPR));
- if (!m_profilingCounter) {
+ if (!m_resultProfile) {
m_slowPathJumpList.append(jit.branchTest32(CCallHelpers::Zero, m_scratchGPR)); // Go slow if potential negative zero.
} else {
@@ -104,7 +104,7 @@
negativeZero.link(&jit);
// Record this, so that the speculative JIT knows that we failed speculation
// because of a negative zero.
- jit.add32(CCallHelpers::TrustedImm32(1), CCallHelpers::AbsoluteAddress(m_profilingCounter));
+ jit.add32(CCallHelpers::TrustedImm32(1), CCallHelpers::AbsoluteAddress(m_resultProfile->addressOfSpecialFastPathCount()));
m_slowPathJumpList.append(jit.jump());
notNegativeZero.link(&jit);
Modified: trunk/Source/_javascript_Core/jit/JITMulGenerator.h (194293 => 194294)
--- trunk/Source/_javascript_Core/jit/JITMulGenerator.h 2015-12-18 21:52:07 UTC (rev 194293)
+++ trunk/Source/_javascript_Core/jit/JITMulGenerator.h 2015-12-18 22:03:30 UTC (rev 194294)
@@ -37,7 +37,8 @@
public:
JITMulGenerator(SnippetOperand leftOperand, SnippetOperand rightOperand,
JSValueRegs result, JSValueRegs left, JSValueRegs right,
- FPRReg leftFPR, FPRReg rightFPR, GPRReg scratchGPR, FPRReg scratchFPR, uint32_t* profilingCounter = nullptr)
+ FPRReg leftFPR, FPRReg rightFPR, GPRReg scratchGPR, FPRReg scratchFPR,
+ ResultProfile* resultProfile = nullptr)
: m_leftOperand(leftOperand)
, m_rightOperand(rightOperand)
, m_result(result)
@@ -47,7 +48,7 @@
, m_rightFPR(rightFPR)
, m_scratchGPR(scratchGPR)
, m_scratchFPR(scratchFPR)
- , m_profilingCounter(profilingCounter)
+ , m_resultProfile(resultProfile)
{
ASSERT(!m_leftOperand.isPositiveConstInt32() || !m_rightOperand.isPositiveConstInt32());
}
@@ -68,7 +69,7 @@
FPRReg m_rightFPR;
GPRReg m_scratchGPR;
FPRReg m_scratchFPR;
- uint32_t* m_profilingCounter;
+ ResultProfile* m_resultProfile;
bool m_didEmitFastPath { false };
CCallHelpers::JumpList m_endJumpList;
Modified: trunk/Source/_javascript_Core/runtime/CommonSlowPaths.cpp (194293 => 194294)
--- trunk/Source/_javascript_Core/runtime/CommonSlowPaths.cpp 2015-12-18 21:52:07 UTC (rev 194293)
+++ trunk/Source/_javascript_Core/runtime/CommonSlowPaths.cpp 2015-12-18 22:03:30 UTC (rev 194294)
@@ -116,26 +116,34 @@
END_IMPL(); \
} while (false)
-#define RETURN(value) do { \
- JSValue rReturnValue = (value); \
- CHECK_EXCEPTION(); \
- OP(1) = rReturnValue; \
- END_IMPL(); \
+#define RETURN_WITH_PROFILING(value__, profilingAction__) do { \
+ JSValue returnValue__ = (value__); \
+ CHECK_EXCEPTION(); \
+ OP(1) = returnValue__; \
+ profilingAction__; \
+ END_IMPL(); \
} while (false)
-#define RETURN_PROFILED(opcode, value) do { \
- JSValue rpPeturnValue = (value); \
- CHECK_EXCEPTION(); \
- OP(1) = rpPeturnValue; \
- PROFILE_VALUE(opcode, rpPeturnValue); \
- END_IMPL(); \
- } while (false)
+#define RETURN(value) \
+ RETURN_WITH_PROFILING(value, { })
+#define RETURN_PROFILED(opcode__, value__) \
+ RETURN_WITH_PROFILING(value__, PROFILE_VALUE(opcode__, returnValue__))
+
#define PROFILE_VALUE(opcode, value) do { \
pc[OPCODE_LENGTH(opcode) - 1].u.profile->m_buckets[0] = \
JSValue::encode(value); \
} while (false)
+#define RETURN_WITH_RESULT_PROFILING(value__) \
+ RETURN_WITH_PROFILING(value__, PROFILE_RESULT(returnValue__))
+
+#define PROFILE_RESULT(value__) do { \
+ CodeBlock* codeBlock = exec->codeBlock(); \
+ unsigned bytecodeOffset = codeBlock->bytecodeOffset(pc); \
+ codeBlock->updateResultProfileForBytecodeOffset(bytecodeOffset, value__); \
+ } while (false)
+
#define CALL_END_IMPL(exec, callTarget) RETURN_TWO((callTarget), (exec))
#define CALL_THROW(exec, pc, exceptionToThrow) do { \
@@ -357,12 +365,12 @@
JSValue v2 = OP_C(3).jsValue();
if (v1.isString() && !v2.isObject())
- RETURN(jsString(exec, asString(v1), v2.toString(exec)));
+ RETURN_WITH_RESULT_PROFILING(jsString(exec, asString(v1), v2.toString(exec)));
if (v1.isNumber() && v2.isNumber())
- RETURN(jsNumber(v1.asNumber() + v2.asNumber()));
+ RETURN_WITH_RESULT_PROFILING(jsNumber(v1.asNumber() + v2.asNumber()));
- RETURN(jsAddSlowCase(exec, v1, v2));
+ RETURN_WITH_RESULT_PROFILING(jsAddSlowCase(exec, v1, v2));
}
// The following arithmetic and bitwise operations need to be sure to run
@@ -374,7 +382,7 @@
BEGIN();
double a = OP_C(2).jsValue().toNumber(exec);
double b = OP_C(3).jsValue().toNumber(exec);
- RETURN(jsNumber(a * b));
+ RETURN_WITH_RESULT_PROFILING(jsNumber(a * b));
}
SLOW_PATH_DECL(slow_path_sub)
@@ -382,7 +390,7 @@
BEGIN();
double a = OP_C(2).jsValue().toNumber(exec);
double b = OP_C(3).jsValue().toNumber(exec);
- RETURN(jsNumber(a - b));
+ RETURN_WITH_RESULT_PROFILING(jsNumber(a - b));
}
SLOW_PATH_DECL(slow_path_div)
@@ -390,7 +398,7 @@
BEGIN();
double a = OP_C(2).jsValue().toNumber(exec);
double b = OP_C(3).jsValue().toNumber(exec);
- RETURN(jsNumber(a / b));
+ RETURN_WITH_RESULT_PROFILING(jsNumber(a / b));
}
SLOW_PATH_DECL(slow_path_mod)