Source/JavaScriptCore/ChangeLog

 12012-07-08 Filip Pizlo <fpizlo@apple.com>
 2
 3 It should be possible to jettison JIT stub routines even if they are currently running
 4 https://bugs.webkit.org/show_bug.cgi?id=90731
 5
 6 Reviewed by NOBODY (OOPS!).
 7
 8 This gives the GC awareness of all JIT-generated stubs for inline caches. That
 9 means that if you want to delete a JIT-generated stub, you don't have to worry
 10 about whether or not it is currently running: if there is a chance that it might
 11 be, the GC will kindly defer deletion until non-running-ness is proved.
 12
 13 * CMakeLists.txt:
 14 * GNUmakefile.list.am:
 15 * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
 16 * JavaScriptCore.xcodeproj/project.pbxproj:
 17 * Target.pri:
 18 * bytecode/Instruction.h:
 19 (JSC):
 20 (PolymorphicStubInfo):
 21 (JSC::PolymorphicAccessStructureList::PolymorphicStubInfo::set):
 22 (JSC::PolymorphicAccessStructureList::PolymorphicAccessStructureList):
 23 * bytecode/PolymorphicPutByIdList.cpp:
 24 (JSC::PutByIdAccess::fromStructureStubInfo):
 25 * bytecode/PolymorphicPutByIdList.h:
 26 (JSC::PutByIdAccess::transition):
 27 (JSC::PutByIdAccess::replace):
 28 (JSC::PutByIdAccess::stubRoutine):
 29 (PutByIdAccess):
 30 (JSC::PolymorphicPutByIdList::currentSlowPathTarget):
 31 * bytecode/StructureStubInfo.h:
 32 (JSC::StructureStubInfo::reset):
 33 * dfg/DFGRepatch.cpp:
 34 (JSC::DFG::generateProtoChainAccessStub):
 35 (JSC::DFG::tryCacheGetByID):
 36 (JSC::DFG::tryBuildGetByIDList):
 37 (JSC::DFG::tryBuildGetByIDProtoList):
 38 (JSC::DFG::emitPutReplaceStub):
 39 (JSC::DFG::emitPutTransitionStub):
 40 (JSC::DFG::tryCachePutByID):
 41 (JSC::DFG::tryBuildPutByIdList):
 42 * heap/ConservativeRoots.cpp:
 43 (JSC):
 44 (DummyMarkHook):
 45 (JSC::DummyMarkHook::mark):
 46 (JSC::ConservativeRoots::add):
 47 (CompositeMarkHook):
 48 (JSC::CompositeMarkHook::CompositeMarkHook):
 49 (JSC::CompositeMarkHook::mark):
 50 * heap/ConservativeRoots.h:
 51 (JSC):
 52 (ConservativeRoots):
 53 * heap/Heap.cpp:
 54 (JSC::Heap::markRoots):
 55 * heap/Heap.h:
 56 (JSC):
 57 (Heap):
 58 * heap/JITStubRoutineSet.cpp: Added.
 59 (JSC):
 60 (JSC::JITStubRoutineSet::JITStubRoutineSet):
 61 (JSC::JITStubRoutineSet::~JITStubRoutineSet):
 62 (JSC::JITStubRoutineSet::add):
 63 (JSC::JITStubRoutineSet::clearMarks):
 64 (JSC::JITStubRoutineSet::markSlow):
 65 (JSC::JITStubRoutineSet::deleteUnmarkedJettisonedStubRoutines):
 66 (JSC::JITStubRoutineSet::traceMarkedStubRoutines):
 67 * heap/JITStubRoutineSet.h: Added.
 68 (JSC):
 69 (JITStubRoutineSet):
 70 (JSC::JITStubRoutineSet::mark):
 71 * heap/MachineStackMarker.h:
 72 (JSC):
 73 * interpreter/RegisterFile.cpp:
 74 (JSC::RegisterFile::gatherConservativeRoots):
 75 * interpreter/RegisterFile.h:
 76 (JSC):
 77 * jit/ExecutableAllocator.cpp:
 78 (JSC::DemandExecutableAllocator::DemandExecutableAllocator):
 79 * jit/ExecutableAllocator.h:
 80 (JSC):
 81 * jit/ExecutableAllocatorFixedVMPool.cpp:
 82 (JSC):
 83 (JSC::FixedVMPoolExecutableAllocator::FixedVMPoolExecutableAllocator):
 84 * jit/GCAwareJITStubRoutine.cpp: Added.
 85 (JSC):
 86 (JSC::GCAwareJITStubRoutine::GCAwareJITStubRoutine):
 87 (JSC::GCAwareJITStubRoutine::~GCAwareJITStubRoutine):
 88 (JSC::GCAwareJITStubRoutine::observeZeroRefCount):
 89 (JSC::GCAwareJITStubRoutine::deleteFromGC):
 90 (JSC::GCAwareJITStubRoutine::markRequiredObjectsInternal):
 91 (JSC::MarkingGCAwareJITStubRoutineWithOneObject::MarkingGCAwareJITStubRoutineWithOneObject):
 92 (JSC::MarkingGCAwareJITStubRoutineWithOneObject::~MarkingGCAwareJITStubRoutineWithOneObject):
 93 (JSC::MarkingGCAwareJITStubRoutineWithOneObject::markRequiredObjectsInternal):
 94 (JSC::createJITStubRoutine):
 95 * jit/GCAwareJITStubRoutine.h: Added.
 96 (JSC):
 97 (GCAwareJITStubRoutine):
 98 (JSC::GCAwareJITStubRoutine::markRequiredObjects):
 99 (MarkingGCAwareJITStubRoutineWithOneObject):
 100 * jit/JITPropertyAccess.cpp:
 101 (JSC::JIT::privateCompilePutByIdTransition):
 102 (JSC::JIT::privateCompilePatchGetArrayLength):
 103 (JSC::JIT::privateCompileGetByIdProto):
 104 (JSC::JIT::privateCompileGetByIdSelfList):
 105 (JSC::JIT::privateCompileGetByIdProtoList):
 106 (JSC::JIT::privateCompileGetByIdChainList):
 107 (JSC::JIT::privateCompileGetByIdChain):
 108 * jit/JITPropertyAccess32_64.cpp:
 109 (JSC::JIT::privateCompilePutByIdTransition):
 110 (JSC::JIT::privateCompilePatchGetArrayLength):
 111 (JSC::JIT::privateCompileGetByIdProto):
 112 (JSC::JIT::privateCompileGetByIdSelfList):
 113 (JSC::JIT::privateCompileGetByIdProtoList):
 114 (JSC::JIT::privateCompileGetByIdChainList):
 115 (JSC::JIT::privateCompileGetByIdChain):
 116 * jit/JITStubRoutine.cpp: Added.
 117 (JSC):
 118 (JSC::JITStubRoutine::~JITStubRoutine):
 119 (JSC::JITStubRoutine::observeZeroRefCount):
 120 * jit/JITStubRoutine.h: Added.
 121 (JSC):
 122 (JITStubRoutine):
 123 (JSC::JITStubRoutine::JITStubRoutine):
 124 (JSC::JITStubRoutine::createSelfManagedRoutine):
 125 (JSC::JITStubRoutine::code):
 126 (JSC::JITStubRoutine::asCodePtr):
 127 (JSC::JITStubRoutine::ref):
 128 (JSC::JITStubRoutine::deref):
 129 (JSC::JITStubRoutine::startAddress):
 130 (JSC::JITStubRoutine::endAddress):
 131 (JSC::JITStubRoutine::addressStep):
 132 (JSC::JITStubRoutine::canPerformRangeFilter):
 133 (JSC::JITStubRoutine::filteringStartAddress):
 134 (JSC::JITStubRoutine::filteringExtentSize):
 135 (JSC::JITStubRoutine::passesFilter):
 136 * jit/JITStubs.cpp:
 137 (JSC::DEFINE_STUB_FUNCTION):
 138 (JSC::getPolymorphicAccessStructureListSlot):
 139
11402012-07-08 Zoltan Herczeg <zherczeg@webkit.org>
2141
3142 [Qt][ARM] Implementing missing macro assembler instructions after r121925
122069

Source/JavaScriptCore/CMakeLists.txt

@@SET(JavaScriptCore_SOURCES
109109 heap/Heap.cpp
110110 heap/HeapTimer.cpp
111111 heap/IncrementalSweeper.cpp
 112 heap/JITStubRoutineSet.cpp
112113 heap/MachineStackMarker.cpp
113114 heap/MarkedAllocator.cpp
114115 heap/MarkedBlock.cpp

@@SET(JavaScriptCore_SOURCES
129130
130131 jit/ExecutableAllocator.cpp
131132 jit/HostCallReturnValue.cpp
 133 jit/GCAwareJITStubRoutine.cpp
132134 jit/JITArithmetic32_64.cpp
133135 jit/JITArithmetic.cpp
134136 jit/JITCall32_64.cpp

@@SET(JavaScriptCore_SOURCES
139141 jit/JITOpcodes.cpp
140142 jit/JITPropertyAccess32_64.cpp
141143 jit/JITPropertyAccess.cpp
 144 jit/JITStubRoutine.cpp
142145 jit/JITStubs.cpp
143146 jit/ThunkGenerators.cpp
144147
122052

Source/JavaScriptCore/GNUmakefile.list.am

@@javascriptcore_sources += \
265265 Source/JavaScriptCore/heap/BlockAllocator.h \
266266 Source/JavaScriptCore/heap/Heap.cpp \
267267 Source/JavaScriptCore/heap/Heap.h \
 268 Source/JavaScriptCore/heap/JITStubRoutineSet.cpp \
 269 Source/JavaScriptCore/heap/JITStubRoutineSet.h \
268270 Source/JavaScriptCore/heap/ListableHandler.h \
269271 Source/JavaScriptCore/heap/Local.h \
270272 Source/JavaScriptCore/heap/LocalScope.h \

@@javascriptcore_sources += \
354356 Source/JavaScriptCore/jit/CompactJITCodeMap.h \
355357 Source/JavaScriptCore/jit/ExecutableAllocator.cpp \
356358 Source/JavaScriptCore/jit/ExecutableAllocator.h \
 359 Source/JavaScriptCore/jit/GCAwareJITStubRoutine.cpp \
 360 Source/JavaScriptCore/jit/GCAwareJITStubRoutine.h \
357361 Source/JavaScriptCore/jit/HostCallReturnValue.cpp \
358362 Source/JavaScriptCore/jit/HostCallReturnValue.h \
359363 Source/JavaScriptCore/jit/JITArithmetic32_64.cpp \

@@javascriptcore_sources += \
373377 Source/JavaScriptCore/jit/JITPropertyAccess32_64.cpp \
374378 Source/JavaScriptCore/jit/JITPropertyAccess.cpp \
375379 Source/JavaScriptCore/jit/JITStubCall.h \
 380 Source/JavaScriptCore/jit/JITStubRoutine.cpp \
 381 Source/JavaScriptCore/jit/JITStubRoutine.h \
376382 Source/JavaScriptCore/jit/JITStubs.cpp \
377383 Source/JavaScriptCore/jit/JITStubs.h \
378384 Source/JavaScriptCore/jit/JITWriteBarrier.h \
122052

Source/JavaScriptCore/Target.pri

@@SOURCES += \
8383 heap/Heap.cpp \
8484 heap/HeapTimer.cpp \
8585 heap/IncrementalSweeper.cpp \
 86 heap/JITStubRoutineSet.cpp \
8687 heap/MachineStackMarker.cpp \
8788 heap/MarkStack.cpp \
8889 heap/MarkedAllocator.cpp \

@@SOURCES += \
137138 jit/ExecutableAllocatorFixedVMPool.cpp \
138139 jit/ExecutableAllocator.cpp \
139140 jit/HostCallReturnValue.cpp \
 141 jit/GCAwareJITStubRoutine.cpp \
140142 jit/JITArithmetic.cpp \
141143 jit/JITArithmetic32_64.cpp \
142144 jit/JITCall.cpp \

@@SOURCES += \
147149 jit/JITOpcodes32_64.cpp \
148150 jit/JITPropertyAccess.cpp \
149151 jit/JITPropertyAccess32_64.cpp \
 152 jit/JITStubRoutine.cpp \
150153 jit/JITStubs.cpp \
151154 jit/ThunkGenerators.cpp \
152155 parser/Lexer.cpp \
122052

Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj

18581858 >
18591859 </File>
18601860 <File
 1861 RelativePath="..\..\jit\GCAwareJITStubRoutine.cpp"
 1862 >
 1863 </File>
 1864 <File
 1865 RelativePath="..\..\jit\GCAwareJITStubRoutine.h"
 1866 >
 1867 </File>
 1868 <File
18611869 RelativePath="..\..\jit\JIT.cpp"
18621870 >
18631871 </File>

19181926 >
19191927 </File>
19201928 <File
 1929 RelativePath="..\..\jit\JITStubRoutine.cpp"
 1930 >
 1931 </File>
 1932 <File
 1933 RelativePath="..\..\jit\JITStubRoutine.h"
 1934 >
 1935 </File>
 1936 <File
19211937 RelativePath="..\..\jit\JITStubs.cpp"
19221938 >
19231939 </File>

22142230 >
22152231 </File>
22162232 <File
 2233 RelativePath="..\..\heap\JITStubRoutineSet.cpp"
 2234 >
 2235 </File>
 2236 <File
 2237 RelativePath="..\..\heap\JITStubRoutineSet.h"
 2238 >
 2239 </File>
 2240 <File
22172241 RelativePath="..\..\heap\IncrementalSweeper.h"
22182242 >
22192243 </File>
122052

Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj

140140 0F620179143FCD480068B77C /* DFGAbstractState.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F62016D143FCD2F0068B77C /* DFGAbstractState.cpp */; };
141141 0F66E16B14DF3F1600B7B2E4 /* DFGAdjacencyList.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F66E16814DF3F1300B7B2E4 /* DFGAdjacencyList.h */; settings = {ATTRIBUTES = (Private, ); }; };
142142 0F66E16C14DF3F1600B7B2E4 /* DFGEdge.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F66E16914DF3F1300B7B2E4 /* DFGEdge.h */; settings = {ATTRIBUTES = (Private, ); }; };
 143 0F766D2815A8CC1E008F363E /* JITStubRoutine.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F766D2615A8CC1B008F363E /* JITStubRoutine.cpp */; };
 144 0F766D2B15A8CC38008F363E /* JITStubRoutineSet.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F766D2915A8CC34008F363E /* JITStubRoutineSet.cpp */; };
 145 0F766D2C15A8CC3A008F363E /* JITStubRoutineSet.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F766D2A15A8CC34008F363E /* JITStubRoutineSet.h */; settings = {ATTRIBUTES = (Private, ); }; };
 146 0F766D2F15A8DCE0008F363E /* GCAwareJITStubRoutine.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F766D2D15A8DCDD008F363E /* GCAwareJITStubRoutine.cpp */; };
 147 0F766D3015A8DCE2008F363E /* GCAwareJITStubRoutine.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F766D2E15A8DCDD008F363E /* GCAwareJITStubRoutine.h */; settings = {ATTRIBUTES = (Private, ); }; };
 148 0F766D3115AA8112008F363E /* JITStubRoutine.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F766D1C15A5028D008F363E /* JITStubRoutine.h */; settings = {ATTRIBUTES = (Private, ); }; };
