Title: [93698] trunk/Source/_javascript_Core
Revision
93698
Author
fpi...@apple.com
Date
2011-08-24 02:50:40 -0700 (Wed, 24 Aug 2011)

Log Message

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):

Modified Paths

Added Paths

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
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to