Diff
Modified: trunk/Source/_javascript_Core/ChangeLog (93697 => 93698)
--- trunk/Source/_javascript_Core/ChangeLog 2011-08-24 09:48:47 UTC (rev 93697)
+++ trunk/Source/_javascript_Core/ChangeLog 2011-08-24 09:50:40 UTC (rev 93698)
@@ -1,3 +1,60 @@
+2011-08-24 Filip Pizlo <fpi...@apple.com>
+
+ There is no facility for profiling how the write barrier is used
+ https://bugs.webkit.org/show_bug.cgi?id=66747
+
+ Reviewed by Geoffrey Garen.
+
+ Added facilities for the JIT to specify the kind of write barrier
+ being executed. Added code for profiling the number of each kind
+ of barrier encountered.
+
+ * GNUmakefile.list.am:
+ * _javascript_Core.exp:
+ * _javascript_Core.pro:
+ * _javascript_Core.vcproj/_javascript_Core/_javascript_Core.vcproj:
+ * _javascript_Core.xcodeproj/project.pbxproj:
+ * dfg/DFGJITCodeGenerator.cpp:
+ (JSC::DFG::JITCodeGenerator::writeBarrier):
+ (JSC::DFG::JITCodeGenerator::cachedPutById):
+ * dfg/DFGJITCodeGenerator.h:
+ * dfg/DFGJITCompiler.cpp:
+ (JSC::DFG::JITCompiler::emitCount):
+ * dfg/DFGJITCompiler.h:
+ (JSC::DFG::JITCompiler::emitCount):
+ * dfg/DFGNonSpeculativeJIT.cpp:
+ (JSC::DFG::NonSpeculativeJIT::compile):
+ * dfg/DFGRepatch.cpp:
+ (JSC::DFG::tryCachePutByID):
+ * dfg/DFGSpeculativeJIT.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+ * heap/Heap.h:
+ (JSC::Heap::writeBarrier):
+ * heap/WriteBarrierSupport.cpp: Added.
+ (JSC::WriteBarrierCounters::initialize):
+ * heap/WriteBarrierSupport.h: Added.
+ (JSC::WriteBarrierCounters::WriteBarrierCounters):
+ (JSC::WriteBarrierCounters::jitCounterFor):
+ (JSC::WriteBarrierCounters::countWriteBarrier):
+ * jit/JIT.h:
+ * jit/JITPropertyAccess.cpp:
+ (JSC::JIT::emit_op_put_by_id):
+ (JSC::JIT::privateCompilePutByIdTransition):
+ (JSC::JIT::emit_op_put_scoped_var):
+ (JSC::JIT::emit_op_put_global_var):
+ (JSC::JIT::emitWriteBarrier):
+ * jit/JITPropertyAccess32_64.cpp:
+ (JSC::JIT::emit_op_put_by_val):
+ (JSC::JIT::emit_op_put_by_id):
+ (JSC::JIT::privateCompilePutByIdTransition):
+ (JSC::JIT::emit_op_put_scoped_var):
+ (JSC::JIT::emit_op_put_global_var):
+ (JSC::JIT::emitWriteBarrier):
+ * runtime/InitializeThreading.cpp:
+ (JSC::initializeThreadingOnce):
+ * runtime/WriteBarrier.h:
+ (JSC::WriteBarrierBase::setWithoutWriteBarrier):
+
2011-08-23 Mark Hahnenberg <mhahnenb...@apple.com>
Add checks to ensure allocation does not take place during initialization of GC-managed objects
Modified: trunk/Source/_javascript_Core/GNUmakefile.list.am (93697 => 93698)
--- trunk/Source/_javascript_Core/GNUmakefile.list.am 2011-08-24 09:48:47 UTC (rev 93697)
+++ trunk/Source/_javascript_Core/GNUmakefile.list.am 2011-08-24 09:50:40 UTC (rev 93698)
@@ -150,6 +150,8 @@
Source/_javascript_Core/heap/OldSpace.h \
Source/_javascript_Core/heap/Strong.h \
Source/_javascript_Core/heap/Weak.h \
+ Source/_javascript_Core/heap/WriteBarrierSupport.cpp \
+ Source/_javascript_Core/heap/WriteBarrierSupport.h \
Source/_javascript_Core/config.h \
Source/_javascript_Core/debugger/DebuggerActivation.cpp \
Source/_javascript_Core/debugger/DebuggerActivation.h \
Modified: trunk/Source/_javascript_Core/_javascript_Core.exp (93697 => 93698)
--- trunk/Source/_javascript_Core/_javascript_Core.exp 2011-08-24 09:48:47 UTC (rev 93697)
+++ trunk/Source/_javascript_Core/_javascript_Core.exp 2011-08-24 09:50:40 UTC (rev 93698)
@@ -210,6 +210,8 @@
__ZN3JSC19initializeThreadingEv
__ZN3JSC20MarkedArgumentBuffer10slowAppendENS_7JSValueE
__ZN3JSC20createReferenceErrorEPNS_9ExecStateERKNS_7UStringE
+__ZN3JSC20WriteBarrierCounters22usesWithBarrierFromCppE
+__ZN3JSC20WriteBarrierCounters25usesWithoutBarrierFromCppE
__ZN3JSC22globalMemoryStatisticsEv
__ZN3JSC22objectConstructorTableE
__ZN3JSC23AbstractSamplingCounter4dumpEv
Modified: trunk/Source/_javascript_Core/_javascript_Core.pro (93697 => 93698)
--- trunk/Source/_javascript_Core/_javascript_Core.pro 2011-08-24 09:48:47 UTC (rev 93697)
+++ trunk/Source/_javascript_Core/_javascript_Core.pro 2011-08-24 09:50:40 UTC (rev 93698)
@@ -79,6 +79,7 @@
heap/MarkedBlock.cpp \
heap/NewSpace.cpp \
heap/OldSpace.cpp \
+ heap/WriteBarrierSupport.cpp \
debugger/DebuggerActivation.cpp \
debugger/DebuggerCallFrame.cpp \
debugger/Debugger.cpp \
Modified: trunk/Source/_javascript_Core/_javascript_Core.vcproj/_javascript_Core/_javascript_Core.vcproj (93697 => 93698)
--- trunk/Source/_javascript_Core/_javascript_Core.vcproj/_javascript_Core/_javascript_Core.vcproj 2011-08-24 09:48:47 UTC (rev 93697)
+++ trunk/Source/_javascript_Core/_javascript_Core.vcproj/_javascript_Core/_javascript_Core.vcproj 2011-08-24 09:50:40 UTC (rev 93698)
@@ -1969,6 +1969,14 @@
RelativePath="..\..\heap\Weak.h"
>
</File>
+ <File
+ RelativePath="..\..\heap\WriteBarrierSupport.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\heap\WriteBarrierSupport.h"
+ >
+ </File>
</Filter>
<File
RelativePath="..\..\config.h"
Modified: trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj (93697 => 93698)
--- trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj 2011-08-24 09:48:47 UTC (rev 93697)
+++ trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj 2011-08-24 09:50:40 UTC (rev 93698)
@@ -49,9 +49,11 @@
0BDFFAE10FC6193100D69EF4 /* OwnFastMallocPtr.h in Headers */ = {isa = PBXBuildFile; fileRef = 0BDFFAD10FC616EC00D69EF4 /* OwnFastMallocPtr.h */; settings = {ATTRIBUTES = (Private, ); }; };
0BF28A2911A33DC300638F84 /* SizeLimits.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0BF28A2811A33DC300638F84 /* SizeLimits.cpp */; };
0F29479C126E698C00B3ABF5 /* DecimalNumber.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F29479B126E698C00B3ABF5 /* DecimalNumber.cpp */; };
- 0F7700901402FDE40078EB39 /* SamplingCounter.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F77008E1402FDD60078EB39 /* SamplingCounter.h */; };
+ 0F7700901402FDE40078EB39 /* SamplingCounter.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F77008E1402FDD60078EB39 /* SamplingCounter.h */; settings = {ATTRIBUTES = (Private, ); }; };
0F7700921402FF3C0078EB39 /* SamplingCounter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F7700911402FF280078EB39 /* SamplingCounter.cpp */; };
0F963B3813FC6FE90002D9B2 /* ValueProfile.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F963B3613FC6FDE0002D9B2 /* ValueProfile.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 0FC8150A14043BF500CFA603 /* WriteBarrierSupport.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FC8150914043BD200CFA603 /* WriteBarrierSupport.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 0FC8150B14043C0E00CFA603 /* WriteBarrierSupport.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FC8150814043BCA00CFA603 /* WriteBarrierSupport.cpp */; };
1400067712A6F7830064D123 /* OSAllocator.h in Headers */ = {isa = PBXBuildFile; fileRef = 1400067612A6F7830064D123 /* OSAllocator.h */; settings = {ATTRIBUTES = (Private, ); }; };
1400069312A6F9E10064D123 /* OSAllocatorPosix.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1400069212A6F9E10064D123 /* OSAllocatorPosix.cpp */; };
140566C4107EC255005DBC8D /* JSAPIValueWrapper.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC0894D50FAFBA2D00001865 /* JSAPIValueWrapper.cpp */; };
@@ -735,6 +737,8 @@
0F77008E1402FDD60078EB39 /* SamplingCounter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SamplingCounter.h; sourceTree = "<group>"; };
0F7700911402FF280078EB39 /* SamplingCounter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SamplingCounter.cpp; sourceTree = "<group>"; };
0F963B3613FC6FDE0002D9B2 /* ValueProfile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ValueProfile.h; sourceTree = "<group>"; };
+ 0FC8150814043BCA00CFA603 /* WriteBarrierSupport.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WriteBarrierSupport.cpp; sourceTree = "<group>"; };
+ 0FC8150914043BD200CFA603 /* WriteBarrierSupport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WriteBarrierSupport.h; sourceTree = "<group>"; };
1400067612A6F7830064D123 /* OSAllocator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OSAllocator.h; sourceTree = "<group>"; };
1400069212A6F9E10064D123 /* OSAllocatorPosix.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OSAllocatorPosix.cpp; sourceTree = "<group>"; };
140D17D60E8AD4A9000CD17D /* JSBasePrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSBasePrivate.h; sourceTree = "<group>"; };
@@ -1505,6 +1509,8 @@
142E312A134FF0A600AFADB5 /* heap */ = {
isa = PBXGroup;
children = (
+ 0FC8150914043BD200CFA603 /* WriteBarrierSupport.h */,
+ 0FC8150814043BCA00CFA603 /* WriteBarrierSupport.cpp */,
146B14DB12EB5B12001BEC1B /* ConservativeRoots.cpp */,
149DAAF212EB559D0083B12B /* ConservativeRoots.h */,
142E312B134FF0A600AFADB5 /* Handle.h */,
@@ -2239,6 +2245,7 @@
86D3B2C410156BDE002865E7 /* ARMAssembler.h in Headers */,
86ADD1450FDDEA980006EEC2 /* ARMv7Assembler.h in Headers */,
BC18C3E60E16F5CD00B34460 /* ArrayConstructor.h in Headers */,
+ 0FC8150A14043BF500CFA603 /* WriteBarrierSupport.h in Headers */,
0F963B3813FC6FE90002D9B2 /* ValueProfile.h in Headers */,
BC18C3E70E16F5CD00B34460 /* ArrayPrototype.h in Headers */,
BC18C5240E16FC8A00B34460 /* ArrayPrototype.lut.h in Headers */,
@@ -2848,6 +2855,7 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
+ 0FC8150B14043C0E00CFA603 /* WriteBarrierSupport.cpp in Sources */,
0F7700921402FF3C0078EB39 /* SamplingCounter.cpp in Sources */,
147F39BD107EC37600427A48 /* ArgList.cpp in Sources */,
147F39BE107EC37600427A48 /* Arguments.cpp in Sources */,
Modified: trunk/Source/_javascript_Core/dfg/DFGJITCodeGenerator.cpp (93697 => 93698)
--- trunk/Source/_javascript_Core/dfg/DFGJITCodeGenerator.cpp 2011-08-24 09:48:47 UTC (rev 93697)
+++ trunk/Source/_javascript_Core/dfg/DFGJITCodeGenerator.cpp 2011-08-24 09:50:40 UTC (rev 93698)
@@ -465,11 +465,17 @@
return functionCall;
}
-void JITCodeGenerator::writeBarrier(MacroAssembler&, GPRReg owner, GPRReg scratch)
+void JITCodeGenerator::writeBarrier(MacroAssembler& jit, GPRReg owner, GPRReg scratch, WriteBarrierUseKind useKind)
{
+ UNUSED_PARAM(jit);
UNUSED_PARAM(owner);
UNUSED_PARAM(scratch);
+ UNUSED_PARAM(useKind);
ASSERT(owner != scratch);
+
+#if ENABLE(WRITE_BARRIER_PROFILING)
+ JITCompiler::emitCount(jit, WriteBarrierCounters::jitCounterFor(useKind));
+#endif
}
void JITCodeGenerator::cachedPutById(GPRReg baseGPR, GPRReg valueGPR, GPRReg scratchGPR, unsigned identifierNumber, PutKind putKind, JITCompiler::Jump slowPathTarget)
@@ -477,7 +483,7 @@
JITCompiler::DataLabelPtr structureToCompare;
JITCompiler::Jump structureCheck = m_jit.branchPtrWithPatch(JITCompiler::NotEqual, JITCompiler::Address(baseGPR, JSCell::structureOffset()), structureToCompare, JITCompiler::TrustedImmPtr(reinterpret_cast<void*>(-1)));
- writeBarrier(m_jit, baseGPR, scratchGPR);
+ writeBarrier(m_jit, baseGPR, scratchGPR, WriteBarrierForPropertyAccess);
m_jit.loadPtr(JITCompiler::Address(baseGPR, JSObject::offsetOfPropertyStorage()), scratchGPR);
JITCompiler::DataLabel32 storeWithPatch = m_jit.storePtrWithAddressOffsetPatch(valueGPR, JITCompiler::Address(scratchGPR, 0));
Modified: trunk/Source/_javascript_Core/dfg/DFGJITCodeGenerator.h (93697 => 93698)
--- trunk/Source/_javascript_Core/dfg/DFGJITCodeGenerator.h 2011-08-24 09:48:47 UTC (rev 93697)
+++ trunk/Source/_javascript_Core/dfg/DFGJITCodeGenerator.h 2011-08-24 09:50:40 UTC (rev 93698)
@@ -176,7 +176,7 @@
m_gprs.release(info.gpr());
}
- static void writeBarrier(MacroAssembler&, GPRReg ownerGPR, GPRReg scratchGPR);
+ static void writeBarrier(MacroAssembler&, GPRReg ownerGPR, GPRReg scratchGPR, WriteBarrierUseKind);
static GPRReg selectScratchGPR(GPRReg preserve1 = InvalidGPRReg, GPRReg preserve2 = InvalidGPRReg, GPRReg preserve3 = InvalidGPRReg)
{
Modified: trunk/Source/_javascript_Core/dfg/DFGJITCompiler.cpp (93697 => 93698)
--- trunk/Source/_javascript_Core/dfg/DFGJITCompiler.cpp 2011-08-24 09:48:47 UTC (rev 93697)
+++ trunk/Source/_javascript_Core/dfg/DFGJITCompiler.cpp 2011-08-24 09:50:40 UTC (rev 93698)
@@ -1041,18 +1041,18 @@
#endif
#if ENABLE(SAMPLING_COUNTERS) && CPU(X86_64) // Or any other 64-bit platform!
-void JITCompiler::emitCount(AbstractSamplingCounter& counter, uint32_t increment)
+void JITCompiler::emitCount(MacroAssembler& jit, AbstractSamplingCounter& counter, uint32_t increment)
{
- addPtr(TrustedImm32(increment), AbsoluteAddress(counter.addressOfCounter()));
+ jit.addPtr(TrustedImm32(increment), AbsoluteAddress(counter.addressOfCounter()));
}
#endif
#if ENABLE(SAMPLING_COUNTERS) && CPU(X86) // Or any other little-endian 32-bit platform!
-void JITCompiler::emitCount(AbstractSamplingCounter& counter, uint32_t increment)
+void JITCompiler::emitCount(MacroAsembler& jit, AbstractSamplingCounter& counter, uint32_t increment)
{
intptr_t hiWord = reinterpret_cast<intptr_t>(counter.addressOfCounter()) + sizeof(int32_t);
- add32(TrustedImm32(increment), AbsoluteAddress(counter.addressOfCounter()));
- addWithCarry32(TrustedImm32(0), AbsoluteAddress(reinterpret_cast<void*>(hiWord)));
+ jit.add32(TrustedImm32(increment), AbsoluteAddress(counter.addressOfCounter()));
+ jit.addWithCarry32(TrustedImm32(0), AbsoluteAddress(reinterpret_cast<void*>(hiWord)));
}
#endif
Modified: trunk/Source/_javascript_Core/dfg/DFGJITCompiler.h (93697 => 93698)
--- trunk/Source/_javascript_Core/dfg/DFGJITCompiler.h 2011-08-24 09:48:47 UTC (rev 93697)
+++ trunk/Source/_javascript_Core/dfg/DFGJITCompiler.h 2011-08-24 09:50:40 UTC (rev 93698)
@@ -273,7 +273,11 @@
#if ENABLE(SAMPLING_COUNTERS)
// Debug profiling tool.
- void emitCount(AbstractSamplingCounter&, uint32_t increment = 1);
+ static void emitCount(MacroAssembler&, AbstractSamplingCounter&, uint32_t increment = 1);
+ void emitCount(AbstractSamplingCounter& counter, uint32_t increment = 1)
+ {
+ emitCount(*this, counter, increment);
+ }
#endif
#if ENABLE(SAMPLING_FLAGS)
Modified: trunk/Source/_javascript_Core/dfg/DFGNonSpeculativeJIT.cpp (93697 => 93698)
--- trunk/Source/_javascript_Core/dfg/DFGNonSpeculativeJIT.cpp 2011-08-24 09:48:47 UTC (rev 93697)
+++ trunk/Source/_javascript_Core/dfg/DFGNonSpeculativeJIT.cpp 2011-08-24 09:50:40 UTC (rev 93698)
@@ -903,7 +903,7 @@
property.use();
value.use();
- writeBarrier(m_jit, baseGPR, storageGPR);
+ writeBarrier(m_jit, baseGPR, storageGPR, WriteBarrierForPropertyAccess);
JITCompiler::Jump baseNotCell = m_jit.branchTestPtr(MacroAssembler::NonZero, baseGPR, GPRInfo::tagMaskRegister);
@@ -1050,7 +1050,7 @@
m_jit.move(MacroAssembler::TrustedImmPtr(m_jit.codeBlock()->globalObject()), globalObjectReg);
- writeBarrier(m_jit, globalObjectReg, scratchReg);
+ writeBarrier(m_jit, globalObjectReg, scratchReg, WriteBarrierForVariableAccess);
m_jit.loadPtr(MacroAssembler::Address(globalObjectReg, JSVariableObject::offsetOfRegisters()), scratchReg);
m_jit.storePtr(value.gpr(), JITCompiler::addressForGlobalVar(scratchReg, node.varNumber()));
Modified: trunk/Source/_javascript_Core/dfg/DFGRepatch.cpp (93697 => 93698)
--- trunk/Source/_javascript_Core/dfg/DFGRepatch.cpp 2011-08-24 09:48:47 UTC (rev 93697)
+++ trunk/Source/_javascript_Core/dfg/DFGRepatch.cpp 2011-08-24 09:50:40 UTC (rev 93698)
@@ -525,7 +525,7 @@
testPrototype(stubJit, scratchGPR, (*it)->storedPrototype(), failureCases);
}
- JITCodeGenerator::writeBarrier(stubJit, baseGPR, scratchGPR);
+ JITCodeGenerator::writeBarrier(stubJit, baseGPR, scratchGPR, WriteBarrierForPropertyAccess);
stubJit.storePtr(MacroAssembler::TrustedImmPtr(structure), MacroAssembler::Address(baseGPR, JSCell::structureOffset()));
if (structure->isUsingInlineStorage())
Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp (93697 => 93698)
--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp 2011-08-24 09:48:47 UTC (rev 93697)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp 2011-08-24 09:50:40 UTC (rev 93698)
@@ -945,7 +945,7 @@
if (!m_compileOkay)
return;
- writeBarrier(m_jit, baseReg, scratchReg);
+ writeBarrier(m_jit, baseReg, scratchReg, WriteBarrierForPropertyAccess);
// Check that base is an array, and that property is contained within m_vector (< m_vectorLength).
// If we have predicted the base to be type array, we can skip the check.
@@ -1004,7 +1004,7 @@
GPRReg baseReg = base.gpr();
GPRReg scratchReg = scratch.gpr();
- writeBarrier(m_jit, baseReg, scratchReg);
+ writeBarrier(m_jit, baseReg, scratchReg, WriteBarrierForPropertyAccess);
// Get the array storage.
GPRReg storageReg = scratchReg;
@@ -1165,7 +1165,7 @@
m_jit.move(MacroAssembler::TrustedImmPtr(m_jit.codeBlock()->globalObject()), globalObjectReg);
- writeBarrier(m_jit, globalObjectReg, scratchReg);
+ writeBarrier(m_jit, globalObjectReg, scratchReg, WriteBarrierForVariableAccess);
m_jit.loadPtr(MacroAssembler::Address(globalObjectReg, JSVariableObject::offsetOfRegisters()), scratchReg);
m_jit.storePtr(value.gpr(), JITCompiler::addressForGlobalVar(scratchReg, node.varNumber()));
Modified: trunk/Source/_javascript_Core/heap/Heap.h (93697 => 93698)
--- trunk/Source/_javascript_Core/heap/Heap.h 2011-08-24 09:48:47 UTC (rev 93697)
+++ trunk/Source/_javascript_Core/heap/Heap.h 2011-08-24 09:50:40 UTC (rev 93698)
@@ -28,6 +28,7 @@
#include "MarkedBlockSet.h"
#include "NewSpace.h"
#include "SlotVisitor.h"
+#include "WriteBarrierSupport.h"
#include <wtf/Forward.h>
#include <wtf/HashCountedSet.h>
#include <wtf/HashSet.h>
@@ -129,6 +130,10 @@
static const size_t maxExtraCost = 1024 * 1024;
enum AllocationEffort { AllocationMustSucceed, AllocationCanFail };
+
+#if ENABLE(GGC)
+ static void writeBarrierFastCase(const JSCell* owner, JSCell*);
+#endif
bool isValidAllocation(size_t);
void reportExtraMemoryCostSlowCase(size_t);
@@ -236,30 +241,38 @@
}
#if ENABLE(GGC)
- inline void Heap::writeBarrier(const JSCell* owner, JSCell* cell)
+ inline void Heap::writeBarrierFastCase(const JSCell* owner, JSCell* cell)
{
if (MarkedBlock::blockFor(owner)->inNewSpace())
return;
writeBarrierSlowCase(owner, cell);
}
+ inline void Heap::writeBarrier(const JSCell* owner, JSCell* cell)
+ {
+ WriteBarrierCounters::countWriteBarrier();
+ writeBarrierFastCase(owner, cell);
+ }
+
inline void Heap::writeBarrier(const JSCell* owner, JSValue value)
{
+ WriteBarrierCounters::countWriteBarrier();
if (!value)
return;
if (!value.isCell())
return;
- writeBarrier(owner, value.asCell());
+ writeBarrierFastCase(owner, value.asCell());
}
-
#else
inline void Heap::writeBarrier(const JSCell*, JSCell*)
{
+ WriteBarrierCounters::countWriteBarrier();
}
inline void Heap::writeBarrier(const JSCell*, JSValue)
{
+ WriteBarrierCounters::countWriteBarrier();
}
#endif
Added: trunk/Source/_javascript_Core/heap/WriteBarrierSupport.cpp (0 => 93698)
--- trunk/Source/_javascript_Core/heap/WriteBarrierSupport.cpp (rev 0)
+++ trunk/Source/_javascript_Core/heap/WriteBarrierSupport.cpp 2011-08-24 09:50:40 UTC (rev 93698)
@@ -0,0 +1,54 @@
+/*
+ * 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. AND ITS CONTRIBUTORS ``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 ITS 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 "WriteBarrierSupport.h"
+
+namespace JSC {
+
+#if ENABLE(WRITE_BARRIER_PROFILING)
+GlobalSamplingCounter WriteBarrierCounters::usesWithBarrierFromCpp;
+GlobalSamplingCounter WriteBarrierCounters::usesWithoutBarrierFromCpp;
+GlobalSamplingCounter WriteBarrierCounters::usesWithBarrierFromJit;
+GlobalSamplingCounter WriteBarrierCounters::usesForPropertiesFromJit;
+GlobalSamplingCounter WriteBarrierCounters::usesForVariablesFromJit;
+GlobalSamplingCounter WriteBarrierCounters::usesWithoutBarrierFromJit;
+
+void WriteBarrierCounters::initialize()
+{
+ usesWithBarrierFromCpp.name("WithBarrierFromCpp");
+ usesWithoutBarrierFromCpp.name("WithoutBarrierFromCpp");
+ usesWithBarrierFromJit.name("WithBarrierFromJit");
+ usesForPropertiesFromJit.name("WriteForPropertiesFromJit");
+ usesForVariablesFromJit.name("WriteForVariablesFromJit");
+ usesWithoutBarrierFromJit.name("WithoutBarrierFromJit");
+}
+#else
+char WriteBarrierCounters::usesWithBarrierFromCpp;
+char WriteBarrierCounters::usesWithoutBarrierFromCpp;
+#endif
+
+} // namespace JSC
+
Added: trunk/Source/_javascript_Core/heap/WriteBarrierSupport.h (0 => 93698)
--- trunk/Source/_javascript_Core/heap/WriteBarrierSupport.h (rev 0)
+++ trunk/Source/_javascript_Core/heap/WriteBarrierSupport.h 2011-08-24 09:50:40 UTC (rev 93698)
@@ -0,0 +1,99 @@
+/*
+ * 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. AND ITS CONTRIBUTORS ``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 ITS 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 WriteBarrierSupport_h
+#define WriteBarrierSupport_h
+
+#include "SamplingCounter.h"
+#include <wtf/Assertions.h>
+
+namespace JSC {
+
+// This allows the JIT to distinguish between uses of the barrier for different
+// kinds of writes. This is used by the JIT for profiling, and may be appropriate
+// for allowing the GC implementation to specialize the JIT's write barrier code
+// for different kinds of target objects.
+enum WriteBarrierUseKind {
+ // This allows specialization for access to the property storage (either
+ // array element or property), but not for any other kind of property
+ // accesses (such as writes that are a consequence of setter execution).
+ WriteBarrierForPropertyAccess,
+
+ // This allows specialization for variable accesses (such as global or
+ // scoped variables).
+ WriteBarrierForVariableAccess,
+
+ // This captures all other forms of write barriers. It should always be
+ // correct to use a generic access write barrier, even when storing to
+ // properties. Hence, if optimization is not necessary, it is preferable
+ // to just use a generic access.
+ WriteBarrierForGenericAccess
+};
+
+class WriteBarrierCounters {
+private:
+ WriteBarrierCounters() { }
+
+public:
+#if ENABLE(WRITE_BARRIER_PROFILING)
+ static GlobalSamplingCounter usesWithBarrierFromCpp;
+ static GlobalSamplingCounter usesWithoutBarrierFromCpp;
+ static GlobalSamplingCounter usesWithBarrierFromJit;
+ static GlobalSamplingCounter usesForPropertiesFromJit;
+ static GlobalSamplingCounter usesForVariablesFromJit;
+ static GlobalSamplingCounter usesWithoutBarrierFromJit;
+
+ static void initialize();
+
+ static GlobalSamplingCounter& jitCounterFor(WriteBarrierUseKind useKind)
+ {
+ switch (useKind) {
+ case WriteBarrierForPropertyAccess:
+ return usesForPropertiesFromJit;
+ case WriteBarrierForVariableAccess:
+ return usesForVariablesFromJit;
+ default:
+ ASSERT(useKind == WriteBarrierForGenericAccess);
+ return usesWithBarrierFromJit;
+ }
+ }
+#else
+ // These are necessary to work around not having conditional exports.
+ static char usesWithBarrierFromCpp;
+ static char usesWithoutBarrierFromCpp;
+#endif // ENABLE(WRITE_BARRIER_PROFILING)
+
+ static void countWriteBarrier()
+ {
+#if ENABLE(WRITE_BARRIER_PROFILING)
+ WriteBarrierCounters::usesWithBarrierFromCpp.count();
+#endif
+ }
+};
+
+} // namespace JSC
+
+#endif // WriteBarrierSupport_h
+
Modified: trunk/Source/_javascript_Core/jit/JIT.h (93697 => 93698)
--- trunk/Source/_javascript_Core/jit/JIT.h 2011-08-24 09:48:47 UTC (rev 93697)
+++ trunk/Source/_javascript_Core/jit/JIT.h 2011-08-24 09:50:40 UTC (rev 93698)
@@ -299,7 +299,7 @@
void testPrototype(JSValue, JumpList& failureCases);
- void emitWriteBarrier(RegisterID owner, RegisterID scratch);
+ void emitWriteBarrier(RegisterID owner, RegisterID scratch, WriteBarrierUseKind);
template<typename ClassType, typename StructureType> void emitAllocateBasicJSObject(StructureType, void* vtable, RegisterID result, RegisterID storagePtr);
template<typename T> void emitAllocateJSFinalObject(T structure, RegisterID result, RegisterID storagePtr);
Modified: trunk/Source/_javascript_Core/jit/JITPropertyAccess.cpp (93697 => 93698)
--- trunk/Source/_javascript_Core/jit/JITPropertyAccess.cpp 2011-08-24 09:48:47 UTC (rev 93697)
+++ trunk/Source/_javascript_Core/jit/JITPropertyAccess.cpp 2011-08-24 09:50:40 UTC (rev 93698)
@@ -438,7 +438,7 @@
// Jump to a slow case if either the base object is an immediate, or if the Structure does not match.
emitJumpSlowCaseIfNotJSCell(regT0, baseVReg);
- emitWriteBarrier(regT0, regT2);
+ emitWriteBarrier(regT0, regT2, WriteBarrierForPropertyAccess);
BEGIN_UNINTERRUPTED_SEQUENCE(sequencePutById);
@@ -543,7 +543,7 @@
restoreReturnAddressBeforeReturn(regT3);
}
- emitWriteBarrier(regT0, regT2);
+ emitWriteBarrier(regT0, regT2, WriteBarrierForPropertyAccess);
storePtr(TrustedImmPtr(newStructure), Address(regT0, JSCell::structureOffset()));
compilePutDirectOffset(regT0, regT1, newStructure, cachedOffset);
@@ -996,7 +996,7 @@
loadPtr(Address(regT1, OBJECT_OFFSETOF(ScopeChainNode, next)), regT1);
loadPtr(Address(regT1, OBJECT_OFFSETOF(ScopeChainNode, object)), regT1);
- emitWriteBarrier(regT1, regT2);
+ emitWriteBarrier(regT1, regT2, WriteBarrierForVariableAccess);
loadPtr(Address(regT1, JSVariableObject::offsetOfRegisters()), regT1);
storePtr(regT0, Address(regT1, currentInstruction[1].u.operand * sizeof(Register)));
@@ -1017,17 +1017,22 @@
emitGetVirtualRegister(currentInstruction[2].u.operand, regT0);
move(TrustedImmPtr(globalObject), regT1);
- emitWriteBarrier(regT1, regT2);
+ emitWriteBarrier(regT1, regT2, WriteBarrierForVariableAccess);
loadPtr(Address(regT1, JSVariableObject::offsetOfRegisters()), regT1);
storePtr(regT0, Address(regT1, currentInstruction[1].u.operand * sizeof(Register)));
}
-void JIT::emitWriteBarrier(RegisterID owner, RegisterID scratch)
+void JIT::emitWriteBarrier(RegisterID owner, RegisterID scratch, WriteBarrierUseKind useKind)
{
UNUSED_PARAM(owner);
UNUSED_PARAM(scratch);
+ UNUSED_PARAM(useKind);
ASSERT(owner != scratch);
+
+#if ENABLE(WRITE_BARRIER_PROFILING)
+ emitCount(WriteBarrierCounters::jitCounterFor(useKind));
+#endif
}
#endif // USE(JSVALUE64)
Modified: trunk/Source/_javascript_Core/jit/JITPropertyAccess32_64.cpp (93697 => 93698)
--- trunk/Source/_javascript_Core/jit/JITPropertyAccess32_64.cpp 2011-08-24 09:48:47 UTC (rev 93697)
+++ trunk/Source/_javascript_Core/jit/JITPropertyAccess32_64.cpp 2011-08-24 09:50:40 UTC (rev 93698)
@@ -259,7 +259,7 @@
addSlowCase(branch32(NotEqual, regT3, TrustedImm32(JSValue::Int32Tag)));
emitJumpSlowCaseIfNotJSCell(base, regT1);
- emitWriteBarrier(regT0, regT1);
+ emitWriteBarrier(regT0, regT1, WriteBarrierForPropertyAccess);
addSlowCase(branchPtr(NotEqual, Address(regT0), TrustedImmPtr(m_globalData->jsArrayVPtr)));
addSlowCase(branch32(AboveOrEqual, regT2, Address(regT0, JSArray::vectorLengthOffset())));
@@ -395,7 +395,7 @@
emitJumpSlowCaseIfNotJSCell(base, regT1);
- emitWriteBarrier(regT0, regT1);
+ emitWriteBarrier(regT0, regT1, WriteBarrierForPropertyAccess);
BEGIN_UNINTERRUPTED_SEQUENCE(sequencePutById);
@@ -521,7 +521,7 @@
#endif
}
- emitWriteBarrier(regT0, regT1);
+ emitWriteBarrier(regT0, regT1, WriteBarrierForPropertyAccess);
storePtr(TrustedImmPtr(newStructure), Address(regT0, JSCell::structureOffset()));
#if CPU(MIPS) || CPU(SH4) || CPU(ARM)
@@ -1051,7 +1051,7 @@
loadPtr(Address(regT2, OBJECT_OFFSETOF(ScopeChainNode, next)), regT2);
loadPtr(Address(regT2, OBJECT_OFFSETOF(ScopeChainNode, object)), regT2);
- emitWriteBarrier(regT2, regT3);
+ emitWriteBarrier(regT2, regT3, WriteBarrierForVariableAccess);
loadPtr(Address(regT2, JSVariableObject::offsetOfRegisters()), regT2);
emitStore(index, regT1, regT0, regT2);
@@ -1082,18 +1082,23 @@
emitLoad(value, regT1, regT0);
move(TrustedImmPtr(globalObject), regT2);
- emitWriteBarrier(regT2, regT3);
+ emitWriteBarrier(regT2, regT3, WriteBarrierForVariableAccess);
loadPtr(Address(regT2, JSVariableObject::offsetOfRegisters()), regT2);
emitStore(index, regT1, regT0, regT2);
map(m_bytecodeOffset + OPCODE_LENGTH(op_put_global_var), value, regT1, regT0);
}
-void JIT::emitWriteBarrier(RegisterID owner, RegisterID scratch)
+void JIT::emitWriteBarrier(RegisterID owner, RegisterID scratch, WriteBarrierUseKind useKind)
{
UNUSED_PARAM(owner);
UNUSED_PARAM(scratch);
+ UNUSED_PARAM(useKind);
ASSERT(owner != scratch);
+
+#if ENABLE(WRITE_BARRIER_PROFILING)
+ emitCount(WriteBarrierCounters::jitCounterFor(useKind));
+#endif
}
} // namespace JSC
Modified: trunk/Source/_javascript_Core/runtime/InitializeThreading.cpp (93697 => 93698)
--- trunk/Source/_javascript_Core/runtime/InitializeThreading.cpp 2011-08-24 09:48:47 UTC (rev 93697)
+++ trunk/Source/_javascript_Core/runtime/InitializeThreading.cpp 2011-08-24 09:50:40 UTC (rev 93698)
@@ -34,6 +34,7 @@
#include "Identifier.h"
#include "JSGlobalObject.h"
#include "UString.h"
+#include "WriteBarrier.h"
#include <wtf/DateMath.h>
#include <wtf/Threading.h>
@@ -48,6 +49,9 @@
static void initializeThreadingOnce()
{
WTF::initializeThreading();
+#if ENABLE(WRITE_BARRIER_PROFILING)
+ WriteBarrierCounters::initialize();
+#endif
JSGlobalData::storeVPtrs();
#if ENABLE(JSC_MULTIPLE_THREADS)
RegisterFile::initializeThreading();
Modified: trunk/Source/_javascript_Core/runtime/WriteBarrier.h (93697 => 93698)
--- trunk/Source/_javascript_Core/runtime/WriteBarrier.h 2011-08-24 09:48:47 UTC (rev 93697)
+++ trunk/Source/_javascript_Core/runtime/WriteBarrier.h 2011-08-24 09:50:40 UTC (rev 93698)
@@ -28,6 +28,7 @@
#include "HandleTypes.h"
#include "Heap.h"
+#include "SamplingCounter.h"
#include "TypeTraits.h"
namespace JSC {
@@ -120,6 +121,9 @@
void setWithoutWriteBarrier(T* value)
{
+#if ENABLE(WRITE_BARRIER_PROFILING)
+ WriteBarrierCounters::usesWithoutBarrierFromCpp.count();
+#endif
this->m_cell = reinterpret_cast<JSCell*>(value);
}
Modified: trunk/Source/_javascript_Core/wtf/Platform.h (93697 => 93698)
--- trunk/Source/_javascript_Core/wtf/Platform.h 2011-08-24 09:48:47 UTC (rev 93697)
+++ trunk/Source/_javascript_Core/wtf/Platform.h 2011-08-24 09:50:40 UTC (rev 93698)
@@ -963,6 +963,12 @@
#define ENABLE_VERBOSE_VALUE_PROFILE 0
#endif
+/* Counts uses of write barriers using sampling counters. Be sure to also
+ set ENABLE_SAMPLING_COUNTERS to 1. */
+#if !defined(ENABLE_WRITE_BARRIER_PROFILING)
+#define ENABLE_WRITE_BARRIER_PROFILING 0
+#endif
+
/* Ensure that either the JIT or the interpreter has been enabled. */
#if !defined(ENABLE_INTERPRETER) && !ENABLE(JIT)
#define ENABLE_INTERPRETER 1