Diff
Modified: trunk/Source/_javascript_Core/ChangeLog (99373 => 99374)
--- trunk/Source/_javascript_Core/ChangeLog 2011-11-06 11:04:17 UTC (rev 99373)
+++ trunk/Source/_javascript_Core/ChangeLog 2011-11-06 11:39:12 UTC (rev 99374)
@@ -1,3 +1,60 @@
+2011-11-03 Filip Pizlo <[email protected]>
+
+ JSC should be able to sample itself in a more flexible way than just sampling flags
+ https://bugs.webkit.org/show_bug.cgi?id=71522
+
+ Reviewed by Gavin Barraclough.
+
+ Added a construct that looks like SamplingRegion samplingRegion("name").
+
+ * _javascript_Core.exp:
+ * _javascript_Core.xcodeproj/project.pbxproj:
+ * bytecode/SamplingTool.cpp:
+ (JSC::SamplingRegion::Locker::Locker):
+ (JSC::SamplingRegion::Locker::~Locker):
+ (JSC::SamplingRegion::sample):
+ (JSC::SamplingRegion::dump):
+ (JSC::SamplingRegion::dumpInternal):
+ (JSC::SamplingThread::threadStartFunc):
+ * bytecode/SamplingTool.h:
+ (JSC::SamplingRegion::SamplingRegion):
+ (JSC::SamplingRegion::~SamplingRegion):
+ (JSC::SamplingRegion::exchangeCurrent):
+ * bytecompiler/BytecodeGenerator.cpp:
+ (JSC::BytecodeGenerator::generate):
+ * dfg/DFGDriver.cpp:
+ (JSC::DFG::compile):
+ * heap/Heap.cpp:
+ (JSC::Heap::markRoots):
+ (JSC::Heap::collect):
+ * heap/VTableSpectrum.cpp:
+ (JSC::VTableSpectrum::countVPtr):
+ (JSC::VTableSpectrum::dump):
+ * heap/VTableSpectrum.h:
+ * jsc.cpp:
+ (main):
+ (runWithScripts):
+ * parser/Parser.h:
+ (JSC::parse):
+ * runtime/Executable.cpp:
+ (JSC::EvalExecutable::compileInternal):
+ (JSC::ProgramExecutable::compileInternal):
+ (JSC::FunctionExecutable::compileForCallInternal):
+ (JSC::FunctionExecutable::compileForConstructInternal):
+ * wtf/Atomics.h:
+ (WTF::weakCompareAndSwap):
+ * wtf/Platform.h:
+ * wtf/Spectrum.h: Added.
+ (WTF::Spectrum::Spectrum):
+ (WTF::Spectrum::add):
+ (WTF::Spectrum::get):
+ (WTF::Spectrum::begin):
+ (WTF::Spectrum::end):
+ (WTF::Spectrum::KeyAndCount::KeyAndCount):
+ (WTF::Spectrum::KeyAndCount::operator<):
+ (WTF::Spectrum::buildList):
+ * wtf/wtf.pri:
+
2011-11-05 Sam Weinig <[email protected]>
Fix windows build.
Modified: trunk/Source/_javascript_Core/_javascript_Core.exp (99373 => 99374)
--- trunk/Source/_javascript_Core/_javascript_Core.exp 2011-11-06 11:04:17 UTC (rev 99373)
+++ trunk/Source/_javascript_Core/_javascript_Core.exp 2011-11-06 11:39:12 UTC (rev 99374)
@@ -179,6 +179,7 @@
__ZN3JSC14JSGlobalObjectD2Ev
__ZN3JSC14MachineThreads16addCurrentThreadEv
__ZN3JSC14MarkStackArray6expandEv
+__ZN3JSC14SamplingRegion4dumpEv
__ZN3JSC14SamplingThread4stopEv
__ZN3JSC14SamplingThread5startEj
__ZN3JSC14ScopeChainNode6s_infoE
Modified: trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj (99373 => 99374)
--- trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj 2011-11-06 11:04:17 UTC (rev 99373)
+++ trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj 2011-11-06 11:39:12 UTC (rev 99374)
@@ -50,6 +50,7 @@
0BF28A2911A33DC300638F84 /* SizeLimits.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0BF28A2811A33DC300638F84 /* SizeLimits.cpp */; };
0F16D726142C39C000CF784A /* BitVector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F16D724142C39A200CF784A /* BitVector.cpp */; };
0F242DA713F3B1E8007ADD4C /* WeakReferenceHarvester.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F242DA513F3B1BB007ADD4C /* WeakReferenceHarvester.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 0F2E5BF7146357D5003EB2EB /* Spectrum.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F2E5BF5146357D2003EB2EB /* Spectrum.h */; settings = {ATTRIBUTES = (Private, ); }; };
0F426A481460CBB300131F8F /* ValueRecovery.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F426A451460CBAB00131F8F /* ValueRecovery.h */; settings = {ATTRIBUTES = (Private, ); }; };
0F426A491460CBB700131F8F /* VirtualRegister.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F426A461460CBAB00131F8F /* VirtualRegister.h */; settings = {ATTRIBUTES = (Private, ); }; };
0F426A4B1460CD6E00131F8F /* DataFormat.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F426A4A1460CD6B00131F8F /* DataFormat.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -813,6 +814,7 @@
0BF28A2811A33DC300638F84 /* SizeLimits.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SizeLimits.cpp; sourceTree = "<group>"; };
0F16D724142C39A200CF784A /* BitVector.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = BitVector.cpp; sourceTree = "<group>"; };
0F242DA513F3B1BB007ADD4C /* WeakReferenceHarvester.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WeakReferenceHarvester.h; sourceTree = "<group>"; };
+ 0F2E5BF5146357D2003EB2EB /* Spectrum.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Spectrum.h; sourceTree = "<group>"; };
0F426A451460CBAB00131F8F /* ValueRecovery.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ValueRecovery.h; sourceTree = "<group>"; };
0F426A461460CBAB00131F8F /* VirtualRegister.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VirtualRegister.h; sourceTree = "<group>"; };
0F426A4A1460CD6B00131F8F /* DataFormat.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DataFormat.h; sourceTree = "<group>"; };
@@ -1855,6 +1857,7 @@
65162EF108E6A21C007556CD /* wtf */ = {
isa = PBXGroup;
children = (
+ 0F2E5BF5146357D2003EB2EB /* Spectrum.h */,
0FD52AAC1430359D0026DC9F /* UnionFind.h */,
0F636D9F142D27D200B2E66A /* PackedIntVector.h */,
0F16D724142C39A200CF784A /* BitVector.cpp */,
@@ -2897,6 +2900,7 @@
0F426A481460CBB300131F8F /* ValueRecovery.h in Headers */,
0F426A491460CBB700131F8F /* VirtualRegister.h in Headers */,
0F426A4B1460CD6E00131F8F /* DataFormat.h in Headers */,
+ 0F2E5BF7146357D5003EB2EB /* Spectrum.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Modified: trunk/Source/_javascript_Core/bytecode/SamplingTool.cpp (99373 => 99374)
--- trunk/Source/_javascript_Core/bytecode/SamplingTool.cpp 2011-11-06 11:04:17 UTC (rev 99373)
+++ trunk/Source/_javascript_Core/bytecode/SamplingTool.cpp 2011-11-06 11:39:12 UTC (rev 99374)
@@ -83,6 +83,93 @@
void SamplingFlags::stop() {}
#endif
+#if ENABLE(SAMPLING_REGIONS)
+volatile uintptr_t SamplingRegion::s_currentOrReserved;
+Spectrum<const char*>* SamplingRegion::s_spectrum;
+unsigned long SamplingRegion::s_noneOfTheAbove;
+unsigned SamplingRegion::s_numberOfSamplesSinceDump;
+
+SamplingRegion::Locker::Locker()
+{
+ uintptr_t previous;
+ while (true) {
+ previous = s_currentOrReserved;
+ if (previous & 1) {
+#if OS(UNIX)
+ sched_yield();
+#endif
+ continue;
+ }
+ if (WTF::weakCompareAndSwap(&s_currentOrReserved, previous, previous | 1))
+ break;
+ }
+}
+
+SamplingRegion::Locker::~Locker()
+{
+ // We don't need the CAS, but we do it out of an
+ // abundance of caution (and because it gives us a memory fence, which is
+ // never bad).
+ uintptr_t previous;
+ do {
+ previous = s_currentOrReserved;
+ } while (!WTF::weakCompareAndSwap(&s_currentOrReserved, previous, previous & ~1));
+}
+
+void SamplingRegion::sample()
+{
+ // Make sure we lock s_current.
+ Locker locker;
+
+ // Create a spectrum if we don't have one already.
+ if (!s_spectrum)
+ s_spectrum = new Spectrum<const char*>();
+
+ ASSERT(s_currentOrReserved & 1);
+
+ // Walk the region stack, and record each region we see.
+ SamplingRegion* region = bitwise_cast<SamplingRegion*>(s_currentOrReserved & ~1);
+ if (region) {
+ for (; region; region = region->m_previous)
+ s_spectrum->add(region->m_name);
+ } else
+ s_noneOfTheAbove++;
+
+ if (s_numberOfSamplesSinceDump++ == SamplingThread::s_hertz) {
+ s_numberOfSamplesSinceDump = 0;
+ dumpInternal();
+ }
+}
+
+void SamplingRegion::dump()
+{
+ Locker locker;
+
+ dumpInternal();
+}
+
+void SamplingRegion::dumpInternal()
+{
+ if (!s_spectrum) {
+ printf("\nSamplingRegion: was never sampled.\n\n");
+ return;
+ }
+
+ Vector<Spectrum<const char*>::KeyAndCount> list = s_spectrum->buildList();
+
+ unsigned long total = s_noneOfTheAbove;
+ for (unsigned i = list.size(); i--;)
+ total += list[i].count;
+
+ printf("\nSamplingRegion: sample counts for regions: (%lu samples)\n", total);
+
+ for (unsigned i = list.size(); i--;)
+ printf(" %3.2lf%% %s\n", (100.0 * list[i].count) / total, list[i].key);
+}
+#else // ENABLE(SAMPLING_REGIONS)
+void SamplingRegion::dump() { }
+#endif // ENABLE(SAMPLING_REGIONS)
+
/*
Start with flag 16 set.
By doing this the monitoring of lower valued flags will be masked out
@@ -131,6 +218,9 @@
#if ENABLE(SAMPLING_FLAGS)
SamplingFlags::sample();
#endif
+#if ENABLE(SAMPLING_REGIONS)
+ SamplingRegion::sample();
+#endif
#if ENABLE(OPCODE_SAMPLING)
SamplingTool::sample();
#endif
Modified: trunk/Source/_javascript_Core/bytecode/SamplingTool.h (99373 => 99374)
--- trunk/Source/_javascript_Core/bytecode/SamplingTool.h 2011-11-06 11:04:17 UTC (rev 99373)
+++ trunk/Source/_javascript_Core/bytecode/SamplingTool.h 2011-11-06 11:39:12 UTC (rev 99374)
@@ -34,7 +34,9 @@
#include "Opcode.h"
#include "SamplingCounter.h"
#include <wtf/Assertions.h>
+#include <wtf/Atomics.h>
#include <wtf/HashMap.h>
+#include <wtf/MainThread.h>
#include <wtf/Threading.h>
namespace JSC {
@@ -93,6 +95,89 @@
#endif
};
+#if ENABLE(SAMPLING_REGIONS)
+ class SamplingRegion {
+ public:
+ // Create a scoped sampling region using a C string constant name that describes
+ // what you are doing. This must be a string constant that persists for the
+ // lifetime of the process and is immutable.
+ SamplingRegion(const char* name)
+ {
+ if (!isMainThread()) {
+ m_name = 0;
+ return;
+ }
+
+ m_name = name;
+ exchangeCurrent(this, &m_previous);
+ ASSERT(!m_previous || m_previous > this);
+ }
+
+ ~SamplingRegion()
+ {
+ if (!m_name)
+ return;
+
+ ASSERT(bitwise_cast<SamplingRegion*>(s_currentOrReserved & ~1) == this);
+ exchangeCurrent(m_previous);
+ }
+
+ static void sample();
+
+ static void dump();
+
+ private:
+ const char* m_name;
+ SamplingRegion* m_previous;
+
+ static void exchangeCurrent(SamplingRegion* current, SamplingRegion** previousPtr = 0)
+ {
+ uintptr_t previous;
+ while (true) {
+ previous = s_currentOrReserved;
+
+ // If it's reserved (i.e. sampling thread is reading it), loop around.
+ if (previous & 1) {
+#if OS(UNIX)
+ sched_yield();
+#endif
+ continue;
+ }
+
+ // If we're going to CAS, then make sure previous is set.
+ if (previousPtr)
+ *previousPtr = bitwise_cast<SamplingRegion*>(previous);
+
+ if (WTF::weakCompareAndSwap(&s_currentOrReserved, previous, bitwise_cast<uintptr_t>(current)))
+ break;
+ }
+ }
+
+ static void dumpInternal();
+
+ class Locker {
+ public:
+ Locker();
+ ~Locker();
+ };
+
+ static volatile uintptr_t s_currentOrReserved;
+
+ // rely on identity hashing of string constants
+ static Spectrum<const char*>* s_spectrum;
+
+ static unsigned long s_noneOfTheAbove;
+
+ static unsigned s_numberOfSamplesSinceDump;
+ };
+#else // ENABLE(SAMPLING_REGIONS)
+ class SamplingRegion {
+ public:
+ SamplingRegion(const char*) { }
+ void dump();
+ };
+#endif // ENABLE(SAMPLING_REGIONS)
+
class CodeBlock;
class ExecState;
class Interpreter;
Modified: trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.cpp (99373 => 99374)
--- trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.cpp 2011-11-06 11:04:17 UTC (rev 99373)
+++ trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.cpp 2011-11-06 11:39:12 UTC (rev 99374)
@@ -140,6 +140,8 @@
JSObject* BytecodeGenerator::generate()
{
+ SamplingRegion samplingRegion("Bytecode Generation");
+
m_codeBlock->setThisRegister(m_thisRegister.index());
m_scopeNode->emitBytecode(*this);
Modified: trunk/Source/_javascript_Core/dfg/DFGDriver.cpp (99373 => 99374)
--- trunk/Source/_javascript_Core/dfg/DFGDriver.cpp 2011-11-06 11:04:17 UTC (rev 99373)
+++ trunk/Source/_javascript_Core/dfg/DFGDriver.cpp 2011-11-06 11:39:12 UTC (rev 99374)
@@ -37,6 +37,8 @@
enum CompileMode { CompileFunction, CompileOther };
inline bool compile(CompileMode compileMode, ExecState* exec, CodeBlock* codeBlock, JITCode& jitCode, MacroAssemblerCodePtr* jitCodeWithArityCheck)
{
+ SamplingRegion samplingRegion("DFG Compilation (Driver)");
+
JSGlobalData* globalData = &exec->globalData();
Graph dfg;
if (!parse(dfg, globalData, codeBlock))
Modified: trunk/Source/_javascript_Core/heap/Heap.cpp (99373 => 99374)
--- trunk/Source/_javascript_Core/heap/Heap.cpp 2011-11-06 11:04:17 UTC (rev 99373)
+++ trunk/Source/_javascript_Core/heap/Heap.cpp 2011-11-06 11:39:12 UTC (rev 99374)
@@ -553,6 +553,8 @@
void Heap::markRoots(bool fullGC)
{
+ SamplingRegion samplingRegion("Garbage Collection: Tracing");
+
COND_GCPHASE(fullGC, MarkFullRoots, MarkYoungRoots);
UNUSED_PARAM(fullGC);
ASSERT(isValidThreadState(m_globalData));
@@ -759,6 +761,8 @@
void Heap::collect(SweepToggle sweepToggle)
{
+ SamplingRegion samplingRegion("Garbage Collection");
+
GCPHASE(Collect);
ASSERT(globalData()->identifierTable == wtfThreadData().currentIdentifierTable());
ASSERT(m_isSafeToCollect);
@@ -792,6 +796,7 @@
}
if (sweepToggle == DoSweep) {
+ SamplingRegion samplingRegion("Garbage Collection: Sweeping");
GCPHASE(Sweeping);
sweep();
shrink();
Modified: trunk/Source/_javascript_Core/heap/VTableSpectrum.cpp (99373 => 99374)
--- trunk/Source/_javascript_Core/heap/VTableSpectrum.cpp 2011-11-06 11:04:17 UTC (rev 99373)
+++ trunk/Source/_javascript_Core/heap/VTableSpectrum.cpp 2011-11-06 11:39:12 UTC (rev 99374)
@@ -49,9 +49,7 @@
void VTableSpectrum::countVPtr(void* vTablePointer)
{
- std::pair<HashMap<void*, unsigned long>::iterator, bool> result = m_map.add(vTablePointer, 1);
- if (!result.second)
- result.first->second++;
+ add(vTablePointer);
}
void VTableSpectrum::count(JSCell* cell)
@@ -59,45 +57,17 @@
countVPtr(cell->vptr());
}
-struct VTableAndCount {
- void* vtable;
- unsigned long count;
-
- VTableAndCount() { }
-
- VTableAndCount(void* vtable, unsigned long count)
- : vtable(vtable)
- , count(count)
- {
- }
-
- bool operator<(const VTableAndCount& other) const
- {
- if (count != other.count)
- return count < other.count;
- return vtable > other.vtable; // this results in lower-addressed vtables being printed first
- }
-};
-
void VTableSpectrum::dump(FILE* output, const char* comment)
{
fprintf(output, "%s:\n", comment);
- HashMap<void*, unsigned long>::iterator begin = m_map.begin();
- HashMap<void*, unsigned long>::iterator end = m_map.end();
+ Vector<KeyAndCount> list = buildList();
- Vector<VTableAndCount, 0> list;
-
- for (HashMap<void*, unsigned long>::iterator iter = begin; iter != end; ++iter)
- list.append(VTableAndCount(iter->first, iter->second));
-
- std::sort(list.begin(), list.end());
-
for (size_t index = list.size(); index-- > 0;) {
- VTableAndCount item = list.at(index);
+ KeyAndCount item = list.at(index);
#if PLATFORM(MAC)
Dl_info info;
- if (dladdr(item.vtable, &info)) {
+ if (dladdr(item.key, &info)) {
char* findResult = strrchr(info.dli_fname, '/');
const char* strippedFileName;
@@ -106,11 +76,11 @@
else
strippedFileName = info.dli_fname;
- fprintf(output, " %s:%s(%p): %lu\n", strippedFileName, info.dli_sname, item.vtable, item.count);
+ fprintf(output, " %s:%s(%p): %lu\n", strippedFileName, info.dli_sname, item.key, item.count);
continue;
}
#endif
- fprintf(output, " %p: %lu\n", item.vtable, item.count);
+ fprintf(output, " %p: %lu\n", item.key, item.count);
}
fflush(output);
Modified: trunk/Source/_javascript_Core/heap/VTableSpectrum.h (99373 => 99374)
--- trunk/Source/_javascript_Core/heap/VTableSpectrum.h 2011-11-06 11:04:17 UTC (rev 99373)
+++ trunk/Source/_javascript_Core/heap/VTableSpectrum.h 2011-11-06 11:39:12 UTC (rev 99374)
@@ -27,13 +27,13 @@
#define VTableSpectrum_h
#include <stdio.h>
-#include <wtf/HashMap.h>
+#include <wtf/Spectrum.h>
namespace JSC {
class JSCell;
-class VTableSpectrum {
+class VTableSpectrum: Spectrum<void*> {
public:
VTableSpectrum();
~VTableSpectrum();
@@ -42,9 +42,6 @@
void count(JSCell*);
void dump(FILE* output, const char* comment);
-
-private:
- HashMap<void*, unsigned long> m_map;
};
} // namespace JSC
Modified: trunk/Source/_javascript_Core/jsc.cpp (99373 => 99374)
--- trunk/Source/_javascript_Core/jsc.cpp 2011-11-06 11:04:17 UTC (rev 99373)
+++ trunk/Source/_javascript_Core/jsc.cpp 2011-11-06 11:39:12 UTC (rev 99374)
@@ -31,6 +31,7 @@
#include "JSFunction.h"
#include "JSLock.h"
#include "JSString.h"
+#include "MainThread.h"
#include "SamplingTool.h"
#include <math.h>
#include <stdio.h>
@@ -404,6 +405,7 @@
#endif
// Initialize JSC before getting JSGlobalData.
+ WTF::initializeMainThread();
JSC::initializeThreading();
// We can't use destructors in the following code because it uses Windows
@@ -472,6 +474,9 @@
#if ENABLE(SAMPLING_FLAGS)
SamplingFlags::stop();
#endif
+#if ENABLE(SAMPLING_REGIONS)
+ SamplingRegion::dump();
+#endif
globalData.dumpSampleData(globalObject->globalExec());
#if ENABLE(SAMPLING_COUNTERS)
AbstractSamplingCounter::dump();
Modified: trunk/Source/_javascript_Core/parser/Parser.h (99373 => 99374)
--- trunk/Source/_javascript_Core/parser/Parser.h 2011-11-06 11:04:17 UTC (rev 99373)
+++ trunk/Source/_javascript_Core/parser/Parser.h 2011-11-06 11:39:12 UTC (rev 99374)
@@ -1029,6 +1029,7 @@
template <class ParsedNode>
PassRefPtr<ParsedNode> parse(JSGlobalData* globalData, JSGlobalObject* lexicalGlobalObject, const SourceCode& source, FunctionParameters* parameters, JSParserStrictness strictness, JSParserMode parserMode, Debugger* debugger, ExecState* execState, JSObject** exception)
{
+ SamplingRegion samplingRegion("Parsing");
Parser parser(globalData, source, parameters, strictness, parserMode);
return parser.parse<ParsedNode>(lexicalGlobalObject, debugger, execState, exception);
}
Modified: trunk/Source/_javascript_Core/runtime/Executable.cpp (99373 => 99374)
--- trunk/Source/_javascript_Core/runtime/Executable.cpp 2011-11-06 11:04:17 UTC (rev 99373)
+++ trunk/Source/_javascript_Core/runtime/Executable.cpp 2011-11-06 11:39:12 UTC (rev 99374)
@@ -148,6 +148,8 @@
JSObject* EvalExecutable::compileInternal(ExecState* exec, ScopeChainNode* scopeChainNode, JITCode::JITType jitType)
{
+ SamplingRegion samplingRegion(jitType == JITCode::BaselineJIT ? "Baseline Compilation (TOTAL)" : "DFG Compilation (TOTAL)");
+
#if !ENABLE(JIT)
UNUSED_PARAM(jitType);
#endif
@@ -280,6 +282,8 @@
JSObject* ProgramExecutable::compileInternal(ExecState* exec, ScopeChainNode* scopeChainNode, JITCode::JITType jitType)
{
+ SamplingRegion samplingRegion(jitType == JITCode::BaselineJIT ? "Baseline Compilation (TOTAL)" : "DFG Compilation (TOTAL)");
+
#if !ENABLE(JIT)
UNUSED_PARAM(jitType);
#endif
@@ -455,6 +459,8 @@
JSObject* FunctionExecutable::compileForCallInternal(ExecState* exec, ScopeChainNode* scopeChainNode, JITCode::JITType jitType)
{
+ SamplingRegion samplingRegion(jitType == JITCode::BaselineJIT ? "Baseline Compilation (TOTAL)" : "DFG Compilation (TOTAL)");
+
#if !ENABLE(JIT)
UNUSED_PARAM(exec);
UNUSED_PARAM(jitType);
@@ -515,6 +521,8 @@
JSObject* FunctionExecutable::compileForConstructInternal(ExecState* exec, ScopeChainNode* scopeChainNode, JITCode::JITType jitType)
{
+ SamplingRegion samplingRegion(jitType == JITCode::BaselineJIT ? "Baseline Compilation (TOTAL)" : "DFG Compilation (TOTAL)");
+
#if !ENABLE(JIT)
UNUSED_PARAM(jitType);
UNUSED_PARAM(exec);
Modified: trunk/Source/_javascript_Core/wtf/Atomics.h (99373 => 99374)
--- trunk/Source/_javascript_Core/wtf/Atomics.h 2011-11-06 11:04:17 UTC (rev 99373)
+++ trunk/Source/_javascript_Core/wtf/Atomics.h 2011-11-06 11:39:12 UTC (rev 99374)
@@ -126,7 +126,7 @@
asm volatile(
"lock; cmpxchgl %3, %2\n\t"
"sete %1"
- : "+a"(expected), "=r"(result), "+m"(*location)
+ : "+a"(expected), "=q"(result), "+m"(*location)
: "r"(newValue)
: "memory"
);
@@ -140,6 +140,38 @@
#endif
}
+inline bool weakCompareAndSwap(void*volatile* location, void* expected, void* newValue)
+{
+ // FIXME: Implement COMPARE_AND_SWAP on other architectures and compilers. Currently
+ // it only works on X86 or X86_64 with a GCC-style compiler.
+#if ENABLE(COMPARE_AND_SWAP)
+ bool result;
+ asm volatile(
+#if CPU(X86_64)
+ "lock; cmpxchgq %3, %2\n\t"
+#else
+ "lock; cmpxchgl %3, %2\n\t"
+#endif
+ "sete %1"
+ : "+a"(expected), "=q"(result), "+m"(*location)
+ : "r"(newValue)
+ : "memory"
+ );
+ return result;
+#else // ENABLE(COMPARE_AND_SWAP)
+ UNUSED_PARAM(location);
+ UNUSED_PARAM(expected);
+ UNUSED_PARAM(newValue);
+ CRASH();
+ return 0;
+#endif // ENABLE(COMPARE_AND_SWAP)
+}
+
+inline bool weakCompareAndSwap(volatile uintptr_t* location, uintptr_t expected, uintptr_t newValue)
+{
+ return weakCompareAndSwap(reinterpret_cast<void*volatile*>(location), reinterpret_cast<void*>(expected), reinterpret_cast<void*>(newValue));
+}
+
} // namespace WTF
#if USE(LOCKFREE_THREADSAFEREFCOUNTED)
Modified: trunk/Source/_javascript_Core/wtf/Platform.h (99373 => 99374)
--- trunk/Source/_javascript_Core/wtf/Platform.h 2011-11-06 11:04:17 UTC (rev 99373)
+++ trunk/Source/_javascript_Core/wtf/Platform.h 2011-11-06 11:39:12 UTC (rev 99374)
@@ -808,12 +808,13 @@
#define ENABLE_DEBUG_WITH_BREAKPOINT 0
#define ENABLE_SAMPLING_COUNTERS 0
#define ENABLE_SAMPLING_FLAGS 0
+#define ENABLE_SAMPLING_REGIONS 0
#define ENABLE_OPCODE_SAMPLING 0
#define ENABLE_CODEBLOCK_SAMPLING 0
#if ENABLE(CODEBLOCK_SAMPLING) && !ENABLE(OPCODE_SAMPLING)
#error "CODEBLOCK_SAMPLING requires OPCODE_SAMPLING"
#endif
-#if ENABLE(OPCODE_SAMPLING) || ENABLE(SAMPLING_FLAGS)
+#if ENABLE(OPCODE_SAMPLING) || ENABLE(SAMPLING_FLAGS) || ENABLE(SAMPLING_REGIONS)
#define ENABLE_SAMPLING_THREAD 1
#endif
Added: trunk/Source/_javascript_Core/wtf/Spectrum.h (0 => 99374)
--- trunk/Source/_javascript_Core/wtf/Spectrum.h (rev 0)
+++ trunk/Source/_javascript_Core/wtf/Spectrum.h 2011-11-06 11:39:12 UTC (rev 99374)
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2011 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 Spectrum_h
+#define Spectrum_h
+
+#include "HashMap.h"
+#include "Vector.h"
+#include <algorithm>
+
+namespace WTF {
+
+template<typename T>
+class Spectrum {
+public:
+ typedef typename HashMap<T, unsigned long>::iterator iterator;
+ typedef typename HashMap<T, unsigned long>::const_iterator const_iterator;
+
+ Spectrum() { }
+
+ void add(const T& key, unsigned long count = 1)
+ {
+ std::pair<iterator, bool> result = m_map.add(key, count);
+ if (!result.second)
+ result.first->second += count;
+ }
+
+ unsigned long get(const T& key) const
+ {
+ const_iterator iter = m_map.find(key);
+ if (iter == m_map.end())
+ return 0;
+ return iter->second;
+ }
+
+ iterator begin() { return m_map.begin(); }
+ iterator end() { return m_map.end(); }
+ const_iterator begin() const { return m_map.begin(); }
+ const_iterator end() const { return m_map.end(); }
+
+ struct KeyAndCount {
+ KeyAndCount() { }
+
+ KeyAndCount(const T& key, unsigned long count)
+ : key(key)
+ , count(count)
+ {
+ }
+
+ bool operator<(const KeyAndCount& other) const
+ {
+ if (count != other.count)
+ return count < other.count;
+ // This causes lower-ordered keys being returned first; this is really just
+ // here to make sure that the order is somewhat deterministic rather than being
+ // determined by hashing.
+ return key > other.key;
+ }
+
+ T key;
+ unsigned long count;
+ };
+
+ // Returns a list ordered from lowest-count to highest-count.
+ Vector<KeyAndCount> buildList() const
+ {
+ Vector<KeyAndCount> list;
+ for (const_iterator iter = begin(); iter != end(); ++iter)
+ list.append(KeyAndCount(iter->first, iter->second));
+
+ std::sort(list.begin(), list.end());
+ return list;
+ }
+
+private:
+ HashMap<T, unsigned long> m_map;
+};
+
+} // namespace WTF
+
+using WTF::Spectrum;
+
+#endif // Spectrum_h
Modified: trunk/Source/_javascript_Core/wtf/wtf.pri (99373 => 99374)
--- trunk/Source/_javascript_Core/wtf/wtf.pri 2011-11-06 11:04:17 UTC (rev 99373)
+++ trunk/Source/_javascript_Core/wtf/wtf.pri 2011-11-06 11:39:12 UTC (rev 99374)
@@ -97,6 +97,7 @@
wtf/RefPtrHashMap.h \
wtf/RetainPtr.h \
wtf/SHA1.h \
+ wtf/Spectrum.h \
wtf/StackBounds.h \
wtf/StaticConstructors.h \
wtf/StdLibExtras.h \
Modified: trunk/Source/_javascript_Glue/ChangeLog (99373 => 99374)
--- trunk/Source/_javascript_Glue/ChangeLog 2011-11-06 11:04:17 UTC (rev 99373)
+++ trunk/Source/_javascript_Glue/ChangeLog 2011-11-06 11:39:12 UTC (rev 99374)
@@ -1,3 +1,12 @@
+2011-11-03 Filip Pizlo <[email protected]>
+
+ JSC should be able to sample itself in a more flexible way than just sampling flags
+ https://bugs.webkit.org/show_bug.cgi?id=71522
+
+ Reviewed by Gavin Barraclough.
+
+ * ForwardingHeaders/wtf/Spectrum.h: Added.
+
2011-11-03 Mark Hahnenberg <[email protected]>
De-virtualize JSObject::getPropertyNames
Added: trunk/Source/_javascript_Glue/ForwardingHeaders/wtf/Spectrum.h (0 => 99374)
--- trunk/Source/_javascript_Glue/ForwardingHeaders/wtf/Spectrum.h (rev 0)
+++ trunk/Source/_javascript_Glue/ForwardingHeaders/wtf/Spectrum.h 2011-11-06 11:39:12 UTC (rev 99374)
@@ -0,0 +1 @@
+#include <_javascript_Core/Spectrum.h>
Modified: trunk/Source/WebCore/ChangeLog (99373 => 99374)
--- trunk/Source/WebCore/ChangeLog 2011-11-06 11:04:17 UTC (rev 99373)
+++ trunk/Source/WebCore/ChangeLog 2011-11-06 11:39:12 UTC (rev 99374)
@@ -1,3 +1,14 @@
+2011-11-03 Filip Pizlo <[email protected]>
+
+ JSC should be able to sample itself in a more flexible way than just sampling flags
+ https://bugs.webkit.org/show_bug.cgi?id=71522
+
+ Reviewed by Gavin Barraclough.
+
+ No new tests, since no functionality changed.
+
+ * ForwardingHeaders/wtf/Spectrum.h: Added.
+
2011-11-06 Nikita Vasilyev <[email protected]>
Web Inspector: Unindent edited text by pressing Shift + Tab
Added: trunk/Source/WebCore/ForwardingHeaders/wtf/Spectrum.h (0 => 99374)
--- trunk/Source/WebCore/ForwardingHeaders/wtf/Spectrum.h (rev 0)
+++ trunk/Source/WebCore/ForwardingHeaders/wtf/Spectrum.h 2011-11-06 11:39:12 UTC (rev 99374)
@@ -0,0 +1 @@
+#include <_javascript_Core/Spectrum.h>