Changeset 122768 in webkit
- Timestamp:
- Jul 16, 2012 3:08:21 PM (12 years ago)
- Location:
- trunk/Source/JavaScriptCore
- Files:
-
- 17 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ChangeLog
r122753 r122768 1 2012-07-15 Filip Pizlo <fpizlo@apple.com> 2 3 DFG PutById transition should handle storage allocation, and inline it 4 https://bugs.webkit.org/show_bug.cgi?id=91337 5 6 Reviewed by Oliver Hunt. 7 8 This enables the patching of DFG PutById to handle the out-of-line storage 9 allocation case. Furthermore, it inlines out-of-line storage allocation (and 10 reallocation) into the generated stubs. 11 12 To do this, this patch adds the ability to store the relevant register 13 allocation state (i.e. the set of in-use registers) in the structure stub 14 info so that the stub generation code can more flexibly select scratch 15 registers: sometimes it needs none, sometimes one - or sometimes up to 16 three. Moreover, to make the stub generation register allocation simple and 17 maintainable, this patch introduces a reusable scratch register allocator 18 class. This register allocator understands that some registers are in use by 19 the main path code and so must be spilled as necessary, other registers are 20 locked for use in the stub itself and so cannot even be spilled, while still 21 others may be allocated for scratch purposes. A scratch register that is 22 used must be spilled. If a register is locked, it cannot be used as a 23 scratch register. If a register is used, it can be used as a scratch 24 register so long as it is spilled. 25 26 This is a sub-1% speed-up on V8 and neutral elsewhere. 27 28 * GNUmakefile.list.am: 29 * JavaScriptCore.xcodeproj/project.pbxproj: 30 * assembler/MacroAssemblerCodeRef.h: 31 (FunctionPtr): 32 (JSC::FunctionPtr::FunctionPtr): 33 * bytecode/StructureStubInfo.h: 34 * dfg/DFGCCallHelpers.h: 35 (JSC::DFG::CCallHelpers::setupArgumentsWithExecState): 36 (CCallHelpers): 37 * dfg/DFGGPRInfo.h: 38 * dfg/DFGJITCompiler.cpp: 39 (JSC::DFG::JITCompiler::link): 40 * dfg/DFGJITCompiler.h: 41 (JSC::DFG::PropertyAccessRecord::PropertyAccessRecord): 42 (PropertyAccessRecord): 43 * dfg/DFGOperations.cpp: 44 * dfg/DFGOperations.h: 45 * dfg/DFGRegisterBank.h: 46 (JSC::DFG::RegisterBank::isInUse): 47 (RegisterBank): 48 * dfg/DFGRegisterSet.h: Added. 49 (DFG): 50 (RegisterSet): 51 (JSC::DFG::RegisterSet::RegisterSet): 52 (JSC::DFG::RegisterSet::asPOD): 53 (JSC::DFG::RegisterSet::copyInfo): 54 (JSC::DFG::RegisterSet::set): 55 (JSC::DFG::RegisterSet::setGPRByIndex): 56 (JSC::DFG::RegisterSet::clear): 57 (JSC::DFG::RegisterSet::get): 58 (JSC::DFG::RegisterSet::getGPRByIndex): 59 (JSC::DFG::RegisterSet::getFreeGPR): 60 (JSC::DFG::RegisterSet::setFPRByIndex): 61 (JSC::DFG::RegisterSet::getFPRByIndex): 62 (JSC::DFG::RegisterSet::setByIndex): 63 (JSC::DFG::RegisterSet::getByIndex): 64 (JSC::DFG::RegisterSet::numberOfSetGPRs): 65 (JSC::DFG::RegisterSet::numberOfSetFPRs): 66 (JSC::DFG::RegisterSet::numberOfSetRegisters): 67 (JSC::DFG::RegisterSet::setBit): 68 (JSC::DFG::RegisterSet::clearBit): 69 (JSC::DFG::RegisterSet::getBit): 70 * dfg/DFGRepatch.cpp: 71 (JSC::DFG::generateProtoChainAccessStub): 72 (JSC::DFG::tryCacheGetByID): 73 (JSC::DFG::tryBuildGetByIDList): 74 (JSC::DFG::emitPutReplaceStub): 75 (JSC::DFG::emitPutTransitionStub): 76 (JSC::DFG::tryCachePutByID): 77 (JSC::DFG::tryBuildPutByIdList): 78 * dfg/DFGScratchRegisterAllocator.h: Added. 79 (DFG): 80 (ScratchRegisterAllocator): 81 (JSC::DFG::ScratchRegisterAllocator::ScratchRegisterAllocator): 82 (JSC::DFG::ScratchRegisterAllocator::lock): 83 (JSC::DFG::ScratchRegisterAllocator::allocateScratch): 84 (JSC::DFG::ScratchRegisterAllocator::allocateScratchGPR): 85 (JSC::DFG::ScratchRegisterAllocator::allocateScratchFPR): 86 (JSC::DFG::ScratchRegisterAllocator::didReuseRegisters): 87 (JSC::DFG::ScratchRegisterAllocator::preserveReusedRegistersByPushing): 88 (JSC::DFG::ScratchRegisterAllocator::restoreReusedRegistersByPopping): 89 (JSC::DFG::ScratchRegisterAllocator::desiredScratchBufferSize): 90 (JSC::DFG::ScratchRegisterAllocator::preserveUsedRegistersToScratchBuffer): 91 (JSC::DFG::ScratchRegisterAllocator::restoreUsedRegistersFromScratchBuffer): 92 * dfg/DFGSpeculativeJIT.h: 93 (SpeculativeJIT): 94 (JSC::DFG::SpeculativeJIT::usedRegisters): 95 * dfg/DFGSpeculativeJIT32_64.cpp: 96 (JSC::DFG::SpeculativeJIT::cachedGetById): 97 (JSC::DFG::SpeculativeJIT::cachedPutById): 98 (JSC::DFG::SpeculativeJIT::compile): 99 * dfg/DFGSpeculativeJIT64.cpp: 100 (JSC::DFG::SpeculativeJIT::cachedGetById): 101 (JSC::DFG::SpeculativeJIT::cachedPutById): 102 (JSC::DFG::SpeculativeJIT::compile): 103 * heap/CopiedAllocator.h: 104 (CopiedAllocator): 105 (JSC::CopiedAllocator::fastPathShouldSucceed): 106 (JSC): 107 1 108 2012-07-16 Patrick Gansterer <paroga@webkit.org> 2 109 -
trunk/Source/JavaScriptCore/GNUmakefile.list.am
r122650 r122768 217 217 Source/JavaScriptCore/dfg/DFGRedundantPhiEliminationPhase.h \ 218 218 Source/JavaScriptCore/dfg/DFGRegisterBank.h \ 219 Source/JavaScriptCore/dfg/DFGRegisterSet.h \ 219 220 Source/JavaScriptCore/dfg/DFGRepatch.cpp \ 220 221 Source/JavaScriptCore/dfg/DFGRepatch.h \ 221 222 Source/JavaScriptCore/dfg/DFGScoreBoard.h \ 223 Source/JavaScriptCore/dfg/DFGScratchRegisterAllocator.h \ 222 224 Source/JavaScriptCore/dfg/DFGSilentRegisterSavePlan.h \ 223 225 Source/JavaScriptCore/dfg/DFGSlowPathGenerator.h \ -
trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
r122544 r122768 151 151 0F766D3815AE4A1C008F363E /* StructureStubClearingWatchpoint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F766D3615AE4A1A008F363E /* StructureStubClearingWatchpoint.cpp */; }; 152 152 0F766D3915AE4A1F008F363E /* StructureStubClearingWatchpoint.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F766D3715AE4A1A008F363E /* StructureStubClearingWatchpoint.h */; settings = {ATTRIBUTES = (Private, ); }; }; 153 0F766D4415B2A3C0008F363E /* DFGRegisterSet.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F766D4215B2A3BD008F363E /* DFGRegisterSet.h */; settings = {ATTRIBUTES = (Private, ); }; }; 154 0F766D4615B3701F008F363E /* DFGScratchRegisterAllocator.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F766D4515B3701D008F363E /* DFGScratchRegisterAllocator.h */; settings = {ATTRIBUTES = (Private, ); }; }; 153 155 0F7700921402FF3C0078EB39 /* SamplingCounter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F7700911402FF280078EB39 /* SamplingCounter.cpp */; }; 154 156 0F7B294A14C3CD29007C3DB1 /* DFGCCallHelpers.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F7B294814C3CD23007C3DB1 /* DFGCCallHelpers.h */; settings = {ATTRIBUTES = (Private, ); }; }; … … 896 898 0F766D3615AE4A1A008F363E /* StructureStubClearingWatchpoint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StructureStubClearingWatchpoint.cpp; sourceTree = "<group>"; }; 897 899 0F766D3715AE4A1A008F363E /* StructureStubClearingWatchpoint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StructureStubClearingWatchpoint.h; sourceTree = "<group>"; }; 900 0F766D4215B2A3BD008F363E /* DFGRegisterSet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGRegisterSet.h; path = dfg/DFGRegisterSet.h; sourceTree = "<group>"; }; 901 0F766D4515B3701D008F363E /* DFGScratchRegisterAllocator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGScratchRegisterAllocator.h; path = dfg/DFGScratchRegisterAllocator.h; sourceTree = "<group>"; }; 898 902 0F77008E1402FDD60078EB39 /* SamplingCounter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SamplingCounter.h; sourceTree = "<group>"; }; 899 903 0F7700911402FF280078EB39 /* SamplingCounter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SamplingCounter.cpp; sourceTree = "<group>"; }; … … 2305 2309 0A4337BD1506219B00991C95 /* DFGRedundantPhiEliminationPhase.h */, 2306 2310 86EC9DC11328DF82002B2AD7 /* DFGRegisterBank.h */, 2311 0F766D4215B2A3BD008F363E /* DFGRegisterSet.h */, 2307 2312 86BB09BE138E381B0056702F /* DFGRepatch.cpp */, 2308 2313 86BB09BF138E381B0056702F /* DFGRepatch.h */, 2309 2314 86ECA3F9132DF25A002B2AD7 /* DFGScoreBoard.h */, 2315 0F766D4515B3701D008F363E /* DFGScratchRegisterAllocator.h */, 2310 2316 0F1E3A65153A21DF000F9456 /* DFGSilentRegisterSavePlan.h */, 2311 2317 0F1E3A501537C2CB000F9456 /* DFGSlowPathGenerator.h */, … … 2851 2857 0F766D3515AE253B008F363E /* JumpReplacementWatchpoint.h in Headers */, 2852 2858 0F766D3915AE4A1F008F363E /* StructureStubClearingWatchpoint.h in Headers */, 2859 0F766D4415B2A3C0008F363E /* DFGRegisterSet.h in Headers */, 2860 0F766D4615B3701F008F363E /* DFGScratchRegisterAllocator.h in Headers */, 2853 2861 ); 2854 2862 runOnlyForDeploymentPostprocessing = 0; -
trunk/Source/JavaScriptCore/assembler/MacroAssemblerCodeRef.h
r120786 r122768 127 127 } 128 128 129 template<typename returnType, typename argType1, typename argType2, typename argType3, typename argType4, typename argType5> 130 FunctionPtr(returnType(*value)(argType1, argType2, argType3, argType4, argType5)) 131 : m_value((void*)value) 132 { 133 ASSERT_VALID_CODE_POINTER(m_value); 134 } 135 129 136 // MSVC doesn't seem to treat functions with different calling conventions as 130 137 // different types; these methods already defined for fastcall, below. -
trunk/Source/JavaScriptCore/bytecode/StructureStubInfo.h
r122544 r122768 32 32 33 33 #include "CodeOrigin.h" 34 #include "DFGRegisterSet.h" 34 35 #include "Instruction.h" 35 36 #include "JITStubRoutine.h" … … 213 214 #endif 214 215 int8_t valueGPR; 215 int8_t scratchGPR;216 DFG::RegisterSetPOD usedRegisters; 216 217 int32_t deltaCallToDone; 217 218 int32_t deltaCallToStorageLoad; -
trunk/Source/JavaScriptCore/dfg/DFGCCallHelpers.h
r122392 r122768 230 230 } 231 231 232 ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, TrustedImmPtr arg2, TrustedImm32 arg3, GPRReg arg4) 233 { 234 resetCallArguments(); 235 addCallArgument(GPRInfo::callFrameRegister); 236 addCallArgument(arg1); 237 addCallArgument(arg2); 238 addCallArgument(arg3); 239 addCallArgument(arg4); 240 } 241 242 ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, TrustedImmPtr arg2, TrustedImm32 arg3, GPRReg arg4, GPRReg arg5) 243 { 244 resetCallArguments(); 245 addCallArgument(GPRInfo::callFrameRegister); 246 addCallArgument(arg1); 247 addCallArgument(arg2); 248 addCallArgument(arg3); 249 addCallArgument(arg4); 250 addCallArgument(arg5); 251 } 252 232 253 ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, GPRReg arg3, GPRReg arg4) 233 254 { … … 643 664 } 644 665 666 ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, TrustedImmPtr arg2, TrustedImm32 arg3, GPRReg arg4) 667 { 668 poke(arg4); 669 setupArgumentsWithExecState(arg1, arg2, arg3); 670 } 671 672 ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, TrustedImmPtr arg2, TrustedImm32 arg3, GPRReg arg4, GPRReg arg5) 673 { 674 poke(arg5, 1); 675 poke(arg4); 676 setupArgumentsWithExecState(arg1, arg2, arg3); 677 } 678 645 679 ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, TrustedImm32 arg3, TrustedImm32 arg4) 646 680 { … … 722 756 723 757 #endif // NUMBER_OF_ARGUMENT_REGISTERS == 4 758 759 #if NUMBER_OF_ARGUMENT_REGISTERS >= 5 760 ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, TrustedImmPtr arg2, TrustedImm32 arg3, GPRReg arg4) 761 { 762 setupTwoStubArgs<GPRInfo::argumentGPR1, GPRInfo::argumentGPR4>(arg1, arg4); 763 move(arg2, GPRInfo::argumentGPR2); 764 move(arg3, GPRInfo::argumentGPR3); 765 move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0); 766 } 767 #endif 724 768 725 769 void setupResults(GPRReg destA, GPRReg destB) -
trunk/Source/JavaScriptCore/dfg/DFGGPRInfo.h
r122392 r122768 27 27 #define DFGGPRInfo_h 28 28 29 #include <wtf/Platform.h> 30 29 31 #if ENABLE(DFG_JIT) 30 32 31 #include <assembler/MacroAssembler.h>32 #include <dfg/DFGRegisterBank.h>33 #include "DFGRegisterBank.h" 34 #include "MacroAssembler.h" 33 35 34 36 namespace JSC { namespace DFG { -
trunk/Source/JavaScriptCore/dfg/DFGJITCompiler.cpp
r122392 r122768 180 180 info.patch.dfg.valueGPR = m_propertyAccesses[i].m_valueGPR; 181 181 #endif 182 info.patch.dfg.scratchGPR = m_propertyAccesses[i].m_scratchGPR;182 m_propertyAccesses[i].m_usedRegisters.copyInfo(info.patch.dfg.usedRegisters); 183 183 info.patch.dfg.registersFlushed = m_propertyAccesses[i].m_registerMode == PropertyAccessRecord::RegistersFlushed; 184 184 } -
trunk/Source/JavaScriptCore/dfg/DFGJITCompiler.h
r122392 r122768 36 36 #include "DFGGraph.h" 37 37 #include "DFGRegisterBank.h" 38 #include "DFGRegisterSet.h" 38 39 #include "JITCode.h" 39 40 #include "LinkBuffer.h" … … 170 171 int8_t baseGPR, 171 172 int8_t valueGPR, 172 int8_t scratchGPR,173 const RegisterSet& usedRegisters, 173 174 RegisterMode registerMode = RegistersInUse) 174 175 #elif USE(JSVALUE32_64) … … 185 186 int8_t valueTagGPR, 186 187 int8_t valueGPR, 187 int8_t scratchGPR,188 const RegisterSet& usedRegisters, 188 189 RegisterMode registerMode = RegistersInUse) 189 190 #endif … … 205 206 #endif 206 207 , m_valueGPR(valueGPR) 207 , m_ scratchGPR(scratchGPR)208 , m_usedRegisters(usedRegisters) 208 209 , m_registerMode(registerMode) 209 210 { … … 227 228 #endif 228 229 int8_t m_valueGPR; 229 int8_t m_scratchGPR;230 RegisterSet m_usedRegisters; 230 231 RegisterMode m_registerMode; 231 232 }; -
trunk/Source/JavaScriptCore/dfg/DFGOperations.cpp
r122392 r122768 1231 1231 { 1232 1232 return jsIsFunctionType(JSValue::decode(value)); 1233 } 1234 1235 void DFG_OPERATION operationReallocateStorageAndFinishPut(ExecState* exec, JSObject* base, Structure* structure, PropertyOffset offset, EncodedJSValue value) 1236 { 1237 JSGlobalData& globalData = exec->globalData(); 1238 ASSERT(structure->outOfLineCapacity() > base->structure()->outOfLineCapacity()); 1239 ASSERT(!globalData.heap.storageAllocator().fastPathShouldSucceed(structure->outOfLineCapacity() * sizeof(JSValue))); 1240 base->setStructureAndReallocateStorageIfNecessary(globalData, structure); 1241 base->putDirectOffset(globalData, offset, JSValue::decode(value)); 1233 1242 } 1234 1243 -
trunk/Source/JavaScriptCore/dfg/DFGOperations.h
r121280 r122768 181 181 size_t DFG_OPERATION operationIsObject(EncodedJSValue) WTF_INTERNAL; 182 182 size_t DFG_OPERATION operationIsFunction(EncodedJSValue) WTF_INTERNAL; 183 void DFG_OPERATION operationReallocateStorageAndFinishPut(ExecState*, JSObject*, Structure*, PropertyOffset, EncodedJSValue) WTF_INTERNAL; 183 184 184 185 // This method is used to lookup an exception hander, keyed by faultLocation, which is -
trunk/Source/JavaScriptCore/dfg/DFGRegisterBank.h
r107499 r122768 227 227 } 228 228 229 bool isInUse(RegID reg) const 230 { 231 return isLocked(reg) || name(reg) != InvalidVirtualRegister; 232 } 233 229 234 #ifndef NDEBUG 230 235 void dump() -
trunk/Source/JavaScriptCore/dfg/DFGRepatch.cpp
r122595 r122768 30 30 31 31 #include "DFGCCallHelpers.h" 32 #include "DFGScratchRegisterAllocator.h" 32 33 #include "DFGSpeculativeJIT.h" 33 34 #include "DFGThunks.h" … … 162 163 #endif 163 164 GPRReg resultGPR = static_cast<GPRReg>(stubInfo.patch.dfg.valueGPR); 164 GPRReg scratchGPR = static_cast<GPRReg>(stubInfo.patch.dfg.scratchGPR);165 GPRReg scratchGPR = RegisterSet(stubInfo.patch.dfg.usedRegisters).getFreeGPR(); 165 166 bool needToRestoreScratch = false; 166 167 … … 232 233 #endif 233 234 GPRReg resultGPR = static_cast<GPRReg>(stubInfo.patch.dfg.valueGPR); 234 GPRReg scratchGPR = static_cast<GPRReg>(stubInfo.patch.dfg.scratchGPR);235 GPRReg scratchGPR = RegisterSet(stubInfo.patch.dfg.usedRegisters).getFreeGPR(); 235 236 bool needToRestoreScratch = false; 236 237 … … 385 386 #endif 386 387 GPRReg resultGPR = static_cast<GPRReg>(stubInfo.patch.dfg.valueGPR); 387 GPRReg scratchGPR = static_cast<GPRReg>(stubInfo.patch.dfg.scratchGPR);388 GPRReg scratchGPR = RegisterSet(stubInfo.patch.dfg.usedRegisters).getFreeGPR(); 388 389 389 390 CCallHelpers stubJit(globalData, codeBlock); … … 630 631 #endif 631 632 GPRReg valueGPR = static_cast<GPRReg>(stubInfo.patch.dfg.valueGPR); 632 GPRReg scratchGPR = static_cast<GPRReg>(stubInfo.patch.dfg.scratchGPR);633 GPRReg scratchGPR = RegisterSet(stubInfo.patch.dfg.usedRegisters).getFreeGPR(); 633 634 bool needToRestoreScratch = false; 634 635 #if ENABLE(GGC) || ENABLE(WRITE_BARRIER_PROFILING) … … 723 724 #endif 724 725 GPRReg valueGPR = static_cast<GPRReg>(stubInfo.patch.dfg.valueGPR); 725 GPRReg scratchGPR = static_cast<GPRReg>(stubInfo.patch.dfg.scratchGPR); 726 bool needToRestoreScratch = false; 727 728 ASSERT(scratchGPR != baseGPR); 729 730 MacroAssembler stubJit; 731 726 727 ScratchRegisterAllocator allocator(stubInfo.patch.dfg.usedRegisters); 728 allocator.lock(baseGPR); 729 #if USE(JSVALUE32_64) 730 allocator.lock(valueTagGPR); 731 #endif 732 allocator.lock(valueGPR); 733 734 CCallHelpers stubJit(globalData); 735 736 GPRReg scratchGPR1 = allocator.allocateScratchGPR(); 737 ASSERT(scratchGPR1 != baseGPR); 738 ASSERT(scratchGPR1 != valueGPR); 739 740 bool needSecondScratch = false; 741 bool needThirdScratch = false; 742 #if ENABLE(GGC) || ENABLE(WRITE_BARRIER_PROFILING) 743 needSecondScratch = true; 744 #endif 745 if (structure->outOfLineCapacity() != oldStructure->outOfLineCapacity() 746 && oldStructure->outOfLineCapacity()) { 747 needSecondScratch = true; 748 needThirdScratch = true; 749 } 750 751 GPRReg scratchGPR2; 752 if (needSecondScratch) { 753 scratchGPR2 = allocator.allocateScratchGPR(); 754 ASSERT(scratchGPR2 != baseGPR); 755 ASSERT(scratchGPR2 != valueGPR); 756 ASSERT(scratchGPR2 != scratchGPR1); 757 } else 758 scratchGPR2 = InvalidGPRReg; 759 GPRReg scratchGPR3; 760 if (needThirdScratch) { 761 scratchGPR3 = allocator.allocateScratchGPR(); 762 ASSERT(scratchGPR3 != baseGPR); 763 ASSERT(scratchGPR3 != valueGPR); 764 ASSERT(scratchGPR3 != scratchGPR1); 765 ASSERT(scratchGPR3 != scratchGPR2); 766 } else 767 scratchGPR3 = InvalidGPRReg; 768 769 allocator.preserveReusedRegistersByPushing(stubJit); 770 732 771 MacroAssembler::JumpList failureCases; 733 772 734 if (scratchGPR == InvalidGPRReg) {735 scratchGPR = SpeculativeJIT::selectScratchGPR(baseGPR, valueGPR);736 stubJit.push(scratchGPR);737 needToRestoreScratch = true;738 }739 740 773 ASSERT(oldStructure->transitionWatchpointSetHasBeenInvalidated()); 741 774 … … 744 777 addStructureTransitionCheck( 745 778 oldStructure->storedPrototype(), exec->codeBlock(), stubInfo, stubJit, failureCases, 746 scratchGPR );779 scratchGPR1); 747 780 748 781 if (putKind == NotDirect) { … … 750 783 addStructureTransitionCheck( 751 784 (*it)->storedPrototype(), exec->codeBlock(), stubInfo, stubJit, failureCases, 752 scratchGPR );785 scratchGPR1); 753 786 } 754 787 } 755 788 756 789 #if ENABLE(GGC) || ENABLE(WRITE_BARRIER_PROFILING) 790 ASSERT(needSecondScratch); 791 ASSERT(scratchGPR2 != InvalidGPRReg); 757 792 // Must always emit this write barrier as the structure transition itself requires it 758 GPRReg scratch2 = SpeculativeJIT::selectScratchGPR(baseGPR, valueGPR, scratchGPR); 759 stubJit.push(scratch2); 760 SpeculativeJIT::writeBarrier(stubJit, baseGPR, scratchGPR, scratch2, WriteBarrierForPropertyAccess); 761 stubJit.pop(scratch2); 762 #endif 793 SpeculativeJIT::writeBarrier(stubJit, baseGPR, scratchGPR1, scratchGPR2, WriteBarrierForPropertyAccess); 794 #endif 795 796 MacroAssembler::JumpList slowPath; 797 798 bool scratchGPR1HasStorage = false; 799 800 if (structure->outOfLineCapacity() != oldStructure->outOfLineCapacity()) { 801 size_t newSize = structure->outOfLineCapacity() * sizeof(JSValue); 802 CopiedAllocator* copiedAllocator = &globalData->heap.storageAllocator(); 803 804 if (!oldStructure->outOfLineCapacity()) { 805 stubJit.loadPtr(&copiedAllocator->m_currentRemaining, scratchGPR1); 806 slowPath.append(stubJit.branchSubPtr(MacroAssembler::Signed, MacroAssembler::TrustedImm32(newSize), scratchGPR1)); 807 stubJit.storePtr(scratchGPR1, &copiedAllocator->m_currentRemaining); 808 stubJit.negPtr(scratchGPR1); 809 stubJit.addPtr(MacroAssembler::AbsoluteAddress(&copiedAllocator->m_currentPayloadEnd), scratchGPR1); 810 stubJit.subPtr(MacroAssembler::TrustedImm32(newSize), scratchGPR1); 811 } else { 812 size_t oldSize = oldStructure->outOfLineCapacity() * sizeof(JSValue); 813 ASSERT(newSize > oldSize); 814 815 // Optimistically assume that the old storage was the very last thing 816 // allocated. 817 stubJit.loadPtr(MacroAssembler::Address(baseGPR, JSObject::offsetOfOutOfLineStorage()), scratchGPR3); 818 stubJit.loadPtr(&copiedAllocator->m_currentPayloadEnd, scratchGPR2); 819 stubJit.loadPtr(&copiedAllocator->m_currentRemaining, scratchGPR1); 820 stubJit.subPtr(scratchGPR1, scratchGPR2); 821 stubJit.subPtr(MacroAssembler::TrustedImm32(oldSize), scratchGPR2); 822 MacroAssembler::Jump needFullRealloc = 823 stubJit.branchPtr(MacroAssembler::NotEqual, scratchGPR2, scratchGPR3); 824 slowPath.append(stubJit.branchSubPtr(MacroAssembler::Signed, MacroAssembler::TrustedImm32(newSize - oldSize), scratchGPR1)); 825 stubJit.storePtr(scratchGPR1, &copiedAllocator->m_currentRemaining); 826 stubJit.move(scratchGPR2, scratchGPR1); 827 MacroAssembler::Jump doneRealloc = stubJit.jump(); 828 829 needFullRealloc.link(&stubJit); 830 slowPath.append(stubJit.branchSubPtr(MacroAssembler::Signed, MacroAssembler::TrustedImm32(newSize), scratchGPR1)); 831 stubJit.storePtr(scratchGPR1, &copiedAllocator->m_currentRemaining); 832 stubJit.negPtr(scratchGPR1); 833 stubJit.addPtr(MacroAssembler::AbsoluteAddress(&copiedAllocator->m_currentPayloadEnd), scratchGPR1); 834 stubJit.subPtr(MacroAssembler::TrustedImm32(newSize), scratchGPR1); 835 // We have scratchGPR1 = new storage, scratchGPR3 = old storage, scratchGPR2 = available 836 for (size_t offset = 0; offset < oldSize; offset += sizeof(JSValue)) { 837 stubJit.loadPtr(MacroAssembler::Address(scratchGPR3, offset), scratchGPR2); 838 stubJit.storePtr(scratchGPR2, MacroAssembler::Address(scratchGPR1, offset)); 839 } 840 841 doneRealloc.link(&stubJit); 842 } 843 844 stubJit.storePtr(scratchGPR1, MacroAssembler::Address(baseGPR, JSObject::offsetOfOutOfLineStorage())); 845 scratchGPR1HasStorage = true; 846 } 763 847 764 848 stubJit.storePtr(MacroAssembler::TrustedImmPtr(structure), MacroAssembler::Address(baseGPR, JSCell::structureOffset())); … … 767 851 stubJit.storePtr(valueGPR, MacroAssembler::Address(baseGPR, JSObject::offsetOfInlineStorage() + offsetInInlineStorage(slot.cachedOffset()) * sizeof(JSValue))); 768 852 else { 769 stubJit.loadPtr(MacroAssembler::Address(baseGPR, JSObject::offsetOfOutOfLineStorage()), scratchGPR); 770 stubJit.storePtr(valueGPR, MacroAssembler::Address(scratchGPR, offsetInOutOfLineStorage(slot.cachedOffset()) * sizeof(JSValue))); 853 if (!scratchGPR1HasStorage) 854 stubJit.loadPtr(MacroAssembler::Address(baseGPR, JSObject::offsetOfOutOfLineStorage()), scratchGPR1); 855 stubJit.storePtr(valueGPR, MacroAssembler::Address(scratchGPR1, offsetInOutOfLineStorage(slot.cachedOffset()) * sizeof(JSValue))); 771 856 } 772 857 #elif USE(JSVALUE32_64) … … 775 860 stubJit.store32(valueTagGPR, MacroAssembler::Address(baseGPR, JSObject::offsetOfInlineStorage() + offsetInInlineStorage(slot.cachedOffset()) * sizeof(JSValue) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag))); 776 861 } else { 777 stubJit.loadPtr(MacroAssembler::Address(baseGPR, JSObject::offsetOfOutOfLineStorage()), scratchGPR); 778 stubJit.store32(valueGPR, MacroAssembler::Address(scratchGPR, offsetInOutOfLineStorage(slot.cachedOffset()) * sizeof(JSValue) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload))); 779 stubJit.store32(valueTagGPR, MacroAssembler::Address(scratchGPR, offsetInOutOfLineStorage(slot.cachedOffset()) * sizeof(JSValue) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag))); 862 if (!scratchGPR1HasStorage) 863 stubJit.loadPtr(MacroAssembler::Address(baseGPR, JSObject::offsetOfOutOfLineStorage()), scratchGPR1); 864 stubJit.store32(valueGPR, MacroAssembler::Address(scratchGPR1, offsetInOutOfLineStorage(slot.cachedOffset()) * sizeof(JSValue) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload))); 865 stubJit.store32(valueTagGPR, MacroAssembler::Address(scratchGPR1, offsetInOutOfLineStorage(slot.cachedOffset()) * sizeof(JSValue) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag))); 780 866 } 781 867 #endif … … 784 870 MacroAssembler::Jump failure; 785 871 786 if ( needToRestoreScratch) {787 stubJit.pop(scratchGPR);872 if (allocator.didReuseRegisters()) { 873 allocator.restoreReusedRegistersByPopping(stubJit); 788 874 success = stubJit.jump(); 789 875 790 876 failureCases.link(&stubJit); 791 stubJit.pop(scratchGPR);877 allocator.restoreReusedRegistersByPopping(stubJit); 792 878 failure = stubJit.jump(); 793 879 } else 794 880 success = stubJit.jump(); 795 881 882 MacroAssembler::Call operationCall; 883 MacroAssembler::Jump successInSlowPath; 884 885 if (structure->outOfLineCapacity() != oldStructure->outOfLineCapacity()) { 886 slowPath.link(&stubJit); 887 888 allocator.restoreReusedRegistersByPopping(stubJit); 889 ScratchBuffer* scratchBuffer = globalData->scratchBufferForSize(allocator.desiredScratchBufferSize()); 890 allocator.preserveUsedRegistersToScratchBuffer(stubJit, scratchBuffer, scratchGPR1); 891 #if USE(JSVALUE64) 892 stubJit.setupArgumentsWithExecState(baseGPR, MacroAssembler::TrustedImmPtr(structure), MacroAssembler::TrustedImm32(slot.cachedOffset()), valueGPR); 893 #else 894 stubJit.setupArgumentsWithExecState(baseGPR, MacroAssembler::TrustedImmPtr(structure), MacroAssembler::TrustedImm32(slot.cachedOffset()), valueTagGPR, valueGPR); 895 #endif 896 operationCall = stubJit.call(); 897 allocator.restoreUsedRegistersFromScratchBuffer(stubJit, scratchBuffer, scratchGPR1); 898 successInSlowPath = stubJit.jump(); 899 } 900 796 901 LinkBuffer patchBuffer(*globalData, &stubJit, exec->codeBlock()); 797 902 patchBuffer.link(success, stubInfo.callReturnLocation.labelAtOffset(stubInfo.patch.dfg.deltaCallToDone)); 798 if ( needToRestoreScratch)903 if (allocator.didReuseRegisters()) 799 904 patchBuffer.link(failure, failureLabel); 800 905 else 801 906 patchBuffer.link(failureCases, failureLabel); 802 803 stubRoutine = FINALIZE_CODE_FOR_STUB( 804 patchBuffer, 805 ("DFG PutById transition stub for CodeBlock %p, return point %p", 806 exec->codeBlock(), stubInfo.callReturnLocation.labelAtOffset( 807 stubInfo.patch.dfg.deltaCallToDone).executableAddress())); 907 if (structure->outOfLineCapacity() != oldStructure->outOfLineCapacity()) { 908 patchBuffer.link(operationCall, operationReallocateStorageAndFinishPut); 909 patchBuffer.link(successInSlowPath, stubInfo.callReturnLocation.labelAtOffset(stubInfo.patch.dfg.deltaCallToDone)); 910 } 911 912 stubRoutine = 913 createJITStubRoutine( 914 FINALIZE_CODE( 915 patchBuffer, 916 ("DFG PutById transition stub for CodeBlock %p, return point %p", 917 exec->codeBlock(), stubInfo.callReturnLocation.labelAtOffset( 918 stubInfo.patch.dfg.deltaCallToDone).executableAddress())), 919 *globalData, 920 exec->codeBlock()->ownerExecutable(), 921 structure->outOfLineCapacity() != oldStructure->outOfLineCapacity(), 922 structure); 808 923 } 809 924 … … 830 945 return false; 831 946 832 // skip optimizing the case where we need a realloc 833 if (oldStructure->outOfLineCapacity() != structure->outOfLineCapacity()) 947 // Skip optimizing the case where we need a realloc, if we don't have 948 // enough registers to make it happen. 949 if (GPRInfo::numberOfRegisters < 6 950 && oldStructure->outOfLineCapacity() != structure->outOfLineCapacity() 951 && oldStructure->outOfLineCapacity()) 834 952 return false; 835 953 … … 893 1011 return false; 894 1012 895 // skip optimizing the case where we need a realloc 896 if (oldStructure->outOfLineCapacity() != structure->outOfLineCapacity()) 1013 // Skip optimizing the case where we need a realloc, if we don't have 1014 // enough registers to make it happen. 1015 if (GPRInfo::numberOfRegisters < 6 1016 && oldStructure->outOfLineCapacity() != structure->outOfLineCapacity() 1017 && oldStructure->outOfLineCapacity()) 897 1018 return false; 898 1019 -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h
r122392 r122768 272 272 { 273 273 use(nodeUse.index()); 274 } 275 276 RegisterSet usedRegisters() 277 { 278 RegisterSet result; 279 for (unsigned i = GPRInfo::numberOfRegisters; i--;) { 280 GPRReg gpr = GPRInfo::toRegister(i); 281 if (m_gprs.isInUse(gpr)) 282 result.set(gpr); 283 } 284 for (unsigned i = FPRInfo::numberOfRegisters; i--;) { 285 FPRReg fpr = FPRInfo::toRegister(i); 286 if (m_fprs.isInUse(fpr)) 287 result.set(fpr); 288 } 289 return result; 274 290 } 275 291 … … 943 959 944 960 #if USE(JSVALUE64) 945 void cachedGetById(CodeOrigin, GPRReg baseGPR, GPRReg resultGPR, GPRReg scratchGPR,unsigned identifierNumber, JITCompiler::Jump slowPathTarget = JITCompiler::Jump(), SpillRegistersMode = NeedToSpill);961 void cachedGetById(CodeOrigin, GPRReg baseGPR, GPRReg resultGPR, unsigned identifierNumber, JITCompiler::Jump slowPathTarget = JITCompiler::Jump(), SpillRegistersMode = NeedToSpill); 946 962 void cachedPutById(CodeOrigin, GPRReg base, GPRReg value, Edge valueUse, GPRReg scratchGPR, unsigned identifierNumber, PutKind, JITCompiler::Jump slowPathTarget = JITCompiler::Jump()); 947 963 #elif USE(JSVALUE32_64) 948 void cachedGetById(CodeOrigin, GPRReg baseTagGPROrNone, GPRReg basePayloadGPR, GPRReg resultTagGPR, GPRReg resultPayloadGPR, GPRReg scratchGPR,unsigned identifierNumber, JITCompiler::Jump slowPathTarget = JITCompiler::Jump(), SpillRegistersMode = NeedToSpill);964 void cachedGetById(CodeOrigin, GPRReg baseTagGPROrNone, GPRReg basePayloadGPR, GPRReg resultTagGPR, GPRReg resultPayloadGPR, unsigned identifierNumber, JITCompiler::Jump slowPathTarget = JITCompiler::Jump(), SpillRegistersMode = NeedToSpill); 949 965 void cachedPutById(CodeOrigin, GPRReg basePayloadGPR, GPRReg valueTagGPR, GPRReg valuePayloadGPR, Edge valueUse, GPRReg scratchGPR, unsigned identifierNumber, PutKind, JITCompiler::Jump slowPathTarget = JITCompiler::Jump()); 950 966 #endif -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp
r122678 r122768 504 504 } 505 505 506 void SpeculativeJIT::cachedGetById(CodeOrigin codeOrigin, GPRReg baseTagGPROrNone, GPRReg basePayloadGPR, GPRReg resultTagGPR, GPRReg resultPayloadGPR, GPRReg scratchGPR,unsigned identifierNumber, JITCompiler::Jump slowPathTarget, SpillRegistersMode spillMode)506 void SpeculativeJIT::cachedGetById(CodeOrigin codeOrigin, GPRReg baseTagGPROrNone, GPRReg basePayloadGPR, GPRReg resultTagGPR, GPRReg resultPayloadGPR, unsigned identifierNumber, JITCompiler::Jump slowPathTarget, SpillRegistersMode spillMode) 507 507 { 508 508 JITCompiler::DataLabelPtr structureToCompare; … … 554 554 tagLoadWithPatch, payloadLoadWithPatch, slowPath.get(), doneLabel, 555 555 safeCast<int8_t>(basePayloadGPR), safeCast<int8_t>(resultTagGPR), 556 safeCast<int8_t>(resultPayloadGPR), safeCast<int8_t>(scratchGPR),556 safeCast<int8_t>(resultPayloadGPR), usedRegisters(), 557 557 spillMode == NeedToSpill ? PropertyAccessRecord::RegistersInUse : PropertyAccessRecord::RegistersFlushed)); 558 558 addSlowPathGenerator(slowPath.release()); … … 596 596 basePayloadGPR, identifier(identifierNumber)); 597 597 } 598 RegisterSet currentlyUsedRegisters = usedRegisters(); 599 currentlyUsedRegisters.clear(scratchGPR); 600 ASSERT(currentlyUsedRegisters.get(basePayloadGPR)); 601 ASSERT(currentlyUsedRegisters.get(valueTagGPR)); 602 ASSERT(currentlyUsedRegisters.get(valuePayloadGPR)); 598 603 m_jit.addPropertyAccess( 599 604 PropertyAccessRecord( … … 603 608 slowPath.get(), doneLabel, safeCast<int8_t>(basePayloadGPR), 604 609 safeCast<int8_t>(valueTagGPR), safeCast<int8_t>(valuePayloadGPR), 605 safeCast<int8_t>(scratchGPR)));610 usedRegisters())); 606 611 addSlowPathGenerator(slowPath.release()); 607 612 } … … 3299 3304 GPRReg resultTagGPR = resultTag.gpr(); 3300 3305 GPRReg resultPayloadGPR = resultPayload.gpr(); 3301 GPRReg scratchGPR; 3302 3303 if (resultTagGPR == baseGPR) 3304 scratchGPR = resultPayloadGPR; 3305 else 3306 scratchGPR = resultTagGPR; 3307 3306 3308 3307 base.use(); 3309 3308 3310 cachedGetById(node.codeOrigin, InvalidGPRReg, baseGPR, resultTagGPR, resultPayloadGPR, scratchGPR,node.identifierNumber());3309 cachedGetById(node.codeOrigin, InvalidGPRReg, baseGPR, resultTagGPR, resultPayloadGPR, node.identifierNumber()); 3311 3310 3312 3311 jsValueResult(resultTagGPR, resultPayloadGPR, m_compileIndex, UseChildrenCalledExplicitly); … … 3322 3321 GPRReg resultTagGPR = resultTag.gpr(); 3323 3322 GPRReg resultPayloadGPR = resultPayload.gpr(); 3324 GPRReg scratchGPR;3325 3326 if (resultTagGPR == basePayloadGPR)3327 scratchGPR = resultPayloadGPR;3328 else3329 scratchGPR = resultTagGPR;3330 3323 3331 3324 base.use(); … … 3333 3326 JITCompiler::Jump notCell = m_jit.branch32(JITCompiler::NotEqual, baseTagGPR, TrustedImm32(JSValue::CellTag)); 3334 3327 3335 cachedGetById(node.codeOrigin, baseTagGPR, basePayloadGPR, resultTagGPR, resultPayloadGPR, scratchGPR,node.identifierNumber(), notCell);3328 cachedGetById(node.codeOrigin, baseTagGPR, basePayloadGPR, resultTagGPR, resultPayloadGPR, node.identifierNumber(), notCell); 3336 3329 3337 3330 jsValueResult(resultTagGPR, resultPayloadGPR, m_compileIndex, UseChildrenCalledExplicitly); … … 3355 3348 GPRReg resultPayloadGPR = resultPayload.gpr(); 3356 3349 3357 GPRReg scratchGPR = selectScratchGPR(baseGPR, resultTagGPR, resultPayloadGPR);3358 3359 3350 base.use(); 3360 3351 3361 3352 flushRegisters(); 3362 3353 3363 cachedGetById(node.codeOrigin, InvalidGPRReg, baseGPR, resultTagGPR, resultPayloadGPR, scratchGPR,node.identifierNumber(), JITCompiler::Jump(), DontSpill);3354 cachedGetById(node.codeOrigin, InvalidGPRReg, baseGPR, resultTagGPR, resultPayloadGPR, node.identifierNumber(), JITCompiler::Jump(), DontSpill); 3364 3355 3365 3356 jsValueResult(resultTagGPR, resultPayloadGPR, m_compileIndex, UseChildrenCalledExplicitly); … … 3376 3367 GPRReg resultPayloadGPR = resultPayload.gpr(); 3377 3368 3378 GPRReg scratchGPR = selectScratchGPR(baseTagGPR, basePayloadGPR, resultTagGPR, resultPayloadGPR);3379 3380 3369 base.use(); 3381 3370 … … 3384 3373 JITCompiler::Jump notCell = m_jit.branch32(JITCompiler::NotEqual, baseTagGPR, TrustedImm32(JSValue::CellTag)); 3385 3374 3386 cachedGetById(node.codeOrigin, baseTagGPR, basePayloadGPR, resultTagGPR, resultPayloadGPR, scratchGPR,node.identifierNumber(), notCell, DontSpill);3375 cachedGetById(node.codeOrigin, baseTagGPR, basePayloadGPR, resultTagGPR, resultPayloadGPR, node.identifierNumber(), notCell, DontSpill); 3387 3376 3388 3377 jsValueResult(resultTagGPR, resultPayloadGPR, m_compileIndex, UseChildrenCalledExplicitly); -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp
r122678 r122768 493 493 } 494 494 495 void SpeculativeJIT::cachedGetById(CodeOrigin codeOrigin, GPRReg baseGPR, GPRReg resultGPR, GPRReg scratchGPR,unsigned identifierNumber, JITCompiler::Jump slowPathTarget, SpillRegistersMode spillMode)495 void SpeculativeJIT::cachedGetById(CodeOrigin codeOrigin, GPRReg baseGPR, GPRReg resultGPR, unsigned identifierNumber, JITCompiler::Jump slowPathTarget, SpillRegistersMode spillMode) 496 496 { 497 497 JITCompiler::DataLabelPtr structureToCompare; … … 521 521 codeOrigin, structureToCompare, structureCheck, propertyStorageLoad, loadWithPatch, 522 522 slowPath.get(), doneLabel, safeCast<int8_t>(baseGPR), safeCast<int8_t>(resultGPR), 523 safeCast<int8_t>(scratchGPR),523 usedRegisters(), 524 524 spillMode == NeedToSpill ? PropertyAccessRecord::RegistersInUse : PropertyAccessRecord::RegistersFlushed)); 525 525 addSlowPathGenerator(slowPath.release()); 526 527 528 if (scratchGPR != resultGPR && scratchGPR != InvalidGPRReg && spillMode == NeedToSpill)529 unlock(scratchGPR);530 526 } 531 527 … … 569 565 identifier(identifierNumber)); 570 566 } 567 RegisterSet currentlyUsedRegisters = usedRegisters(); 568 currentlyUsedRegisters.clear(scratchGPR); 569 ASSERT(currentlyUsedRegisters.get(baseGPR)); 570 ASSERT(currentlyUsedRegisters.get(valueGPR)); 571 571 m_jit.addPropertyAccess( 572 572 PropertyAccessRecord( 573 573 codeOrigin, structureToCompare, structureCheck, propertyStorageLoad, 574 574 JITCompiler::DataLabelCompact(storeWithPatch.label()), slowPath.get(), doneLabel, 575 safeCast<int8_t>(baseGPR), safeCast<int8_t>(valueGPR), safeCast<int8_t>(scratchGPR)));575 safeCast<int8_t>(baseGPR), safeCast<int8_t>(valueGPR), currentlyUsedRegisters)); 576 576 addSlowPathGenerator(slowPath.release()); 577 577 } … … 3328 3328 GPRReg baseGPR = base.gpr(); 3329 3329 GPRReg resultGPR = result.gpr(); 3330 GPRReg scratchGPR;3331 3332 if (resultGPR == baseGPR)3333 scratchGPR = tryAllocate();3334 else3335 scratchGPR = resultGPR;3336 3330 3337 3331 base.use(); 3338 3332 3339 cachedGetById(node.codeOrigin, baseGPR, resultGPR, scratchGPR,node.identifierNumber());3333 cachedGetById(node.codeOrigin, baseGPR, resultGPR, node.identifierNumber()); 3340 3334 3341 3335 jsValueResult(resultGPR, m_compileIndex, UseChildrenCalledExplicitly); … … 3348 3342 GPRReg baseGPR = base.gpr(); 3349 3343 GPRReg resultGPR = result.gpr(); 3350 GPRReg scratchGPR;3351 3352 if (resultGPR == baseGPR)3353 scratchGPR = tryAllocate();3354 else3355 scratchGPR = resultGPR;3356 3344 3357 3345 base.use(); … … 3359 3347 JITCompiler::Jump notCell = m_jit.branchTestPtr(JITCompiler::NonZero, baseGPR, GPRInfo::tagMaskRegister); 3360 3348 3361 cachedGetById(node.codeOrigin, baseGPR, resultGPR, scratchGPR,node.identifierNumber(), notCell);3349 cachedGetById(node.codeOrigin, baseGPR, resultGPR, node.identifierNumber(), notCell); 3362 3350 3363 3351 jsValueResult(resultGPR, m_compileIndex, UseChildrenCalledExplicitly); … … 3380 3368 GPRReg resultGPR = result.gpr(); 3381 3369 3382 GPRReg scratchGPR = selectScratchGPR(baseGPR, resultGPR);3383 3384 3370 base.use(); 3385 3371 3386 3372 flushRegisters(); 3387 3373 3388 cachedGetById(node.codeOrigin, baseGPR, resultGPR, scratchGPR,node.identifierNumber(), JITCompiler::Jump(), DontSpill);3374 cachedGetById(node.codeOrigin, baseGPR, resultGPR, node.identifierNumber(), JITCompiler::Jump(), DontSpill); 3389 3375 3390 3376 jsValueResult(resultGPR, m_compileIndex, UseChildrenCalledExplicitly); … … 3398 3384 GPRReg resultGPR = result.gpr(); 3399 3385 3400 GPRReg scratchGPR = selectScratchGPR(baseGPR, resultGPR);3401 3402 3386 base.use(); 3403 3387 flushRegisters(); … … 3405 3389 JITCompiler::Jump notCell = m_jit.branchTestPtr(JITCompiler::NonZero, baseGPR, GPRInfo::tagMaskRegister); 3406 3390 3407 cachedGetById(node.codeOrigin, baseGPR, resultGPR, scratchGPR,node.identifierNumber(), notCell, DontSpill);3391 cachedGetById(node.codeOrigin, baseGPR, resultGPR, node.identifierNumber(), notCell, DontSpill); 3408 3392 3409 3393 jsValueResult(resultGPR, m_compileIndex, UseChildrenCalledExplicitly); -
trunk/Source/JavaScriptCore/heap/CopiedAllocator.h
r122677 r122768 34 34 35 35 class CopiedAllocator { 36 friend class JIT;37 36 public: 38 37 CopiedAllocator(); 39 38 39 bool fastPathShouldSucceed(size_t bytes) const; 40 40 CheckedBoolean tryAllocate(size_t bytes, void** outPtr); 41 41 CheckedBoolean tryReallocate(void *oldPtr, size_t oldBytes, size_t newBytes); … … 47 47 bool isValid() { return !!m_currentBlock; } 48 48 49 private:50 49 CopiedBlock* currentBlock() { return m_currentBlock; } 51 50 51 // Yes, these are public. No, that doesn't mean you can play with them. 52 // If I had made them private then I'd have to list off all of the JIT 53 // classes and functions that are entitled to modify these directly, and 54 // that would have been gross. 52 55 size_t m_currentRemaining; 53 56 char* m_currentPayloadEnd; … … 60 63 , m_currentBlock(0) 61 64 { 65 } 66 67 inline bool CopiedAllocator::fastPathShouldSucceed(size_t bytes) const 68 { 69 ASSERT(is8ByteAligned(reinterpret_cast<void*>(bytes))); 70 71 return bytes <= m_currentRemaining; 62 72 } 63 73
Note: See TracChangeset
for help on using the changeset viewer.