143149 0F7700921402FF3C0078EB39 /* SamplingCounter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F7700911402FF280078EB39 /* SamplingCounter.cpp */; };
144150 0F7B294A14C3CD29007C3DB1 /* DFGCCallHelpers.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F7B294814C3CD23007C3DB1 /* DFGCCallHelpers.h */; settings = {ATTRIBUTES = (Private, ); }; };
145151 0F7B294B14C3CD2F007C3DB1 /* DFGCapabilities.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FD82E1F14172C2F00179C94 /* DFGCapabilities.h */; settings = {ATTRIBUTES = (Private, ); }; };

875881 0F620172143FCD2F0068B77C /* DFGVariableAccessData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGVariableAccessData.h; path = dfg/DFGVariableAccessData.h; sourceTree = "<group>"; };
876882 0F66E16814DF3F1300B7B2E4 /* DFGAdjacencyList.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGAdjacencyList.h; path = dfg/DFGAdjacencyList.h; sourceTree = "<group>"; };
877883 0F66E16914DF3F1300B7B2E4 /* DFGEdge.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGEdge.h; path = dfg/DFGEdge.h; sourceTree = "<group>"; };
 884 0F766D1C15A5028D008F363E /* JITStubRoutine.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JITStubRoutine.h; sourceTree = "<group>"; };
 885 0F766D2615A8CC1B008F363E /* JITStubRoutine.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JITStubRoutine.cpp; sourceTree = "<group>"; };
 886 0F766D2915A8CC34008F363E /* JITStubRoutineSet.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JITStubRoutineSet.cpp; sourceTree = "<group>"; };
 887 0F766D2A15A8CC34008F363E /* JITStubRoutineSet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JITStubRoutineSet.h; sourceTree = "<group>"; };
 888 0F766D2D15A8DCDD008F363E /* GCAwareJITStubRoutine.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GCAwareJITStubRoutine.cpp; sourceTree = "<group>"; };
 889 0F766D2E15A8DCDD008F363E /* GCAwareJITStubRoutine.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GCAwareJITStubRoutine.h; sourceTree = "<group>"; };
878890 0F77008E1402FDD60078EB39 /* SamplingCounter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SamplingCounter.h; sourceTree = "<group>"; };
879891 0F7700911402FF280078EB39 /* SamplingCounter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SamplingCounter.cpp; sourceTree = "<group>"; };
880892 0F7B294814C3CD23007C3DB1 /* DFGCCallHelpers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGCCallHelpers.h; path = dfg/DFGCCallHelpers.h; sourceTree = "<group>"; };

16921704 A7B48DB60EE74CFC00DCBDB6 /* ExecutableAllocator.cpp */,
16931705 A7B48DB50EE74CFC00DCBDB6 /* ExecutableAllocator.h */,
16941706 86DB64630F95C6FC00D7D921 /* ExecutableAllocatorFixedVMPool.cpp */,
 1707 0F766D2D15A8DCDD008F363E /* GCAwareJITStubRoutine.cpp */,
 1708 0F766D2E15A8DCDD008F363E /* GCAwareJITStubRoutine.h */,
16951709 0F4680D014BBC5F800BFE272 /* HostCallReturnValue.cpp */,
16961710 0F4680D114BBC5F800BFE272 /* HostCallReturnValue.h */,
16971711 1429D92D0ED22D7000B89619 /* JIT.cpp */,

17111725 86CC85C30EE7A89400288682 /* JITPropertyAccess.cpp */,
17121726 A7C1E8C8112E701C00A37F98 /* JITPropertyAccess32_64.cpp */,
17131727 960626950FB8EC02009798AB /* JITStubCall.h */,
 1728 0F766D2615A8CC1B008F363E /* JITStubRoutine.cpp */,
 1729 0F766D1C15A5028D008F363E /* JITStubRoutine.h */,
17141730 14A23D6C0F4E19CE0023CDAD /* JITStubs.cpp */,
17151731 14A6581A0F4E36F4000150FD /* JITStubs.h */,
17161732 A76F54A213B28AAB00EF2BCE /* JITWriteBarrier.h */,

17521768 14BA7A9613AADFF8005B7C2C /* Heap.h */,
17531769 C2C8D02F14A3CEFC00578E65 /* HeapBlock.h */,
17541770 14F97446138C853E00DA1C67 /* HeapRootVisitor.h */,
 1771 0F766D2915A8CC34008F363E /* JITStubRoutineSet.cpp */,
 1772 0F766D2A15A8CC34008F363E /* JITStubRoutineSet.h */,
17551773 0F431736146BAC65007E3890 /* ListableHandler.h */,
17561774 142E3130134FF0A600AFADB5 /* Local.h */,
17571775 142E3131134FF0A600AFADB5 /* LocalScope.h */,

28152833 0FF427651591A1CE004CB9FF /* DFGDisassembler.h in Headers */,
28162834 0FF42772159275D8004CB9FF /* ResolveGlobalStatus.h in Headers */,
28172835 0FF7168C15A3B235008F5DAA /* PropertyOffset.h in Headers */,
 2836 0F766D2C15A8CC3A008F363E /* JITStubRoutineSet.h in Headers */,
 2837 0F766D3015A8DCE2008F363E /* GCAwareJITStubRoutine.h in Headers */,
 2838 0F766D3115AA8112008F363E /* JITStubRoutine.h in Headers */,
28182839 );
28192840 runOnlyForDeploymentPostprocessing = 0;
28202841 };

34073428 C2D58C3415912FEE0021A844 /* GCActivityCallback.cpp in Sources */,
34083429 0FF427641591A1CC004CB9FF /* DFGDisassembler.cpp in Sources */,
34093430 0FF42771159275D5004CB9FF /* ResolveGlobalStatus.cpp in Sources */,
 3431 0F766D2815A8CC1E008F363E /* JITStubRoutine.cpp in Sources */,
 3432 0F766D2B15A8CC38008F363E /* JITStubRoutineSet.cpp in Sources */,
 3433 0F766D2F15A8DCE0008F363E /* GCAwareJITStubRoutine.cpp in Sources */,
34103434 );
34113435 runOnlyForDeploymentPostprocessing = 0;
34123436 };
122052

Source/JavaScriptCore/bytecode/Instruction.h

2929#ifndef Instruction_h
3030#define Instruction_h
3131
 32#include "JITStubRoutine.h"
3233#include "MacroAssembler.h"
3334#include "Opcode.h"
3435#include "PropertySlot.h"

@@namespace JSC {
5253 struct ValueProfile;
5354
5455#if ENABLE(JIT)
55  typedef MacroAssemblerCodeRef PolymorphicAccessStructureListStubRoutineType;
56 
5756 // Structure used by op_get_by_id_self_list and op_get_by_id_proto_list instruction to hold data off the main opcode stream.
5857 struct PolymorphicAccessStructureList {
5958 WTF_MAKE_FAST_ALLOCATED;

@@namespace JSC {
6160 struct PolymorphicStubInfo {
6261 bool isChain;
6362 bool isDirect;
64  PolymorphicAccessStructureListStubRoutineType stubRoutine;
 63 RefPtr<JITStubRoutine> stubRoutine;
6564 WriteBarrier<Structure> base;
6665 union {
6766 WriteBarrierBase<Structure> proto;

@@namespace JSC {
7372 u.proto.clear();
7473 }
7574
76  void set(JSGlobalData& globalData, JSCell* owner, PolymorphicAccessStructureListStubRoutineType _stubRoutine, Structure* _base, bool isDirect)
 75 void set(JSGlobalData& globalData, JSCell* owner, PassRefPtr<JITStubRoutine> _stubRoutine, Structure* _base, bool isDirect)
7776 {
7877 stubRoutine = _stubRoutine;
7978 base.set(globalData, owner, _base);

@@namespace JSC {
8281 this->isDirect = isDirect;
8382 }
8483
85  void set(JSGlobalData& globalData, JSCell* owner, PolymorphicAccessStructureListStubRoutineType _stubRoutine, Structure* _base, Structure* _proto, bool isDirect)
 84 void set(JSGlobalData& globalData, JSCell* owner, PassRefPtr<JITStubRoutine> _stubRoutine, Structure* _base, Structure* _proto, bool isDirect)
8685 {
8786 stubRoutine = _stubRoutine;
8887 base.set(globalData, owner, _base);

@@namespace JSC {
9190 this->isDirect = isDirect;
9291 }
9392
94  void set(JSGlobalData& globalData, JSCell* owner, PolymorphicAccessStructureListStubRoutineType _stubRoutine, Structure* _base, StructureChain* _chain, bool isDirect)
 93 void set(JSGlobalData& globalData, JSCell* owner, PassRefPtr<JITStubRoutine> _stubRoutine, Structure* _base, StructureChain* _chain, bool isDirect)
9594 {
9695 stubRoutine = _stubRoutine;
9796 base.set(globalData, owner, _base);

@@namespace JSC {
105104 {
106105 }
107106
108  PolymorphicAccessStructureList(JSGlobalData& globalData, JSCell* owner, PolymorphicAccessStructureListStubRoutineType stubRoutine, Structure* firstBase, bool isDirect)
 107 PolymorphicAccessStructureList(JSGlobalData& globalData, JSCell* owner, PassRefPtr<JITStubRoutine> stubRoutine, Structure* firstBase, bool isDirect)
109108 {
110109 list[0].set(globalData, owner, stubRoutine, firstBase, isDirect);
111110 }
112111
113  PolymorphicAccessStructureList(JSGlobalData& globalData, JSCell* owner, PolymorphicAccessStructureListStubRoutineType stubRoutine, Structure* firstBase, Structure* firstProto, bool isDirect)
 112 PolymorphicAccessStructureList(JSGlobalData& globalData, JSCell* owner, PassRefPtr<JITStubRoutine> stubRoutine, Structure* firstBase, Structure* firstProto, bool isDirect)
114113 {
115114 list[0].set(globalData, owner, stubRoutine, firstBase, firstProto, isDirect);
116115 }
117116
118  PolymorphicAccessStructureList(JSGlobalData& globalData, JSCell* owner, PolymorphicAccessStructureListStubRoutineType stubRoutine, Structure* firstBase, StructureChain* firstChain, bool isDirect)
 117 PolymorphicAccessStructureList(JSGlobalData& globalData, JSCell* owner, PassRefPtr<JITStubRoutine> stubRoutine, Structure* firstBase, StructureChain* firstChain, bool isDirect)
119118 {
120119 list[0].set(globalData, owner, stubRoutine, firstBase, firstChain, isDirect);
121120 }
122052

Source/JavaScriptCore/bytecode/PolymorphicPutByIdList.cpp

@@PutByIdAccess PutByIdAccess::fromStructu
4242 case access_put_by_id_replace:
4343 result.m_type = Replace;
4444 result.m_oldStructure.copyFrom(stubInfo.u.putByIdReplace.baseObjectStructure);
45  result.m_stubRoutine = MacroAssemblerCodeRef::createSelfManagedCodeRef(initialSlowPath);
 45 result.m_stubRoutine = JITStubRoutine::createSelfManagedRoutine(initialSlowPath);
4646 break;
4747
4848 case access_put_by_id_transition_direct:
122052

Source/JavaScriptCore/bytecode/PolymorphicPutByIdList.h

@@public:
6060 Structure* oldStructure,
6161 Structure* newStructure,
6262 StructureChain* chain,
63  MacroAssemblerCodeRef stubRoutine)
 63 PassRefPtr<JITStubRoutine> stubRoutine)
6464 {
6565 PutByIdAccess result;
6666 result.m_type = Transition;

@@public:
7575 JSGlobalData& globalData,
7676 JSCell* owner,
7777 Structure* structure,
78  MacroAssemblerCodeRef stubRoutine)
 78 PassRefPtr<JITStubRoutine> stubRoutine)
7979 {
8080 PutByIdAccess result;
8181 result.m_type = Replace;

@@public:
123123 return m_chain.get();
124124 }
125125
126  MacroAssemblerCodeRef stubRoutine() const
 126 PassRefPtr<JITStubRoutine> stubRoutine() const
127127 {
128128 ASSERT(isTransition() || isReplace());
129129 return m_stubRoutine;

@@private:
136136 WriteBarrier<Structure> m_oldStructure;
137137 WriteBarrier<Structure> m_newStructure;
138138 WriteBarrier<StructureChain> m_chain;
139  MacroAssemblerCodeRef m_stubRoutine;
 139 RefPtr<JITStubRoutine> m_stubRoutine;
140140};
141141
142142class PolymorphicPutByIdList {

@@public:
161161
162162 MacroAssemblerCodePtr currentSlowPathTarget() const
163163 {
164  return m_list.last().stubRoutine().code();
 164 return m_list.last().stubRoutine()->code().code();
165165 }
166166
167167 void addAccess(const PutByIdAccess&);
122052

Source/JavaScriptCore/bytecode/StructureStubInfo.h

3232
3333#include "CodeOrigin.h"
3434#include "Instruction.h"
 35#include "JITStubRoutine.h"
3536#include "MacroAssembler.h"
3637#include "Opcode.h"
3738#include "Structure.h"

@@namespace JSC {
168169 {
169170 deref();
170171 accessType = access_unset;
171  stubRoutine = MacroAssemblerCodeRef();
 172 stubRoutine.clear();
172173 }
173174
174175 void deref();

@@namespace JSC {
286287 } putByIdList;
287288 } u;
288289
289  MacroAssemblerCodeRef stubRoutine;
 290 RefPtr<JITStubRoutine> stubRoutine;
290291 CodeLocationCall callReturnLocation;
291292 CodeLocationLabel hotPathBegin;
292293 };
122052

Source/JavaScriptCore/dfg/DFGRepatch.cpp

3030
3131#include "DFGCCallHelpers.h"
3232#include "DFGSpeculativeJIT.h"
 33#include "GCAwareJITStubRoutine.h"
3334#include "LinkBuffer.h"
3435#include "Operations.h"
3536#include "PolymorphicPutByIdList.h"

@@static void linkRestoreScratch(LinkBuffe
106107 linkRestoreScratch(patchBuffer, needToRestoreScratch, success, fail, failureCases, stubInfo.callReturnLocation.labelAtOffset(stubInfo.patch.dfg.deltaCallToDone), stubInfo.callReturnLocation.labelAtOffset(stubInfo.patch.dfg.deltaCallToSlowCase));
107108}
108109
109 static void generateProtoChainAccessStub(ExecState* exec, StructureStubInfo& stubInfo, StructureChain* chain, size_t count, PropertyOffset offset, Structure* structure, CodeLocationLabel successLabel, CodeLocationLabel slowCaseLabel, MacroAssemblerCodeRef& stubRoutine)
 110static void generateProtoChainAccessStub(ExecState* exec, StructureStubInfo& stubInfo, StructureChain* chain, size_t count, PropertyOffset offset, Structure* structure, CodeLocationLabel successLabel, CodeLocationLabel slowCaseLabel, RefPtr<JITStubRoutine>& stubRoutine)
110111{
111112 JSGlobalData* globalData = &exec->globalData();
112113

@@static void generateProtoChainAccessStub
166167
167168 linkRestoreScratch(patchBuffer, needToRestoreScratch, success, fail, failureCases, successLabel, slowCaseLabel);
168169
169  stubRoutine = FINALIZE_CODE(
 170 stubRoutine = FINALIZE_CODE_FOR_STUB(
170171 patchBuffer,
171172 ("DFG prototype chain access stub for CodeBlock %p, return point %p",
172173 exec->codeBlock(), successLabel.executableAddress()));

@@static bool tryCacheGetByID(ExecState* e
220221
221222 linkRestoreScratch(patchBuffer, needToRestoreScratch, stubInfo, success, fail, failureCases);
222223
223  stubInfo.stubRoutine = FINALIZE_CODE(
 224 stubInfo.stubRoutine = FINALIZE_CODE_FOR_STUB(
224225 patchBuffer,
225226 ("DFG GetById array length stub for CodeBlock %p, return point %p",
226227 exec->codeBlock(), stubInfo.callReturnLocation.labelAtOffset(
227228 stubInfo.patch.dfg.deltaCallToDone).executableAddress()));
228229
229230 RepatchBuffer repatchBuffer(codeBlock);
230  repatchBuffer.relink(stubInfo.callReturnLocation.jumpAtOffset(stubInfo.patch.dfg.deltaCallToStructCheck), CodeLocationLabel(stubInfo.stubRoutine.code()));
 231 repatchBuffer.relink(stubInfo.callReturnLocation.jumpAtOffset(stubInfo.patch.dfg.deltaCallToStructCheck), CodeLocationLabel(stubInfo.stubRoutine->code().code()));
231232 repatchBuffer.relink(stubInfo.callReturnLocation, operationGetById);
232233
233234 return true;

@@static bool tryCacheGetByID(ExecState* e
276277 generateProtoChainAccessStub(exec, stubInfo, prototypeChain, count, offset, structure, stubInfo.callReturnLocation.labelAtOffset(stubInfo.patch.dfg.deltaCallToDone), stubInfo.callReturnLocation.labelAtOffset(stubInfo.patch.dfg.deltaCallToSlowCase), stubInfo.stubRoutine);
277278
278279 RepatchBuffer repatchBuffer(codeBlock);
279  repatchBuffer.relink(stubInfo.callReturnLocation.jumpAtOffset(stubInfo.patch.dfg.deltaCallToStructCheck), CodeLocationLabel(stubInfo.stubRoutine.code()));
 280 repatchBuffer.relink(stubInfo.callReturnLocation.jumpAtOffset(stubInfo.patch.dfg.deltaCallToStructCheck), CodeLocationLabel(stubInfo.stubRoutine->code().code()));
280281 repatchBuffer.relink(stubInfo.callReturnLocation, operationGetByIdProtoBuildList);
281282
282283 stubInfo.initGetByIdChain(*globalData, codeBlock->ownerExecutable(), structure, prototypeChain, count, true);

@@static bool tryBuildGetByIDList(ExecStat
323324 listIndex = 0;
324325 } else if (stubInfo.accessType == access_get_by_id_self) {
325326 ASSERT(!stubInfo.stubRoutine);
326  polymorphicStructureList = new PolymorphicAccessStructureList(*globalData, codeBlock->ownerExecutable(), MacroAssemblerCodeRef::createSelfManagedCodeRef(stubInfo.callReturnLocation.labelAtOffset(stubInfo.patch.dfg.deltaCallToSlowCase)), stubInfo.u.getByIdSelf.baseObjectStructure.get(), true);
 327 polymorphicStructureList = new PolymorphicAccessStructureList(*globalData, codeBlock->ownerExecutable(), JITStubRoutine::createSelfManagedRoutine(stubInfo.callReturnLocation.labelAtOffset(stubInfo.patch.dfg.deltaCallToSlowCase)), stubInfo.u.getByIdSelf.baseObjectStructure.get(), true);
327328 stubInfo.initGetByIdSelfList(polymorphicStructureList, 1);
328329 listIndex = 1;
329330 } else {

@@static bool tryBuildGetByIDList(ExecStat
433434
434435 CodeLocationLabel lastProtoBegin;
435436 if (listIndex)
436  lastProtoBegin = CodeLocationLabel(polymorphicStructureList->list[listIndex - 1].stubRoutine.code());
 437 lastProtoBegin = CodeLocationLabel(polymorphicStructureList->list[listIndex - 1].stubRoutine->code().code());
437438 else
438439 lastProtoBegin = stubInfo.callReturnLocation.labelAtOffset(stubInfo.patch.dfg.deltaCallToSlowCase);
439440 ASSERT(!!lastProtoBegin);

@@static bool tryBuildGetByIDList(ExecStat
445446 patchBuffer.link(handlerCall, lookupExceptionHandlerInStub);
446447 }
447448
448  MacroAssemblerCodeRef stubRoutine = FINALIZE_CODE(
449  patchBuffer,
450  ("DFG GetById polymorphic list access for CodeBlock %p, return point %p",
451  exec->codeBlock(), stubInfo.callReturnLocation.labelAtOffset(
452  stubInfo.patch.dfg.deltaCallToDone).executableAddress()));
 449 RefPtr<JITStubRoutine> stubRoutine =
 450 createJITStubRoutine(
 451 FINALIZE_CODE(
 452 patchBuffer,
 453 ("DFG GetById polymorphic list access for CodeBlock %p, return point %p",
 454 exec->codeBlock(), stubInfo.callReturnLocation.labelAtOffset(
 455 stubInfo.patch.dfg.deltaCallToDone).executableAddress())),
 456 *globalData,
 457 codeBlock->ownerExecutable(),
 458 slot.cachedPropertyType() == PropertySlot::Getter
 459 || slot.cachedPropertyType() == PropertySlot::Custom);
453460
454461 polymorphicStructureList->list[listIndex].set(*globalData, codeBlock->ownerExecutable(), stubRoutine, structure, isDirect);
455462
456463 CodeLocationJump jumpLocation = stubInfo.callReturnLocation.jumpAtOffset(stubInfo.patch.dfg.deltaCallToStructCheck);
457464 RepatchBuffer repatchBuffer(codeBlock);
458  repatchBuffer.relink(jumpLocation, CodeLocationLabel(stubRoutine.code()));
 465 repatchBuffer.relink(jumpLocation, CodeLocationLabel(stubRoutine->code().code()));
459466
460467 if (listIndex < (POLYMORPHIC_LIST_CACHE_SIZE - 1))
461468 return true;

@@static bool tryBuildGetByIDProtoList(Exe
499506 if (stubInfo.accessType == access_get_by_id_chain) {
500507 ASSERT(!!stubInfo.stubRoutine);
501508 polymorphicStructureList = new PolymorphicAccessStructureList(*globalData, codeBlock->ownerExecutable(), stubInfo.stubRoutine, stubInfo.u.getByIdChain.baseObjectStructure.get(), stubInfo.u.getByIdChain.chain.get(), true);
502  stubInfo.stubRoutine = MacroAssemblerCodeRef();
 509 stubInfo.stubRoutine.clear();
503510 stubInfo.initGetByIdProtoList(polymorphicStructureList, 1);
504511 } else {
505512 ASSERT(stubInfo.accessType == access_get_by_id_proto_list);

@@static bool tryBuildGetByIDProtoList(Exe
510517 if (listIndex < POLYMORPHIC_LIST_CACHE_SIZE) {
511518 stubInfo.u.getByIdProtoList.listSize++;
512519
513  CodeLocationLabel lastProtoBegin = CodeLocationLabel(polymorphicStructureList->list[listIndex - 1].stubRoutine.code());
 520 CodeLocationLabel lastProtoBegin = CodeLocationLabel(polymorphicStructureList->list[listIndex - 1].stubRoutine->code().code());
514521 ASSERT(!!lastProtoBegin);
515522
516  MacroAssemblerCodeRef stubRoutine;
 523 RefPtr<JITStubRoutine> stubRoutine;
517524
518525 generateProtoChainAccessStub(exec, stubInfo, prototypeChain, count, offset, structure, stubInfo.callReturnLocation.labelAtOffset(stubInfo.patch.dfg.deltaCallToDone), lastProtoBegin, stubRoutine);
519526

@@static bool tryBuildGetByIDProtoList(Exe
521528
522529 CodeLocationJump jumpLocation = stubInfo.callReturnLocation.jumpAtOffset(stubInfo.patch.dfg.deltaCallToStructCheck);
523530 RepatchBuffer repatchBuffer(codeBlock);
524  repatchBuffer.relink(jumpLocation, CodeLocationLabel(stubRoutine.code()));
 531 repatchBuffer.relink(jumpLocation, CodeLocationLabel(stubRoutine->code().code()));
525532
526533 if (listIndex < (POLYMORPHIC_LIST_CACHE_SIZE - 1))
527534 return true;

@@static void emitPutReplaceStub(
581588 PutKind,
582589 Structure* structure,
583590 CodeLocationLabel failureLabel,
584  MacroAssemblerCodeRef& stubRoutine)
 591 RefPtr<JITStubRoutine>& stubRoutine)
585592{
586593 JSGlobalData* globalData = &exec->globalData();
587594 GPRReg baseGPR = static_cast<GPRReg>(stubInfo.patch.dfg.baseGPR);

@@static void emitPutReplaceStub(
655662 patchBuffer.link(success, stubInfo.callReturnLocation.labelAtOffset(stubInfo.patch.dfg.deltaCallToDone));
656663 patchBuffer.link(failure, failureLabel);
657664
658  stubRoutine = FINALIZE_CODE(
 665 stubRoutine = FINALIZE_CODE_FOR_STUB(
659666 patchBuffer,
660667 ("DFG PutById replace stub for CodeBlock %p, return point %p",
661668 exec->codeBlock(), stubInfo.callReturnLocation.labelAtOffset(

@@static void emitPutTransitionStub(
673680 Structure* oldStructure,
674681 StructureChain* prototypeChain,
675682 CodeLocationLabel failureLabel,
676  MacroAssemblerCodeRef& stubRoutine)
 683 RefPtr<JITStubRoutine>& stubRoutine)
677684{
678685 JSGlobalData* globalData = &exec->globalData();
679686

@@static void emitPutTransitionStub(
754761 patchBuffer.link(failure, failureLabel);
755762 else
756763 patchBuffer.link(failureCases, failureLabel);
757 
758  stubRoutine = FINALIZE_CODE(
 764
 765 stubRoutine = FINALIZE_CODE_FOR_STUB(
759766 patchBuffer,
760767 ("DFG PutById transition stub for CodeBlock %p, return point %p",
761768 exec->codeBlock(), stubInfo.callReturnLocation.labelAtOffset(

@@static bool tryCachePutByID(ExecState* e
799806 stubInfo.stubRoutine);
800807
801808 RepatchBuffer repatchBuffer(codeBlock);
802  repatchBuffer.relink(stubInfo.callReturnLocation.jumpAtOffset(stubInfo.patch.dfg.deltaCallToStructCheck), CodeLocationLabel(stubInfo.stubRoutine.code()));
 809 repatchBuffer.relink(stubInfo.callReturnLocation.jumpAtOffset(stubInfo.patch.dfg.deltaCallToStructCheck), CodeLocationLabel(stubInfo.stubRoutine->code().code()));
803810 repatchBuffer.relink(stubInfo.callReturnLocation, appropriateListBuildingPutByIdFunction(slot, putKind));
804811
805812 stubInfo.initPutByIdTransition(*globalData, codeBlock->ownerExecutable(), oldStructure, structure, prototypeChain, putKind == Direct);

@@static bool tryBuildPutByIdList(ExecStat
841848 // Optimize self access.
842849 if (slot.base() == baseValue) {
843850 PolymorphicPutByIdList* list;
844  MacroAssemblerCodeRef stubRoutine;
 851 RefPtr<JITStubRoutine> stubRoutine;
845852
846853 if (slot.type() == PutPropertySlot::NewProperty) {
847854 if (structure->isDictionary())

@@static bool tryBuildPutByIdList(ExecStat
888895 }
889896
890897 RepatchBuffer repatchBuffer(codeBlock);
891  repatchBuffer.relink(stubInfo.callReturnLocation.jumpAtOffset(stubInfo.patch.dfg.deltaCallToStructCheck), CodeLocationLabel(stubRoutine.code()));
 898 repatchBuffer.relink(stubInfo.callReturnLocation.jumpAtOffset(stubInfo.patch.dfg.deltaCallToStructCheck), CodeLocationLabel(stubRoutine->code().code()));
892899
893900 if (list->isFull())
894901 repatchBuffer.relink(stubInfo.callReturnLocation, appropriateGenericPutByIdFunction(slot, putKind));
122052

Source/JavaScriptCore/heap/ConservativeRoots.cpp

@@void ConservativeRoots::grow()
6262 m_roots = newRoots;
6363}
6464
65 class DummyMarkHook {
66 public:
67  void mark(void*) { }
68 };
69 
7065template<typename MarkHook>
7166inline void ConservativeRoots::genericAddPointer(void* p, TinyBloomFilter filter, MarkHook& markHook)
7267{

@@void ConservativeRoots::genericAddSpan(v
110105 genericAddPointer(*it, filter, markHook);
111106}
112107
 108class DummyMarkHook {
 109public:
 110 void mark(void*) { }
 111};
 112
113113void ConservativeRoots::add(void* begin, void* end)
114114{
115  DummyMarkHook hook;
116  genericAddSpan(begin, end, hook);
 115 DummyMarkHook dummy;
 116 genericAddSpan(begin, end, dummy);
117117}
118118
119 void ConservativeRoots::add(void* begin, void* end, DFGCodeBlocks& dfgCodeBlocks)
 119void ConservativeRoots::add(void* begin, void* end, JITStubRoutineSet& jitStubRoutines)
 120{
 121 genericAddSpan(begin, end, jitStubRoutines);
 122}
 123
 124template<typename T, typename U>
 125class CompositeMarkHook {
 126public:
 127 CompositeMarkHook(T& first, U& second)
 128 : m_first(first)
 129 , m_second(second)
 130 {
 131 }
 132
 133 void mark(void* address)
 134 {
 135 m_first.mark(address);
 136 m_second.mark(address);
 137 }
 138
 139private:
 140 T& m_first;
 141 U& m_second;
 142};
 143
 144void ConservativeRoots::add(
 145 void* begin, void* end, JITStubRoutineSet& jitStubRoutines, DFGCodeBlocks& dfgCodeBlocks)
120146{
121  genericAddSpan(begin, end, dfgCodeBlocks);
 147 CompositeMarkHook<JITStubRoutineSet, DFGCodeBlocks> markHook(
 148 jitStubRoutines, dfgCodeBlocks);
 149 genericAddSpan(begin, end, markHook);
122150}
123151
124152} // namespace JSC
122052

Source/JavaScriptCore/heap/ConservativeRoots.h

3232
3333namespace JSC {
3434
35 class JSCell;
3635class DFGCodeBlocks;
3736class Heap;
 37class JITStubRoutineSet;
 38class JSCell;
3839
3940class ConservativeRoots {
4041public:

@@public:
4243 ~ConservativeRoots();
4344
4445 void add(void* begin, void* end);
45  void add(void* begin, void* end, DFGCodeBlocks&);
 46 void add(void* begin, void* end, JITStubRoutineSet&);
 47 void add(void* begin, void* end, JITStubRoutineSet&, DFGCodeBlocks&);
4648
4749 size_t size();
4850 JSCell** roots();
122052

Source/JavaScriptCore/heap/Heap.cpp

@@void Heap::markRoots(bool fullGC)
420420 // We gather conservative roots before clearing mark bits because conservative
421421 // gathering uses the mark bits to determine whether a reference is valid.
422422 ConservativeRoots machineThreadRoots(&m_objectSpace.blocks(), &m_storageSpace);
 423 m_jitStubRoutines.clearMarks();
423424 {
424425 GCPHASE(GatherConservativeRoots);
425426 m_machineThreads.gatherConservativeRoots(machineThreadRoots, &dummy);

@@void Heap::markRoots(bool fullGC)
429430 m_dfgCodeBlocks.clearMarks();
430431 {
431432 GCPHASE(GatherRegisterFileRoots);
432  registerFile().gatherConservativeRoots(registerFileRoots, m_dfgCodeBlocks);
 433 registerFile().gatherConservativeRoots(
 434 registerFileRoots, m_jitStubRoutines, m_dfgCodeBlocks);
433435 }
434436
435437#if ENABLE(DFG_JIT)

@@void Heap::markRoots(bool fullGC)
540542 }
541543
542544 {
543  GCPHASE(TraceCodeBlocks);
544  MARK_LOG_ROOT(visitor, "Trace Code Blocks");
 545 GCPHASE(TraceCodeBlocksAndJITStubRoutines);
 546 MARK_LOG_ROOT(visitor, "Trace Code Blocks and JIT Stub Routines");
545547 m_dfgCodeBlocks.traceMarkedCodeBlocks(visitor);
 548 m_jitStubRoutines.traceMarkedStubRoutines(visitor);
546549 visitor.donateAndDrain();
547550 }
548551

@@void Heap::deleteUnmarkedCompiledCode()
665668 }
666669
667670 m_dfgCodeBlocks.deleteUnmarkedJettisonedCodeBlocks();
 671 m_jitStubRoutines.deleteUnmarkedJettisonedStubRoutines();
668672}
669673
670674void Heap::collectAllGarbage()
122052

Source/JavaScriptCore/heap/Heap.h

2626#include "DFGCodeBlocks.h"
2727#include "HandleSet.h"
2828#include "HandleStack.h"
 29#include "JITStubRoutineSet.h"
2930#include "MarkedAllocator.h"
3031#include "MarkedBlock.h"
3132#include "MarkedBlockSet.h"

@@namespace JSC {
4445 class CodeBlock;
4546 class ExecutableBase;
4647 class GCActivityCallback;
 48 class GCAwareJITStubRoutine;
4749 class GlobalCodeBlock;
4850 class Heap;
4951 class HeapRootVisitor;
5052 class IncrementalSweeper;
 53 class JITStubRoutine;
5154 class JSCell;
5255 class JSGlobalData;
5356 class JSValue;

@@namespace JSC {
168171
169172 private:
170173 friend class CodeBlock;
 174 friend class GCAwareJITStubRoutine;
 175 friend class JITStubRoutine;
171176 friend class LLIntOffsetsExtractor;
172177 friend class MarkedSpace;
173178 friend class MarkedAllocator;

@@namespace JSC {
229234 HandleSet m_handleSet;
230235 HandleStack m_handleStack;
231236 DFGCodeBlocks m_dfgCodeBlocks;
 237 JITStubRoutineSet m_jitStubRoutines;
232238 FinalizerOwner m_finalizerOwner;
233239
234240 bool m_isSafeToCollect;
122052

Source/JavaScriptCore/heap/JITStubRoutineSet.cpp

 1/*
 2 * Copyright (C) 2012 Apple Inc. All rights reserved.
 3 *
 4 * Redistribution and use in source and binary forms, with or without
 5 * modification, are permitted provided that the following conditions
 6 * are met:
 7 * 1. Redistributions of source code must retain the above copyright
 8 * notice, this list of conditions and the following disclaimer.
 9 * 2. Redistributions in binary form must reproduce the above copyright
 10 * notice, this list of conditions and the following disclaimer in the
 11 * documentation and/or other materials provided with the distribution.
 12 *
 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 24 */
 25
 26#include "config.h"
 27#include "JITStubRoutineSet.h"
 28
 29#if ENABLE(JIT)
 30
 31#include "GCAwareJITStubRoutine.h"
 32#include "ScopeChain.h"
 33#include "SlotVisitor.h"
 34
 35namespace JSC {
 36
 37JITStubRoutineSet::JITStubRoutineSet() { }
 38JITStubRoutineSet::~JITStubRoutineSet()
 39{
 40 for (size_t i = m_listOfRoutines.size(); i--;) {
 41 GCAwareJITStubRoutine* routine = m_listOfRoutines[i];
 42
 43 routine->m_mayBeExecuting = false;
 44
 45 if (!routine->m_isJettisoned) {
 46 // Inform the deref() routine that it should delete this guy as soon
 47 // as the ref count reaches zero.
 48 routine->m_isJettisoned = true;
 49 continue;
 50 }
 51
 52 routine->deleteFromGC();
 53 }
 54}
 55
 56void JITStubRoutineSet::add(GCAwareJITStubRoutine* routine)
 57{
 58 ASSERT(!routine->m_isJettisoned);
 59
 60 m_listOfRoutines.append(routine);
 61
 62 uintptr_t start = routine->startAddress();
 63 uintptr_t end = routine->endAddress();
 64 uintptr_t step = JITStubRoutine::addressStep();
 65 for (uintptr_t iter = start; iter < end; iter += step) {
 66 ASSERT(m_addressToRoutineMap.find(iter) == m_addressToRoutineMap.end());
 67 m_addressToRoutineMap.add(iter, routine);
 68 }
 69}
 70
 71void JITStubRoutineSet::clearMarks()
 72{
 73 for (size_t i = m_listOfRoutines.size(); i--;)
 74 m_listOfRoutines[i]->m_mayBeExecuting = false;
 75}
 76
 77void JITStubRoutineSet::markSlow(uintptr_t address)
 78{
 79 HashMap<uintptr_t, GCAwareJITStubRoutine*>::iterator iter =
 80 m_addressToRoutineMap.find(address & ~(JITStubRoutine::addressStep() - 1));
 81
 82 if (iter == m_addressToRoutineMap.end())
 83 return;
 84
 85 iter->second->m_mayBeExecuting = true;
 86}
 87
 88void JITStubRoutineSet::deleteUnmarkedJettisonedStubRoutines()
 89{
 90 for (size_t i = 0; i < m_listOfRoutines.size(); i++) {
 91 GCAwareJITStubRoutine* routine = m_listOfRoutines[i];
 92 if (!routine->m_isJettisoned || routine->m_mayBeExecuting)
 93 continue;
 94
 95 uintptr_t start = routine->startAddress();
 96 uintptr_t end = routine->endAddress();
 97 uintptr_t step = JITStubRoutine::addressStep();
 98 for (uintptr_t iter = start; iter < end; iter += step) {
 99 ASSERT(m_addressToRoutineMap.find(iter) != m_addressToRoutineMap.end());
 100 ASSERT(m_addressToRoutineMap.find(iter)->second == routine);
 101 m_addressToRoutineMap.remove(iter);
 102 }
 103
 104 routine->deleteFromGC();
 105
 106 m_listOfRoutines[i] = m_listOfRoutines.last();
 107 m_listOfRoutines.removeLast();
 108 i--;
 109 }
 110}
 111
 112void JITStubRoutineSet::traceMarkedStubRoutines(SlotVisitor& visitor)
 113{
 114 for (size_t i = m_listOfRoutines.size(); i--;) {
 115 GCAwareJITStubRoutine* routine = m_listOfRoutines[i];
 116 if (!routine->m_mayBeExecuting)
 117 continue;
 118
 119 routine->markRequiredObjects(visitor);
 120 }
 121}
 122
 123} // namespace JSC
 124
 125#endif // ENABLE(JIT)
 126
0

Source/JavaScriptCore/heap/JITStubRoutineSet.h

 1/*
 2 * Copyright (C) 2012 Apple Inc. All rights reserved.
 3 *
 4 * Redistribution and use in source and binary forms, with or without
 5 * modification, are permitted provided that the following conditions
 6 * are met:
 7 * 1. Redistributions of source code must retain the above copyright
 8 * notice, this list of conditions and the following disclaimer.
 9 * 2. Redistributions in binary form must reproduce the above copyright
 10 * notice, this list of conditions and the following disclaimer in the
 11 * documentation and/or other materials provided with the distribution.
 12 *
 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 24 */
 25
 26#ifndef JITStubRoutineSet_h
 27#define JITStubRoutineSet_h
 28
 29#include <wtf/Platform.h>
 30
 31#if ENABLE(JIT)
 32
 33#include "JITStubRoutine.h"
 34#include <wtf/FastAllocBase.h>
 35#include <wtf/HashMap.h>
 36#include <wtf/Vector.h>
 37
 38namespace JSC {
 39
 40class GCAwareJITStubRoutine;
 41class SlotVisitor;
 42
 43class JITStubRoutineSet {
 44 WTF_MAKE_NONCOPYABLE(JITStubRoutineSet);
 45 WTF_MAKE_FAST_ALLOCATED;
 46
 47public:
 48 JITStubRoutineSet();
 49 ~JITStubRoutineSet();
 50
 51 void add(GCAwareJITStubRoutine*);
 52
 53 void clearMarks();
 54
 55 void mark(void* candidateAddress)
 56 {
 57 uintptr_t address = reinterpret_cast<uintptr_t>(candidateAddress);
 58 if (!JITStubRoutine::passesFilter(address))
 59 return;
 60
 61 markSlow(address);
 62 }
 63
 64 void deleteUnmarkedJettisonedStubRoutines();
 65
 66 void traceMarkedStubRoutines(SlotVisitor&);
 67
 68private:
 69 void markSlow(uintptr_t address);
 70
 71 HashMap<uintptr_t, GCAwareJITStubRoutine*> m_addressToRoutineMap;
 72 Vector<GCAwareJITStubRoutine*> m_listOfRoutines;
 73};
 74
 75} // namespace JSC
 76
 77#endif // ENABLE(JIT)
 78
 79#endif // JITStubRoutineSet_h
 80
0

Source/JavaScriptCore/heap/MachineStackMarker.h

2828
2929namespace JSC {
3030
31  class Heap;
3231 class ConservativeRoots;
 32 class Heap;
3333
3434 class MachineThreads {
3535 WTF_MAKE_NONCOPYABLE(MachineThreads);
122052

Source/JavaScriptCore/interpreter/RegisterFile.cpp

@@void RegisterFile::gatherConservativeRoo
7373 conservativeRoots.add(begin(), end());
7474}
7575
76 void RegisterFile::gatherConservativeRoots(ConservativeRoots& conservativeRoots, DFGCodeBlocks& dfgCodeBlocks)
 76void RegisterFile::gatherConservativeRoots(ConservativeRoots& conservativeRoots, JITStubRoutineSet& jitStubRoutines, DFGCodeBlocks& dfgCodeBlocks)
7777{
78  conservativeRoots.add(begin(), end(), dfgCodeBlocks);
 78 conservativeRoots.add(begin(), end(), jitStubRoutines, dfgCodeBlocks);
7979}
8080
8181void RegisterFile::releaseExcessCapacity()
122052

Source/JavaScriptCore/interpreter/RegisterFile.h

@@namespace JSC {
3939
4040 class ConservativeRoots;
4141 class DFGCodeBlocks;
 42 class JITStubRoutineSet;
4243 class LLIntOffsetsExtractor;
4344
4445 class RegisterFile {

@@namespace JSC {
6465 ~RegisterFile();
6566
6667 void gatherConservativeRoots(ConservativeRoots&);
67  void gatherConservativeRoots(ConservativeRoots&, DFGCodeBlocks&);
 68 void gatherConservativeRoots(ConservativeRoots&, JITStubRoutineSet&, DFGCodeBlocks&);
6869
6970 Register* begin() const { return static_cast<Register*>(m_reservation.base()); }
7071 Register* end() const { return m_end; }
122052

Source/JavaScriptCore/jit/ExecutableAllocator.cpp

@@namespace JSC {
5555class DemandExecutableAllocator : public MetaAllocator {
5656public:
5757 DemandExecutableAllocator()
58  : MetaAllocator(32) // round up all allocations to 32 bytes
 58 : MetaAllocator(jitAllocationGranule)
5959 {
6060 MutexLocker lock(allocatorsMutex());
6161 allocators().add(this);
122052

Source/JavaScriptCore/jit/ExecutableAllocator.h

@@namespace JSC {
7777class JSGlobalData;
7878void releaseExecutableMemory(JSGlobalData&);
7979
 80static const unsigned jitAllocationGranule = 32;
 81
8082inline size_t roundUpAllocationSize(size_t request, size_t granularity)
8183{
8284 if ((std::numeric_limits<size_t>::max() - granularity) <= request)

@@typedef WTF::MetaAllocatorHandle Executa
101103class DemandExecutableAllocator;
102104#endif
103105
 106#if ENABLE(EXECUTABLE_ALLOCATOR_FIXED)
 107#if CPU(ARM)
 108static const size_t fixedExecutableMemoryPoolSize = 16 * 1024 * 1024;
 109#elif CPU(X86_64)
 110static const size_t fixedExecutableMemoryPoolSize = 1024 * 1024 * 1024;
 111#else
 112static const size_t fixedExecutableMemoryPoolSize = 32 * 1024 * 1024;
 113#endif
 114
 115extern uintptr_t startOfFixedExecutableMemoryPool;
 116#endif
 117
104118class ExecutableAllocator {
105119 enum ProtectionSetting { Writable, Executable };
106120
122052

Source/JavaScriptCore/jit/ExecutableAllocatorFixedVMPool.cpp

@@using namespace WTF;
4545
4646namespace JSC {
4747
48 #if CPU(ARM)
49 static const size_t fixedPoolSize = 16 * 1024 * 1024;
50 #elif CPU(X86_64)
51 static const size_t fixedPoolSize = 1024 * 1024 * 1024;
52 #else
53 static const size_t fixedPoolSize = 32 * 1024 * 1024;
54 #endif
 48uintptr_t startOfFixedExecutableMemoryPool;
5549
5650class FixedVMPoolExecutableAllocator : public MetaAllocator {
5751public:
5852 FixedVMPoolExecutableAllocator()
59  : MetaAllocator(32) // round up all allocations to 32 bytes
 53 : MetaAllocator(jitAllocationGranule) // round up all allocations to 32 bytes
6054 {
61  m_reservation = PageReservation::reserveWithGuardPages(fixedPoolSize, OSAllocator::JSJITCodePages, EXECUTABLE_POOL_WRITABLE, true);
 55 m_reservation = PageReservation::reserveWithGuardPages(fixedExecutableMemoryPoolSize, OSAllocator::JSJITCodePages, EXECUTABLE_POOL_WRITABLE, true);
6256#if !(ENABLE(CLASSIC_INTERPRETER) || ENABLE(LLINT))
6357 if (!m_reservation)
6458 CRASH();
6559#endif
6660 if (m_reservation) {
67  ASSERT(m_reservation.size() == fixedPoolSize);
 61 ASSERT(m_reservation.size() == fixedExecutableMemoryPoolSize);
6862 addFreshFreeSpace(m_reservation.base(), m_reservation.size());
 63
 64 startOfFixedExecutableMemoryPool = reinterpret_cast<uintptr_t>(m_reservation.base());
6965 }
7066 }
7167
122052

Source/JavaScriptCore/jit/GCAwareJITStubRoutine.cpp

 1/*
 2 * Copyright (C) 2012 Apple Inc. All rights reserved.
 3 *
 4 * Redistribution and use in source and binary forms, with or without
 5 * modification, are permitted provided that the following conditions
 6 * are met:
 7 * 1. Redistributions of source code must retain the above copyright
 8 * notice, this list of conditions and the following disclaimer.
 9 * 2. Redistributions in binary form must reproduce the above copyright
 10 * notice, this list of conditions and the following disclaimer in the
 11 * documentation and/or other materials provided with the distribution.
 12 *
 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 24 */
 25
 26#include "config.h"
 27#include "GCAwareJITStubRoutine.h"
 28
 29#if ENABLE(JIT)
 30
 31#include "Heap.h"
 32#include "JSGlobalData.h"
 33#include "ScopeChain.h"
 34#include "SlotVisitor.h"
 35#include "Structure.h"
 36
 37namespace JSC {
 38
 39GCAwareJITStubRoutine::GCAwareJITStubRoutine(
 40 const MacroAssemblerCodeRef& code, JSGlobalData& globalData)
 41 : JITStubRoutine(code)
 42 , m_mayBeExecuting(false)
 43 , m_isJettisoned(false)
 44{
 45 globalData.heap.m_jitStubRoutines.add(this);
 46}
 47
 48GCAwareJITStubRoutine::~GCAwareJITStubRoutine() { }
 49
 50void GCAwareJITStubRoutine::observeZeroRefCount()
 51{
 52 if (m_isJettisoned) {
 53 // This case is needed for when the system shuts down. It may be that
 54 // the JIT stub routine set gets deleted before we get around to deleting
 55 // this guy. In that case the GC informs us that we're jettisoned already
 56 // and that we should delete ourselves as soon as the ref count reaches
 57 // zero.
 58 delete this;
 59 return;
 60 }
 61
 62 ASSERT(!m_isJettisoned);
 63 ASSERT(!m_refCount);
 64
 65 m_isJettisoned = true;
 66}
 67
 68void GCAwareJITStubRoutine::deleteFromGC()
 69{
 70 ASSERT(m_isJettisoned);
 71 ASSERT(!m_refCount);
 72 ASSERT(!m_mayBeExecuting);
 73
 74 delete this;
 75}
 76
 77void GCAwareJITStubRoutine::markRequiredObjectsInternal(SlotVisitor&)
 78{
 79}
 80
 81MarkingGCAwareJITStubRoutineWithOneObject::MarkingGCAwareJITStubRoutineWithOneObject(
 82 const MacroAssemblerCodeRef& code, JSGlobalData& globalData, const JSCell* owner,
 83 JSCell* object)
 84 : GCAwareJITStubRoutine(code, globalData)
 85 , m_object(globalData, owner, object)
 86{
 87}
 88
 89MarkingGCAwareJITStubRoutineWithOneObject::~MarkingGCAwareJITStubRoutineWithOneObject()
 90{
 91}
 92
 93void MarkingGCAwareJITStubRoutineWithOneObject::markRequiredObjectsInternal(SlotVisitor& visitor)
 94{
 95 visitor.append(&m_object);
 96}
 97
 98PassRefPtr<JITStubRoutine> createJITStubRoutine(
 99 const MacroAssemblerCodeRef& code,
 100 JSGlobalData& globalData,
 101 const JSCell*,
 102 bool makesCalls)
 103{
 104 if (!makesCalls)
 105 return adoptRef(new JITStubRoutine(code));
 106
 107 return static_pointer_cast<JITStubRoutine>(
 108 adoptRef(new GCAwareJITStubRoutine(code, globalData)));
 109}
 110
 111PassRefPtr<JITStubRoutine> createJITStubRoutine(
 112 const MacroAssemblerCodeRef& code,
 113 JSGlobalData& globalData,
 114 const JSCell* owner,
 115 bool makesCalls,
 116 JSCell* object)
 117{
 118 if (!makesCalls)
 119 return adoptRef(new JITStubRoutine(code));
 120
 121 return static_pointer_cast<JITStubRoutine>(
 122 adoptRef(new MarkingGCAwareJITStubRoutineWithOneObject(code, globalData, owner, object)));
 123}
 124
 125} // namespace JSC
 126
 127#endif // ENABLE(JIT)
 128
0

Source/JavaScriptCore/jit/GCAwareJITStubRoutine.h

 1/*
 2 * Copyright (C) 2012 Apple Inc. All rights reserved.
 3 *
 4 * Redistribution and use in source and binary forms, with or without
 5 * modification, are permitted provided that the following conditions
 6 * are met:
 7 * 1. Redistributions of source code must retain the above copyright
 8 * notice, this list of conditions and the following disclaimer.
 9 * 2. Redistributions in binary form must reproduce the above copyright
 10 * notice, this list of conditions and the following disclaimer in the
 11 * documentation and/or other materials provided with the distribution.
 12 *
 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 24 */
 25
 26#ifndef GCAwareJITStubRoutine_h
 27#define GCAwareJITStubRoutine_h
 28
 29#include <wtf/Platform.h>
 30
 31#if ENABLE(JIT)
 32
 33#include "JITStubRoutine.h"
 34#include "JSObject.h"
 35#include "JSString.h"
 36#include "WriteBarrier.h"
 37#include <wtf/RefCounted.h>
 38#include <wtf/Vector.h>
 39
 40namespace JSC {
 41
 42class JITStubRoutineSet;
 43
 44// Use this stub routine if you know that your code might be on stack when
 45// either GC or other kinds of stub deletion happen. Basicaly, if your stub
 46// routine makes calls (either to JS code or to C++ code) then you should
 47// assume that it's possible for that JS or C++ code to do something that
 48// causes the system to try to delete your routine. Using this routine type
 49// ensures that the actual deletion is delayed until the GC proves that the
 50// routine is no longer running. You can also subclass this routine if you
 51// want to mark additional objects during GC in those cases where the
 52// routine is known to be executing, or if you want to force this routine to
 53// keep other routines alive (for example due to the use of a slow-path
 54// list which does not get reclaimed all at once).
 55class GCAwareJITStubRoutine : public JITStubRoutine {
 56public:
 57 GCAwareJITStubRoutine(const MacroAssemblerCodeRef&, JSGlobalData&);
 58 virtual ~GCAwareJITStubRoutine();
 59
 60 void markRequiredObjects(SlotVisitor& visitor)
 61 {
 62 markRequiredObjectsInternal(visitor);
 63 }
 64
 65 void deleteFromGC();
 66
 67protected:
 68 virtual void observeZeroRefCount();
 69
 70 virtual void markRequiredObjectsInternal(SlotVisitor&);
 71
 72private:
 73 friend class JITStubRoutineSet;
 74
 75 bool m_mayBeExecuting;
 76 bool m_isJettisoned;
 77};
 78
 79// Use this if you want to mark one additional object during GC if your stub
 80// routine is known to be executing.
 81class MarkingGCAwareJITStubRoutineWithOneObject : public GCAwareJITStubRoutine {
 82public:
 83 MarkingGCAwareJITStubRoutineWithOneObject(
 84 const MacroAssemblerCodeRef&, JSGlobalData&, const JSCell* owner, JSCell*);
 85 virtual ~MarkingGCAwareJITStubRoutineWithOneObject();
 86
 87protected:
 88 virtual void markRequiredObjectsInternal(SlotVisitor&);
 89
 90private:
 91 WriteBarrier<JSCell> m_object;
 92};
 93
 94// Helper for easily creating a GC-aware JIT stub routine. For the varargs,
 95// pass zero or more JSCell*'s. This will either create a JITStubRoutine, a
 96// GCAwareJITStubRoutine, or an ObjectMarkingGCAwareJITStubRoutine as
 97// appropriate. Generally you only need to pass pointers that will be used
 98// after the first call to C++ or JS.
 99//
 100// PassRefPtr<JITStubRoutine> createJITStubRoutine(
 101// const MacroAssemblerCodeRef& code,
 102// JSGlobalData& globalData,
 103// const JSCell* owner,
 104// bool makesCalls,
 105// ...);
 106//
 107// Note that we don't actually use C-style varargs because that leads to
 108// strange type-related problems. For example it would preclude us from using
 109// our custom of passing '0' as NULL pointer. Besides, when I did try to write
 110// this function using varargs, I ended up with more code than this simple
 111// way.
 112
 113PassRefPtr<JITStubRoutine> createJITStubRoutine(
 114 const MacroAssemblerCodeRef&, JSGlobalData&, const JSCell* owner, bool makesCalls);
 115PassRefPtr<JITStubRoutine> createJITStubRoutine(
 116 const MacroAssemblerCodeRef&, JSGlobalData&, const JSCell* owner, bool makesCalls,
 117 JSCell*);
 118
 119} // namespace JSC
 120
 121#endif // ENABLE(JIT)
 122
 123#endif // GCAwareJITStubRoutine_h
 124
0

Source/JavaScriptCore/jit/JITPropertyAccess32_64.cpp

3030#include "JIT.h"
3131
3232#include "CodeBlock.h"
 33#include "GCAwareJITStubRoutine.h"
3334#include "Interpreter.h"
3435#include "JITInlineMethods.h"
3536#include "JITStubCall.h"

@@void JIT::privateCompilePutByIdTransitio
557558 patchBuffer.link(m_calls[0].from, FunctionPtr(cti_op_put_by_id_transition_realloc));
558559 }
559560
560  stubInfo->stubRoutine = FINALIZE_CODE(
561  patchBuffer,
562  ("Baseline put_by_id transition stub for CodeBlock %p, return point %p",
563  m_codeBlock, returnAddress.value()));
 561 stubInfo->stubRoutine = createJITStubRoutine(
 562 FINALIZE_CODE(
 563 patchBuffer,
 564 ("Baseline put_by_id transition stub for CodeBlock %p, return point %p",
 565 m_codeBlock, returnAddress.value())),
 566 *m_globalData,
 567 m_codeBlock->ownerExecutable(),
 568 willNeedStorageRealloc,
 569 newStructure);
564570 RepatchBuffer repatchBuffer(m_codeBlock);
565  repatchBuffer.relinkCallerToTrampoline(returnAddress, CodeLocationLabel(stubInfo->stubRoutine.code()));
 571 repatchBuffer.relinkCallerToTrampoline(returnAddress, CodeLocationLabel(stubInfo->stubRoutine->code().code()));
566572}
567573
568574void JIT::patchGetByIdSelf(CodeBlock* codeBlock, StructureStubInfo* stubInfo, Structure* structure, PropertyOffset cachedOffset, ReturnAddressPtr returnAddress)

@@void JIT::privateCompilePatchGetArrayLen
624630 patchBuffer.link(success, stubInfo->hotPathBegin.labelAtOffset(stubInfo->patch.baseline.u.get.putResult));
625631
626632 // Track the stub we have created so that it will be deleted later.
627  stubInfo->stubRoutine = FINALIZE_CODE(
 633 stubInfo->stubRoutine = FINALIZE_CODE_FOR_STUB(
628634 patchBuffer,
629635 ("Baseline get_by_id array length stub for CodeBlock %p, return point %p",
630636 m_codeBlock, stubInfo->hotPathBegin.labelAtOffset(

@@void JIT::privateCompilePatchGetArrayLen
633639 // Finally patch the jump to slow case back in the hot path to jump here instead.
634640 CodeLocationJump jumpLocation = stubInfo->hotPathBegin.jumpAtOffset(stubInfo->patch.baseline.u.get.structureCheck);
635641 RepatchBuffer repatchBuffer(m_codeBlock);
636  repatchBuffer.relink(jumpLocation, CodeLocationLabel(stubInfo->stubRoutine.code()));
 642 repatchBuffer.relink(jumpLocation, CodeLocationLabel(stubInfo->stubRoutine->code().code()));
637643
638644 // We don't want to patch more than once - in future go to cti_op_put_by_id_generic.
639645 repatchBuffer.relinkCallerToFunction(returnAddress, FunctionPtr(cti_op_get_by_id_array_fail));

@@void JIT::privateCompileGetByIdProto(Str
694700 }
695701
696702 // Track the stub we have created so that it will be deleted later.
697  stubInfo->stubRoutine = FINALIZE_CODE(
698  patchBuffer,
699  ("Baseline get_by_id proto stub for CodeBlock %p, return point %p",
700  m_codeBlock, stubInfo->hotPathBegin.labelAtOffset(
701  stubInfo->patch.baseline.u.get.putResult).executableAddress()));
 703 stubInfo->stubRoutine = createJITStubRoutine(
 704 FINALIZE_CODE(
 705 patchBuffer,
 706 ("Baseline get_by_id proto stub for CodeBlock %p, return point %p",
 707 m_codeBlock, stubInfo->hotPathBegin.labelAtOffset(
 708 stubInfo->patch.baseline.u.get.putResult).executableAddress())),
 709 *m_globalData,
 710 m_codeBlock->ownerExecutable(),
 711 needsStubLink);
702712
703713 // Finally patch the jump to slow case back in the hot path to jump here instead.
704714 CodeLocationJump jumpLocation = stubInfo->hotPathBegin.jumpAtOffset(stubInfo->patch.baseline.u.get.structureCheck);
705715 RepatchBuffer repatchBuffer(m_codeBlock);
706  repatchBuffer.relink(jumpLocation, CodeLocationLabel(stubInfo->stubRoutine.code()));
 716 repatchBuffer.relink(jumpLocation, CodeLocationLabel(stubInfo->stubRoutine->code().code()));
707717
708718 // We don't want to patch more than once - in future go to cti_op_put_by_id_generic.
709719 repatchBuffer.relinkCallerToFunction(returnAddress, FunctionPtr(cti_op_get_by_id_proto_list));

@@void JIT::privateCompileGetByIdSelfList(
747757 }
748758 }
749759 // Use the patch information to link the failure cases back to the original slow case routine.
750  CodeLocationLabel lastProtoBegin = CodeLocationLabel(polymorphicStructures->list[currentIndex - 1].stubRoutine.code());
 760 CodeLocationLabel lastProtoBegin = CodeLocationLabel(JITStubRoutine::asCodePtr(polymorphicStructures->list[currentIndex - 1].stubRoutine));
751761 if (!lastProtoBegin)
752762 lastProtoBegin = stubInfo->callReturnLocation.labelAtOffset(-stubInfo->patch.baseline.u.get.coldPathBegin);
753763

@@void JIT::privateCompileGetByIdSelfList(
756766 // On success return back to the hot patch code, at a point it will perform the store to dest for us.
757767 patchBuffer.link(success, stubInfo->hotPathBegin.labelAtOffset(stubInfo->patch.baseline.u.get.putResult));
758768
759  MacroAssemblerCodeRef stubRoutine = FINALIZE_CODE(
760  patchBuffer,
761  ("Baseline get_by_id self list stub for CodeBlock %p, return point %p",
762  m_codeBlock, stubInfo->hotPathBegin.labelAtOffset(
763  stubInfo->patch.baseline.u.get.putResult).executableAddress()));
 769 RefPtr<JITStubRoutine> stubRoutine = createJITStubRoutine(
 770 FINALIZE_CODE(
 771 patchBuffer,
 772 ("Baseline get_by_id self list stub for CodeBlock %p, return point %p",
 773 m_codeBlock, stubInfo->hotPathBegin.labelAtOffset(
 774 stubInfo->patch.baseline.u.get.putResult).executableAddress())),
 775 *m_globalData,
 776 m_codeBlock->ownerExecutable(),
 777 needsStubLink);
764778
765779 polymorphicStructures->list[currentIndex].set(*m_globalData, m_codeBlock->ownerExecutable(), stubRoutine, structure, isDirect);
766780
767781 // Finally patch the jump to slow case back in the hot path to jump here instead.
768782 CodeLocationJump jumpLocation = stubInfo->hotPathBegin.jumpAtOffset(stubInfo->patch.baseline.u.get.structureCheck);
769783 RepatchBuffer repatchBuffer(m_codeBlock);
770  repatchBuffer.relink(jumpLocation, CodeLocationLabel(stubRoutine.code()));
 784 repatchBuffer.relink(jumpLocation, CodeLocationLabel(stubRoutine->code().code()));
771785}
772786
773787void JIT::privateCompileGetByIdProtoList(StructureStubInfo* stubInfo, PolymorphicAccessStructureList* prototypeStructures, int currentIndex, Structure* structure, Structure* prototypeStructure, const Identifier& ident, const PropertySlot& slot, PropertyOffset cachedOffset, CallFrame* callFrame)

@@void JIT::privateCompileGetByIdProtoList
818832 }
819833 }
820834 // Use the patch information to link the failure cases back to the original slow case routine.
821  CodeLocationLabel lastProtoBegin = CodeLocationLabel(prototypeStructures->list[currentIndex - 1].stubRoutine.code());
 835 CodeLocationLabel lastProtoBegin = CodeLocationLabel(JITStubRoutine::asCodePtr(prototypeStructures->list[currentIndex - 1].stubRoutine));
822836 patchBuffer.link(failureCases1, lastProtoBegin);
823837 patchBuffer.link(failureCases2, lastProtoBegin);
824838
825839 // On success return back to the hot patch code, at a point it will perform the store to dest for us.
826840 patchBuffer.link(success, stubInfo->hotPathBegin.labelAtOffset(stubInfo->patch.baseline.u.get.putResult));
827841
828  MacroAssemblerCodeRef stubRoutine = FINALIZE_CODE(
829  patchBuffer,
830  ("Baseline get_by_id proto list stub for CodeBlock %p, return point %p",
831  m_codeBlock, stubInfo->hotPathBegin.labelAtOffset(
832  stubInfo->patch.baseline.u.get.putResult).executableAddress()));
 842 RefPtr<JITStubRoutine> stubRoutine = createJITStubRoutine(
 843 FINALIZE_CODE(
 844 patchBuffer,
 845 ("Baseline get_by_id proto list stub for CodeBlock %p, return point %p",
 846 m_codeBlock, stubInfo->hotPathBegin.labelAtOffset(
 847 stubInfo->patch.baseline.u.get.putResult).executableAddress())),
 848 *m_globalData,
 849 m_codeBlock->ownerExecutable(),
 850 needsStubLink);
833851
834852 prototypeStructures->list[currentIndex].set(callFrame->globalData(), m_codeBlock->ownerExecutable(), stubRoutine, structure, prototypeStructure, isDirect);
835853
836854 // Finally patch the jump to slow case back in the hot path to jump here instead.
837855 CodeLocationJump jumpLocation = stubInfo->hotPathBegin.jumpAtOffset(stubInfo->patch.baseline.u.get.structureCheck);
838856 RepatchBuffer repatchBuffer(m_codeBlock);
839  repatchBuffer.relink(jumpLocation, CodeLocationLabel(stubRoutine.code()));
 857 repatchBuffer.relink(jumpLocation, CodeLocationLabel(stubRoutine->code().code()));
840858}
841859
842860void JIT::privateCompileGetByIdChainList(StructureStubInfo* stubInfo, PolymorphicAccessStructureList* prototypeStructures, int currentIndex, Structure* structure, StructureChain* chain, size_t count, const Identifier& ident, const PropertySlot& slot, PropertyOffset cachedOffset, CallFrame* callFrame)

@@void JIT::privateCompileGetByIdChainList
892910 }
893911 }
894912 // Use the patch information to link the failure cases back to the original slow case routine.
895  CodeLocationLabel lastProtoBegin = CodeLocationLabel(prototypeStructures->list[currentIndex - 1].stubRoutine.code());
 913 CodeLocationLabel lastProtoBegin = CodeLocationLabel(JITStubRoutine::asCodePtr(prototypeStructures->list[currentIndex - 1].stubRoutine));
896914
897915 patchBuffer.link(bucketsOfFail, lastProtoBegin);
898916
899917 // On success return back to the hot patch code, at a point it will perform the store to dest for us.
900918 patchBuffer.link(success, stubInfo->hotPathBegin.labelAtOffset(stubInfo->patch.baseline.u.get.putResult));
901919
902  MacroAssemblerCodeRef stubRoutine = FINALIZE_CODE(
903  patchBuffer,
904  ("Baseline get_by_id chain list stub for CodeBlock %p, return point %p",
905  m_codeBlock, stubInfo->hotPathBegin.labelAtOffset(
906  stubInfo->patch.baseline.u.get.putResult).executableAddress()));
 920 RefPtr<JITStubRoutine> stubRoutine = createJITStubRoutine(
 921 FINALIZE_CODE(
 922 patchBuffer,
 923 ("Baseline get_by_id chain list stub for CodeBlock %p, return point %p",
 924 m_codeBlock, stubInfo->hotPathBegin.labelAtOffset(
 925 stubInfo->patch.baseline.u.get.putResult).executableAddress())),
 926 *m_globalData,
 927 m_codeBlock->ownerExecutable(),
 928 needsStubLink);
907929
908930 // Track the stub we have created so that it will be deleted later.
909931 prototypeStructures->list[currentIndex].set(callFrame->globalData(), m_codeBlock->ownerExecutable(), stubRoutine, structure, chain, isDirect);

@@void JIT::privateCompileGetByIdChainList
911933 // Finally patch the jump to slow case back in the hot path to jump here instead.
912934 CodeLocationJump jumpLocation = stubInfo->hotPathBegin.jumpAtOffset(stubInfo->patch.baseline.u.get.structureCheck);
913935 RepatchBuffer repatchBuffer(m_codeBlock);
914  repatchBuffer.relink(jumpLocation, CodeLocationLabel(stubRoutine.code()));
 936 repatchBuffer.relink(jumpLocation, CodeLocationLabel(stubRoutine->code().code()));
915937}
916938
917939void JIT::privateCompileGetByIdChain(StructureStubInfo* stubInfo, Structure* structure, StructureChain* chain, size_t count, const Identifier& ident, const PropertySlot& slot, PropertyOffset cachedOffset, ReturnAddressPtr returnAddress, CallFrame* callFrame)

@@void JIT::privateCompileGetByIdChain(Str
969991 patchBuffer.link(success, stubInfo->hotPathBegin.labelAtOffset(stubInfo->patch.baseline.u.get.putResult));
970992
971993 // Track the stub we have created so that it will be deleted later.
972  MacroAssemblerCodeRef stubRoutine = FINALIZE_CODE(
973  patchBuffer,
974  ("Baseline get_by_id chain stub for CodeBlock %p, return point %p",
975  m_codeBlock, stubInfo->hotPathBegin.labelAtOffset(
976  stubInfo->patch.baseline.u.get.putResult).executableAddress()));
 994 RefPtr<JITStubRoutine> stubRoutine = createJITStubRoutine(
 995 FINALIZE_CODE(
 996 patchBuffer,
 997 ("Baseline get_by_id chain stub for CodeBlock %p, return point %p",
 998 m_codeBlock, stubInfo->hotPathBegin.labelAtOffset(
 999 stubInfo->patch.baseline.u.get.putResult).executableAddress())),
 1000 *m_globalData,
 1001 m_codeBlock->ownerExecutable(),
 1002 needsStubLink);
9771003 stubInfo->stubRoutine = stubRoutine;
9781004
9791005 // Finally patch the jump to slow case back in the hot path to jump here instead.
9801006 CodeLocationJump jumpLocation = stubInfo->hotPathBegin.jumpAtOffset(stubInfo->patch.baseline.u.get.structureCheck);
9811007 RepatchBuffer repatchBuffer(m_codeBlock);
982  repatchBuffer.relink(jumpLocation, CodeLocationLabel(stubRoutine.code()));
 1008 repatchBuffer.relink(jumpLocation, CodeLocationLabel(stubRoutine->code().code()));
9831009
9841010 // We don't want to patch more than once - in future go to cti_op_put_by_id_generic.
9851011 repatchBuffer.relinkCallerToFunction(returnAddress, FunctionPtr(cti_op_get_by_id_proto_list));
122052

Source/JavaScriptCore/jit/JITPropertyAccess.cpp

2929#include "JIT.h"
3030
3131#include "CodeBlock.h"
 32#include "GCAwareJITStubRoutine.h"
3233#include "GetterSetter.h"
3334#include "Interpreter.h"
3435#include "JITInlineMethods.h"

@@void JIT::privateCompilePutByIdTransitio
595596 patchBuffer.link(m_calls[0].from, FunctionPtr(cti_op_put_by_id_transition_realloc));
596597 }
597598
598  stubInfo->stubRoutine = FINALIZE_CODE(
599  patchBuffer,
600  ("Baseline put_by_id transition for CodeBlock %p, return point %p",
601  m_codeBlock, returnAddress.value()));
 599 stubInfo->stubRoutine = createJITStubRoutine(
 600 FINALIZE_CODE(
 601 patchBuffer,
 602 ("Baseline put_by_id transition for CodeBlock %p, return point %p",
 603 m_codeBlock, returnAddress.value())),
 604 *m_globalData,
 605 m_codeBlock->ownerExecutable(),
 606 willNeedStorageRealloc,
 607 newStructure);
602608 RepatchBuffer repatchBuffer(m_codeBlock);
603  repatchBuffer.relinkCallerToTrampoline(returnAddress, CodeLocationLabel(stubInfo->stubRoutine.code()));
 609 repatchBuffer.relinkCallerToTrampoline(returnAddress, CodeLocationLabel(stubInfo->stubRoutine->code().code()));
604610}
605611
606612void JIT::patchGetByIdSelf(CodeBlock* codeBlock, StructureStubInfo* stubInfo, Structure* structure, PropertyOffset cachedOffset, ReturnAddressPtr returnAddress)

@@void JIT::privateCompilePatchGetArrayLen
657663 patchBuffer.link(success, stubInfo->hotPathBegin.labelAtOffset(stubInfo->patch.baseline.u.get.putResult));
658664
659665 // Track the stub we have created so that it will be deleted later.
660  stubInfo->stubRoutine = FINALIZE_CODE(
 666 stubInfo->stubRoutine = FINALIZE_CODE_FOR_STUB(
661667 patchBuffer,
662668 ("Basline JIT get_by_id array length stub for CodeBlock %p, return point %p",
663669 m_codeBlock, stubInfo->hotPathBegin.labelAtOffset(

@@void JIT::privateCompilePatchGetArrayLen
666672 // Finally patch the jump to slow case back in the hot path to jump here instead.
667673 CodeLocationJump jumpLocation = stubInfo->hotPathBegin.jumpAtOffset(stubInfo->patch.baseline.u.get.structureCheck);
668674 RepatchBuffer repatchBuffer(m_codeBlock);
669  repatchBuffer.relink(jumpLocation, CodeLocationLabel(stubInfo->stubRoutine.code()));
 675 repatchBuffer.relink(jumpLocation, CodeLocationLabel(stubInfo->stubRoutine->code().code()));
670676
671677 // We don't want to patch more than once - in future go to cti_op_put_by_id_generic.
672678 repatchBuffer.relinkCallerToFunction(returnAddress, FunctionPtr(cti_op_get_by_id_array_fail));

@@void JIT::privateCompileGetByIdProto(Str
724730 }
725731 }
726732 // Track the stub we have created so that it will be deleted later.
727  stubInfo->stubRoutine = FINALIZE_CODE(
728  patchBuffer,
729  ("Baseline JIT get_by_id proto stub for CodeBlock %p, return point %p",
730  m_codeBlock, stubInfo->hotPathBegin.labelAtOffset(
731  stubInfo->patch.baseline.u.get.putResult).executableAddress()));
 733 stubInfo->stubRoutine = createJITStubRoutine(
 734 FINALIZE_CODE(
 735 patchBuffer,
 736 ("Baseline JIT get_by_id proto stub for CodeBlock %p, return point %p",
 737 m_codeBlock, stubInfo->hotPathBegin.labelAtOffset(
 738 stubInfo->patch.baseline.u.get.putResult).executableAddress())),
 739 *m_globalData,
 740 m_codeBlock->ownerExecutable(),
 741 needsStubLink);
732742
733743 // Finally patch the jump to slow case back in the hot path to jump here instead.
734744 CodeLocationJump jumpLocation = stubInfo->hotPathBegin.jumpAtOffset(stubInfo->patch.baseline.u.get.structureCheck);
735745 RepatchBuffer repatchBuffer(m_codeBlock);
736  repatchBuffer.relink(jumpLocation, CodeLocationLabel(stubInfo->stubRoutine.code()));
 746 repatchBuffer.relink(jumpLocation, CodeLocationLabel(stubInfo->stubRoutine->code().code()));
737747
738748 // We don't want to patch more than once - in future go to cti_op_put_by_id_generic.
739749 repatchBuffer.relinkCallerToFunction(returnAddress, FunctionPtr(cti_op_get_by_id_proto_list));

@@void JIT::privateCompileGetByIdSelfList(
776786 }
777787
778788 // Use the patch information to link the failure cases back to the original slow case routine.
779  CodeLocationLabel lastProtoBegin = CodeLocationLabel(polymorphicStructures->list[currentIndex - 1].stubRoutine.code());
 789 CodeLocationLabel lastProtoBegin = CodeLocationLabel(JITStubRoutine::asCodePtr(polymorphicStructures->list[currentIndex - 1].stubRoutine));
780790 if (!lastProtoBegin)
781791 lastProtoBegin = stubInfo->callReturnLocation.labelAtOffset(-stubInfo->patch.baseline.u.get.coldPathBegin);
782792

@@void JIT::privateCompileGetByIdSelfList(
785795 // On success return back to the hot patch code, at a point it will perform the store to dest for us.
786796 patchBuffer.link(success, stubInfo->hotPathBegin.labelAtOffset(stubInfo->patch.baseline.u.get.putResult));
787797
788  MacroAssemblerCodeRef stubCode = FINALIZE_CODE(
789  patchBuffer,
790  ("Baseline JIT get_by_id list stub for CodeBlock %p, return point %p",
791  m_codeBlock, stubInfo->hotPathBegin.labelAtOffset(
792  stubInfo->patch.baseline.u.get.putResult).executableAddress()));
 798 RefPtr<JITStubRoutine> stubCode = createJITStubRoutine(
 799 FINALIZE_CODE(
 800 patchBuffer,
 801 ("Baseline JIT get_by_id list stub for CodeBlock %p, return point %p",
 802 m_codeBlock, stubInfo->hotPathBegin.labelAtOffset(
 803 stubInfo->patch.baseline.u.get.putResult).executableAddress())),
 804 *m_globalData,
 805 m_codeBlock->ownerExecutable(),
 806 needsStubLink);
793807
794808 polymorphicStructures->list[currentIndex].set(*m_globalData, m_codeBlock->ownerExecutable(), stubCode, structure, isDirect);
795809
796810 // Finally patch the jump to slow case back in the hot path to jump here instead.
797811 CodeLocationJump jumpLocation = stubInfo->hotPathBegin.jumpAtOffset(stubInfo->patch.baseline.u.get.structureCheck);
798812 RepatchBuffer repatchBuffer(m_codeBlock);
799  repatchBuffer.relink(jumpLocation, CodeLocationLabel(stubCode.code()));
 813 repatchBuffer.relink(jumpLocation, CodeLocationLabel(stubCode->code().code()));
800814}
801815
802816void JIT::privateCompileGetByIdProtoList(StructureStubInfo* stubInfo, PolymorphicAccessStructureList* prototypeStructures, int currentIndex, Structure* structure, Structure* prototypeStructure, const Identifier& ident, const PropertySlot& slot, PropertyOffset cachedOffset, CallFrame* callFrame)

@@void JIT::privateCompileGetByIdProtoList
848862 }
849863
850864 // Use the patch information to link the failure cases back to the original slow case routine.
851  CodeLocationLabel lastProtoBegin = CodeLocationLabel(prototypeStructures->list[currentIndex - 1].stubRoutine.code());
 865 CodeLocationLabel lastProtoBegin = CodeLocationLabel(JITStubRoutine::asCodePtr(prototypeStructures->list[currentIndex - 1].stubRoutine));
852866 patchBuffer.link(failureCases1, lastProtoBegin);
853867 patchBuffer.link(failureCases2, lastProtoBegin);
854868
855869 // On success return back to the hot patch code, at a point it will perform the store to dest for us.
856870 patchBuffer.link(success, stubInfo->hotPathBegin.labelAtOffset(stubInfo->patch.baseline.u.get.putResult));
857871
858  MacroAssemblerCodeRef stubCode = FINALIZE_CODE(
859  patchBuffer,
860  ("Baseline JIT get_by_id proto list stub for CodeBlock %p, return point %p",
861  m_codeBlock, stubInfo->hotPathBegin.labelAtOffset(
862  stubInfo->patch.baseline.u.get.putResult).executableAddress()));
 872 RefPtr<JITStubRoutine> stubCode = createJITStubRoutine(
 873 FINALIZE_CODE(
 874 patchBuffer,
 875 ("Baseline JIT get_by_id proto list stub for CodeBlock %p, return point %p",
 876 m_codeBlock, stubInfo->hotPathBegin.labelAtOffset(
 877 stubInfo->patch.baseline.u.get.putResult).executableAddress())),
 878 *m_globalData,
 879 m_codeBlock->ownerExecutable(),
 880 needsStubLink);
863881 prototypeStructures->list[currentIndex].set(*m_globalData, m_codeBlock->ownerExecutable(), stubCode, structure, prototypeStructure, isDirect);
864882
865883 // Finally patch the jump to slow case back in the hot path to jump here instead.
866884 CodeLocationJump jumpLocation = stubInfo->hotPathBegin.jumpAtOffset(stubInfo->patch.baseline.u.get.structureCheck);
867885 RepatchBuffer repatchBuffer(m_codeBlock);
868  repatchBuffer.relink(jumpLocation, CodeLocationLabel(stubCode.code()));
 886 repatchBuffer.relink(jumpLocation, CodeLocationLabel(stubCode->code().code()));
869887}
870888
871889void JIT::privateCompileGetByIdChainList(StructureStubInfo* stubInfo, PolymorphicAccessStructureList* prototypeStructures, int currentIndex, Structure* structure, StructureChain* chain, size_t count, const Identifier& ident, const PropertySlot& slot, PropertyOffset cachedOffset, CallFrame* callFrame)

@@void JIT::privateCompileGetByIdChainList
921939 }
922940
923941 // Use the patch information to link the failure cases back to the original slow case routine.
924  CodeLocationLabel lastProtoBegin = CodeLocationLabel(prototypeStructures->list[currentIndex - 1].stubRoutine.code());
 942 CodeLocationLabel lastProtoBegin = CodeLocationLabel(JITStubRoutine::asCodePtr(prototypeStructures->list[currentIndex - 1].stubRoutine));
925943
926944 patchBuffer.link(bucketsOfFail, lastProtoBegin);
927945
928946 // On success return back to the hot patch code, at a point it will perform the store to dest for us.
929947 patchBuffer.link(success, stubInfo->hotPathBegin.labelAtOffset(stubInfo->patch.baseline.u.get.putResult));
930948
931  CodeRef stubRoutine = FINALIZE_CODE(
932  patchBuffer,
933  ("Baseline JIT get_by_id chain list stub for CodeBlock %p, return point %p",
934  m_codeBlock, stubInfo->hotPathBegin.labelAtOffset(
935  stubInfo->patch.baseline.u.get.putResult).executableAddress()));
 949 RefPtr<JITStubRoutine> stubRoutine = createJITStubRoutine(
 950 FINALIZE_CODE(
 951 patchBuffer,
 952 ("Baseline JIT get_by_id chain list stub for CodeBlock %p, return point %p",
 953 m_codeBlock, stubInfo->hotPathBegin.labelAtOffset(
 954 stubInfo->patch.baseline.u.get.putResult).executableAddress())),
 955 *m_globalData,
 956 m_codeBlock->ownerExecutable(),
 957 needsStubLink);
936958
937959 // Track the stub we have created so that it will be deleted later.
938960 prototypeStructures->list[currentIndex].set(callFrame->globalData(), m_codeBlock->ownerExecutable(), stubRoutine, structure, chain, isDirect);

@@void JIT::privateCompileGetByIdChainList
940962 // Finally patch the jump to slow case back in the hot path to jump here instead.
941963 CodeLocationJump jumpLocation = stubInfo->hotPathBegin.jumpAtOffset(stubInfo->patch.baseline.u.get.structureCheck);
942964 RepatchBuffer repatchBuffer(m_codeBlock);
943  repatchBuffer.relink(jumpLocation, CodeLocationLabel(stubRoutine.code()));
 965 repatchBuffer.relink(jumpLocation, CodeLocationLabel(stubRoutine->code().code()));
944966}
945967
946968void JIT::privateCompileGetByIdChain(StructureStubInfo* stubInfo, Structure* structure, StructureChain* chain, size_t count, const Identifier& ident, const PropertySlot& slot, PropertyOffset cachedOffset, ReturnAddressPtr returnAddress, CallFrame* callFrame)

@@void JIT::privateCompileGetByIdChain(Str
9991021 patchBuffer.link(success, stubInfo->hotPathBegin.labelAtOffset(stubInfo->patch.baseline.u.get.putResult));
10001022
10011023 // Track the stub we have created so that it will be deleted later.
1002  CodeRef stubRoutine = FINALIZE_CODE(
1003  patchBuffer,
1004  ("Baseline JIT get_by_id chain stub for CodeBlock %p, return point %p",
1005  m_codeBlock, stubInfo->hotPathBegin.labelAtOffset(
1006  stubInfo->patch.baseline.u.get.putResult).executableAddress()));
 1024 RefPtr<JITStubRoutine> stubRoutine = createJITStubRoutine(
 1025 FINALIZE_CODE(
 1026 patchBuffer,
 1027 ("Baseline JIT get_by_id chain stub for CodeBlock %p, return point %p",
 1028 m_codeBlock, stubInfo->hotPathBegin.labelAtOffset(
 1029 stubInfo->patch.baseline.u.get.putResult).executableAddress())),
 1030 *m_globalData,
 1031 m_codeBlock->ownerExecutable(),
 1032 needsStubLink);
10071033 stubInfo->stubRoutine = stubRoutine;
10081034
10091035 // Finally patch the jump to slow case back in the hot path to jump here instead.
10101036 CodeLocationJump jumpLocation = stubInfo->hotPathBegin.jumpAtOffset(stubInfo->patch.baseline.u.get.structureCheck);
10111037 RepatchBuffer repatchBuffer(m_codeBlock);
1012  repatchBuffer.relink(jumpLocation, CodeLocationLabel(stubRoutine.code()));
 1038 repatchBuffer.relink(jumpLocation, CodeLocationLabel(stubRoutine->code().code()));
10131039
10141040 // We don't want to patch more than once - in future go to cti_op_put_by_id_generic.
10151041 repatchBuffer.relinkCallerToFunction(returnAddress, FunctionPtr(cti_op_get_by_id_proto_list));
122052

Source/JavaScriptCore/jit/JITStubRoutine.cpp

 1/*
 2 * Copyright (C) 2012 Apple Inc. All rights reserved.
 3 *
 4 * Redistribution and use in source and binary forms, with or without
 5 * modification, are permitted provided that the following conditions
 6 * are met:
 7 * 1. Redistributions of source code must retain the above copyright
 8 * notice, this list of conditions and the following disclaimer.
 9 * 2. Redistributions in binary form must reproduce the above copyright
 10 * notice, this list of conditions and the following disclaimer in the
 11 * documentation and/or other materials provided with the distribution.
 12 *
 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 24 */
 25
 26#include "config.h"
 27#include "JITStubRoutine.h"
 28
 29#if ENABLE(JIT)
 30
 31#include "JSObject.h"
 32#include "ScopeChain.h"
 33#include "SlotVisitor.h"
 34
 35namespace JSC {
 36
 37JITStubRoutine::~JITStubRoutine() { }
 38
 39void JITStubRoutine::observeZeroRefCount()
 40{
 41 ASSERT(!m_refCount);
 42 delete this;
 43}
 44
 45} // namespace JSC
 46
 47#endif // ENABLE(JIT)
 48
0

Source/JavaScriptCore/jit/JITStubRoutine.h

 1/*
 2 * Copyright (C) 2012 Apple Inc. All rights reserved.
 3 *
 4 * Redistribution and use in source and binary forms, with or without
 5 * modification, are permitted provided that the following conditions
 6 * are met:
 7 * 1. Redistributions of source code must retain the above copyright
 8 * notice, this list of conditions and the following disclaimer.
 9 * 2. Redistributions in binary form must reproduce the above copyright
 10 * notice, this list of conditions and the following disclaimer in the
 11 * documentation and/or other materials provided with the distribution.
 12 *
 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 24 */
 25
 26#ifndef JITStubRoutine_h
 27#define JITStubRoutine_h
 28
 29#include <wtf/Platform.h>
 30
 31#if ENABLE(JIT)
 32
 33#include "ExecutableAllocator.h"
 34#include "MacroAssemblerCodeRef.h"
 35#include <wtf/RefCounted.h>
 36#include <wtf/Vector.h>
 37
 38namespace JSC {
 39
 40class JITStubRoutineSet;
 41
 42// This is a base-class for JIT stub routines, and also the class you want
 43// to instantiate directly if you have a routine that does not need any
 44// help from the GC. If in doubt, use one of the other stub routines. But
 45// if you know for sure that the stub routine cannot be on the stack while
 46// someone triggers a stub routine reset, then using this will speed up
 47// memory reclamation. One case where a stub routine satisfies this
 48// condition is if it doesn't make any calls, to either C++ or JS code. In
 49// such a routine you know that it cannot be on the stack when anything
 50// interesting happens.
 51// See GCAwareJITStubRoutine.h for the other stub routines.
 52class JITStubRoutine {
 53 WTF_MAKE_NONCOPYABLE(JITStubRoutine);
 54 WTF_MAKE_FAST_ALLOCATED;
 55public:
 56 JITStubRoutine(const MacroAssemblerCodeRef& code)
 57 : m_code(code)
 58 , m_refCount(1)
 59 {
 60 }
 61
 62 // Use this if you want to pass a CodePtr to someone who insists on taking
 63 // a RefPtr<JITStubRoutine>.
 64 static PassRefPtr<JITStubRoutine> createSelfManagedRoutine(
 65 MacroAssemblerCodePtr rawCodePointer)
 66 {
 67 return adoptRef(new JITStubRoutine(MacroAssemblerCodeRef::createSelfManagedCodeRef(rawCodePointer)));
 68 }
 69
 70 virtual ~JITStubRoutine();
 71
 72 // MacroAssemblerCodeRef is copyable, but at the cost of reference
 73 // counting churn. Returning a reference is a good way of reducing
 74 // the churn.
 75 const MacroAssemblerCodeRef& code() const { return m_code; }
 76
 77 static MacroAssemblerCodePtr asCodePtr(PassRefPtr<JITStubRoutine> stubRoutine)
 78 {
 79 if (!stubRoutine)
 80 return MacroAssemblerCodePtr();
 81
 82 MacroAssemblerCodePtr result = stubRoutine->code().code();
 83 ASSERT(!!result);
 84 return result;
 85 }
 86
 87 void ref()
 88 {
 89 m_refCount++;
 90 }
 91
 92 void deref()
 93 {
 94 if (--m_refCount)
 95 return;
 96 observeZeroRefCount();
 97 }
 98
 99 // Helpers for the GC to determine how to deal with marking JIT stub
 100 // routines.
 101 uintptr_t startAddress() const { return m_code.executableMemory()->startAsInteger(); }
 102 uintptr_t endAddress() const { return m_code.executableMemory()->endAsInteger(); }
 103 static uintptr_t addressStep() { return jitAllocationGranule; }
 104
 105 static bool canPerformRangeFilter()
 106 {
 107#if ENABLE(EXECUTABLE_ALLOCATOR_FIXED)
 108 return true;
 109#else
 110 return false;
 111#endif
 112 }
 113 static uintptr_t filteringStartAddress()
 114 {
 115#if ENABLE(EXECUTABLE_ALLOCATOR_FIXED)
 116 return startOfFixedExecutableMemoryPool;
 117#else
 118 UNREACHABLE_FOR_PLATFORM();
 119 return 0;
 120#endif
 121 }
 122 static size_t filteringExtentSize()
 123 {
 124#if ENABLE(EXECUTABLE_ALLOCATOR_FIXED)
 125 return fixedExecutableMemoryPoolSize;
 126#else
 127 UNREACHABLE_FOR_PLATFORM();
 128 return 0;
 129#endif
 130 }
 131 static bool passesFilter(uintptr_t address)
 132 {
 133 if (!canPerformRangeFilter())
 134 return true;
 135
 136 if (address - filteringStartAddress() >= filteringExtentSize())
 137 return false;
 138
 139 return true;
 140 }
 141
 142protected:
 143 virtual void observeZeroRefCount();
 144
 145 MacroAssemblerCodeRef m_code;
 146 unsigned m_refCount;
 147};
 148
 149// Helper for the creation of simple stub routines that need no help from the GC.
 150#define FINALIZE_CODE_FOR_STUB(patchBuffer, dataLogArguments) \
 151 (adoptRef(new JITStubRoutine(FINALIZE_CODE((patchBuffer), dataLogArguments))))
 152
 153} // namespace JSC
 154
 155#endif // ENABLE(JIT)
 156
 157#endif // JITStubRoutine_h
 158
0

Source/JavaScriptCore/jit/JITStubs.cpp

@@DEFINE_STUB_FUNCTION(EncodedJSValue, op_
17221722
17231723 if (stubInfo->accessType == access_get_by_id_self) {
17241724 ASSERT(!stubInfo->stubRoutine);
1725  polymorphicStructureList = new PolymorphicAccessStructureList(callFrame->globalData(), codeBlock->ownerExecutable(), MacroAssemblerCodeRef(), stubInfo->u.getByIdSelf.baseObjectStructure.get(), true);
 1725 polymorphicStructureList = new PolymorphicAccessStructureList(callFrame->globalData(), codeBlock->ownerExecutable(), 0, stubInfo->u.getByIdSelf.baseObjectStructure.get(), true);
17261726 stubInfo->initGetByIdSelfList(polymorphicStructureList, 1);
17271727 } else {
17281728 polymorphicStructureList = stubInfo->u.getByIdSelfList.structureList;

@@static PolymorphicAccessStructureList* g
17481748 switch (stubInfo->accessType) {
17491749 case access_get_by_id_proto:
17501750 prototypeStructureList = new PolymorphicAccessStructureList(globalData, owner, stubInfo->stubRoutine, stubInfo->u.getByIdProto.baseObjectStructure.get(), stubInfo->u.getByIdProto.prototypeStructure.get(), true);
1751  stubInfo->stubRoutine = MacroAssemblerCodeRef();
 1751 stubInfo->stubRoutine.clear();
17521752 stubInfo->initGetByIdProtoList(prototypeStructureList, 2);
17531753 break;
17541754 case access_get_by_id_chain:
17551755 prototypeStructureList = new PolymorphicAccessStructureList(globalData, owner, stubInfo->stubRoutine, stubInfo->u.getByIdChain.baseObjectStructure.get(), stubInfo->u.getByIdChain.chain.get(), true);
1756  stubInfo->stubRoutine = MacroAssemblerCodeRef();
 1756 stubInfo->stubRoutine.clear();
17571757 stubInfo->initGetByIdProtoList(prototypeStructureList, 2);
17581758 break;
17591759 case access_get_by_id_proto_list:
122052

Source/WTF/wtf/MetaAllocatorHandle.h

@@private:
4545public:
4646 WTF_EXPORT_PRIVATE ~MetaAllocatorHandle();
4747
48  void* start()
 48 void* start() const
4949 {
5050 return m_start;
5151 }
5252
53  void* end()
 53 void* end() const
5454 {
55  return reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(m_start) + m_sizeInBytes);
 55 return reinterpret_cast<void*>(endAsInteger());
 56 }
 57
 58 uintptr_t startAsInteger() const
 59 {
 60 return reinterpret_cast<uintptr_t>(m_start);
 61 }
 62
 63 uintptr_t endAsInteger() const
 64 {
 65 return startAsInteger() + m_sizeInBytes;
5666 }
5767
58  size_t sizeInBytes()
 68 size_t sizeInBytes() const
5969 {
6070 return m_sizeInBytes;
6171 }
122052