Changeset 278875 in webkit
- Timestamp:
- Jun 15, 2021, 9:09:27 AM (4 years ago)
- Location:
- trunk/Source/JavaScriptCore
- Files:
-
- 14 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ChangeLog
r278859 r278875 1 2021-06-15 Mark Lam <mark.lam@apple.com> 2 3 Move setting of scratch buffer active lengths to the runtime functions. 4 https://bugs.webkit.org/show_bug.cgi?id=227013 5 rdar://79325068 6 7 Reviewed by Keith Miller. 8 9 We previously emit JIT'ed code to set and unset the ScratchBuffer active length 10 around calls into C++ runtime functions. This was needed because the runtime 11 functions may allow GC to run, and GC needs to be able to scan the values stored 12 in the ScratchBuffer. 13 14 In this patch, we change it so that the runtime functions that need it will 15 declare an ActiveScratchBufferScope RAII object that will set the ScratchBuffer 16 active length, and unset it on exit. This allows us to: 17 18 1. Emit less JIT code. The runtime function can take care of it. 19 2. Elide setting the ScratchBuffer active length if not needed. The runtime 20 functions know whether they can GC or not. They only need to set the active 21 length if they can GC. 22 23 Note that scanning of the active ScratchBuffer is done synchronously on the 24 mutator thread via Heap::gatherScratchBufferRoots(), which is called as part of 25 the GC conservative root scan. This means there is no urgency / sequencing that 26 requires that the active length be set before calling into the runtime function. 27 Setting it in the runtime function itself is fine as long as it is done before 28 the function executes any operations that can GC. 29 30 This patch also made the following changes: 31 32 1. Introduce ActiveScratchBufferScope RAII object used to set/unset the 33 ScratchBuffer length in the runtime functions. ActiveScratchBufferScope takes 34 the active length in units of number of stack slots / Registers / JSValues 35 instead of bytes. 36 37 2. Deleted ScratchRegisterAllocator::preserveUsedRegistersToScratchBufferForCall() 38 and ScratchRegisterAllocator::restoreUsedRegistersFromScratchBufferForCall(). 39 These functions are unused. 40 41 The reasoning behind what values to pass to ActiveScratchBufferScope, is any: 42 43 1. AssemblyHelpers::debugCall() in AssemblyHelpers.cpp: 44 The ScratchBuffer is only used for operationDebugPrintSpeculationFailure(), 45 which now declares an ActiveScratchBufferScope. 46 47 The active length is GPRInfo::numberOfRegisters + FPRInfo::numberOfRegisters. 48 See scratchSize in AssemblyHelpers::debugCall(). 49 50 2. genericGenerationThunkGenerator() in FTLThunks.cpp: 51 The scratch buffer size for determining the active length is 52 requiredScratchMemorySizeInBytes(). 53 54 However, genericGenerationThunkGenerator() generates code to call either 55 operationCompileFTLOSRExit() or operationCompileFTLLazySlowPath(). Both of 56 these functions will DeferGCForAWhile. Hence, GC cannot run, and we don't need 57 to set the active length here. 58 59 3. compileArrayPush() in FTLLowerDFGToB3.cpp: 60 61 Cases Array::Int32, Array::Contiguous, or Array::Double calls 62 operationArrayPushMultiple() or operationArrayPushDoubleMultiple(). 63 64 For operationArrayPushMultiple(), the active length is elementCount. See 65 computation of scratchSize. 66 67 For operationArrayPushDoubleMultiple(), we don't need to set the active length 68 because the ScratchBuffer only contains double values. The GC does not need 69 to scan those. 70 71 Case Array::ArrayStorage calls operationArrayPushMultiple(). 72 The active length is elementCount. See computation of scratchSize. 73 74 compileNewArray() in FTLLowerDFGToB3.cpp: 75 76 Calls operationNewArray(). Active length is m_node->numChildren(), which is 77 passed to operationNewArray() as the size parameter. See computation of 78 scratchSize. 79 80 compileNewArrayWithSpread() in FTLLowerDFGToB3.cpp: 81 82 Calls operationNewArrayWithSpreadSlow(). Active length is m_node->numChildren(), 83 which is passes to operationNewArrayWithSpreadSlow() as the numItems parameter. 84 See computation of scratchSize. 85 86 4. osrExitGenerationThunkGenerator() in DFGThunks.cpp: 87 88 Calls operationCompileOSRExit(). Active length is GPRInfo::numberOfRegisters + 89 FPRInfo::numberOfRegisters. See computation of scratchSize. 90 91 5. compileNewArray() in DFGSpeculativeJIT.cpp: 92 93 Calls operationNewArray(). Active length is node->numChildren(), which is 94 passed in as the size parameter. 95 96 compileNewArrayWithSpread() in DFGSpeculativeJIT.cpp: 97 98 Calls operationNewArrayWithSpreadSlow(). Active length is node->numChildren(), 99 which is passed in as the numItems parameter. 100 101 compileArrayPush() in DFGSpeculativeJIT.cpp: 102 103 Calls operationArrayPushMultiple(). Active length is elementCount, which is 104 passed in as the elementCount parameter. 105 106 Calls operationArrayPushDoubleMultiple(). Active length is elementCount, but 107 we don't need to set it because the ScratchBuffer only contains double values. 108 109 110 * dfg/DFGOSRExit.cpp: 111 (JSC::DFG::JSC_DEFINE_JIT_OPERATION): 112 * dfg/DFGOperations.cpp: 113 (JSC::DFG::JSC_DEFINE_JIT_OPERATION): 114 * dfg/DFGSpeculativeJIT.cpp: 115 (JSC::DFG::SpeculativeJIT::compileNewArray): 116 (JSC::DFG::SpeculativeJIT::compileNewArrayWithSpread): 117 (JSC::DFG::SpeculativeJIT::compileArrayPush): 118 * dfg/DFGThunks.cpp: 119 (JSC::DFG::osrExitGenerationThunkGenerator): 120 * ftl/FTLLowerDFGToB3.cpp: 121 (JSC::FTL::DFG::LowerDFGToB3::compileArrayPush): 122 (JSC::FTL::DFG::LowerDFGToB3::compileNewArray): 123 (JSC::FTL::DFG::LowerDFGToB3::compileNewArrayWithSpread): 124 * ftl/FTLOSRExitCompiler.cpp: 125 (JSC::FTL::JSC_DEFINE_JIT_OPERATION): 126 * ftl/FTLOperations.cpp: 127 (JSC::FTL::JSC_DEFINE_JIT_OPERATION): 128 * ftl/FTLThunks.cpp: 129 (JSC::FTL::genericGenerationThunkGenerator): 130 * jit/AssemblyHelpers.cpp: 131 (JSC::AssemblyHelpers::debugCall): 132 * jit/ScratchRegisterAllocator.cpp: 133 (JSC::ScratchRegisterAllocator::preserveUsedRegistersToScratchBufferForCall): Deleted. 134 (JSC::ScratchRegisterAllocator::restoreUsedRegistersFromScratchBufferForCall): Deleted. 135 * jit/ScratchRegisterAllocator.h: 136 * runtime/VM.h: 137 * runtime/VMInlines.h: 138 (JSC::ActiveScratchBufferScope::ActiveScratchBufferScope): 139 (JSC::ActiveScratchBufferScope::~ActiveScratchBufferScope): 140 1 141 2021-06-14 Yusuke Suzuki <ysuzuki@apple.com> 2 142 -
trunk/Source/JavaScriptCore/dfg/DFGOSRExit.cpp
r277928 r278875 42 42 #include "OperandsInlines.h" 43 43 #include "ProbeContext.h" 44 #include "VMInlines.h" 44 45 45 46 #include <wtf/Scope.h> … … 145 146 VM& vm = callFrame->deprecatedVM(); 146 147 auto scope = DECLARE_THROW_SCOPE(vm); 148 ActiveScratchBufferScope activeScratchBufferScope(vm, GPRInfo::numberOfRegisters + FPRInfo::numberOfRegisters); 147 149 148 150 if constexpr (validateDFGDoesGC) { … … 891 893 VM& vm = callFrame->deprecatedVM(); 892 894 NativeCallFrameTracer tracer(vm, callFrame); 895 ActiveScratchBufferScope activeScratchBufferScope(vm, GPRInfo::numberOfRegisters + FPRInfo::numberOfRegisters); 893 896 894 897 SpeculationFailureDebugInfo* debugInfo = static_cast<SpeculationFailureDebugInfo*>(debugInfoRaw); -
trunk/Source/JavaScriptCore/dfg/DFGOperations.cpp
r278462 r278875 1040 1040 CallFrame* callFrame = DECLARE_CALL_FRAME(vm); 1041 1041 JITOperationPrologueCallFrameTracer tracer(vm, callFrame); 1042 ActiveScratchBufferScope activeScratchBufferScope(vm, elementCount); 1042 1043 auto scope = DECLARE_THROW_SCOPE(vm); 1043 1044 … … 1065 1066 CallFrame* callFrame = DECLARE_CALL_FRAME(vm); 1066 1067 JITOperationPrologueCallFrameTracer tracer(vm, callFrame); 1068 // Don't need a ActiveScratchBufferScope here because the scratch buffer only contains double values for this call. 1067 1069 auto scope = DECLARE_THROW_SCOPE(vm); 1068 1070 … … 1733 1735 CallFrame* callFrame = DECLARE_CALL_FRAME(vm); 1734 1736 JITOperationPrologueCallFrameTracer tracer(vm, callFrame); 1735 1737 ActiveScratchBufferScope activeScratchBufferScope(vm, size); 1738 1736 1739 return bitwise_cast<char*>(constructArray(globalObject, arrayStructure, static_cast<JSValue*>(buffer), size)); 1737 1740 } … … 3040 3043 CallFrame* callFrame = DECLARE_CALL_FRAME(vm); 3041 3044 JITOperationPrologueCallFrameTracer tracer(vm, callFrame); 3045 ActiveScratchBufferScope activeScratchBufferScope(vm, numItems); 3042 3046 auto scope = DECLARE_THROW_SCOPE(vm); 3043 3047 -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
r278662 r278875 9168 9168 flushRegisters(); 9169 9169 9170 if (scratchSize) {9171 GPRTemporary scratch(this);9172 9173 // Tell GC mark phase how much of the scratch buffer is active during call.9174 m_jit.move(TrustedImmPtr(scratchBuffer->addressOfActiveLength()), scratch.gpr());9175 m_jit.storePtr(TrustedImmPtr(scratchSize), scratch.gpr());9176 }9177 9178 9170 GPRFlushedCallResult result(this); 9179 9171 … … 9182 9174 static_cast<void*>(buffer), size_t(node->numChildren())); 9183 9175 m_jit.exceptionCheck(); 9184 9185 if (scratchSize) {9186 GPRTemporary scratch(this);9187 9188 m_jit.move(TrustedImmPtr(scratchBuffer->addressOfActiveLength()), scratch.gpr());9189 m_jit.storePtr(TrustedImmPtr(nullptr), scratch.gpr());9190 }9191 9176 9192 9177 cellResult(result.gpr(), node, UseChildrenCalledExplicitly); … … 9340 9325 } 9341 9326 9342 {9343 GPRTemporary scratch(this);9344 m_jit.move(TrustedImmPtr(scratchBuffer->addressOfActiveLength()), scratch.gpr());9345 m_jit.storePtr(TrustedImmPtr(scratchSize), MacroAssembler::Address(scratch.gpr()));9346 }9347 9348 9327 flushRegisters(); 9349 9328 … … 9353 9332 callOperation(operationNewArrayWithSpreadSlow, resultGPR, TrustedImmPtr::weakPointer(m_graph, globalObject), buffer, node->numChildren()); 9354 9333 m_jit.exceptionCheck(); 9355 {9356 GPRTemporary scratch(this);9357 m_jit.move(TrustedImmPtr(scratchBuffer->addressOfActiveLength()), scratch.gpr());9358 m_jit.storePtr(TrustedImmPtr(nullptr), MacroAssembler::Address(scratch.gpr()));9359 }9360 9334 9361 9335 cellResult(resultGPR, node); … … 9876 9850 ScratchBuffer* scratchBuffer = vm().scratchBufferForSize(scratchSize); 9877 9851 m_jit.move(TrustedImmPtr(static_cast<EncodedJSValue*>(scratchBuffer->dataBuffer())), bufferGPR); 9878 m_jit.move(TrustedImmPtr(scratchBuffer->addressOfActiveLength()), storageLengthGPR);9879 m_jit.storePtr(TrustedImmPtr(scratchSize), MacroAssembler::Address(storageLengthGPR));9880 9852 9881 9853 storageDone.link(&m_jit); … … 9892 9864 9893 9865 addSlowPathGenerator(slowPathCall(m_jit.jump(), this, operationArrayPushMultiple, resultRegs, TrustedImmPtr::weakPointer(m_graph, m_graph.globalObjectFor(node->origin.semantic)), baseGPR, bufferGPR, TrustedImm32(elementCount))); 9894 9895 m_jit.move(TrustedImmPtr(scratchBuffer->addressOfActiveLength()), bufferGPR);9896 m_jit.storePtr(TrustedImmPtr(nullptr), MacroAssembler::Address(bufferGPR));9897 9866 9898 9867 base.use(); … … 9950 9919 ScratchBuffer* scratchBuffer = vm().scratchBufferForSize(scratchSize); 9951 9920 m_jit.move(TrustedImmPtr(static_cast<EncodedJSValue*>(scratchBuffer->dataBuffer())), bufferGPR); 9952 m_jit.move(TrustedImmPtr(scratchBuffer->addressOfActiveLength()), storageLengthGPR);9953 m_jit.storePtr(TrustedImmPtr(scratchSize), MacroAssembler::Address(storageLengthGPR));9954 9921 9955 9922 storageDone.link(&m_jit); … … 9966 9933 9967 9934 addSlowPathGenerator(slowPathCall(m_jit.jump(), this, operationArrayPushDoubleMultiple, resultRegs, TrustedImmPtr::weakPointer(m_graph, m_graph.globalObjectFor(node->origin.semantic)), baseGPR, bufferGPR, TrustedImm32(elementCount))); 9968 9969 m_jit.move(TrustedImmPtr(scratchBuffer->addressOfActiveLength()), bufferGPR);9970 m_jit.storePtr(TrustedImmPtr(nullptr), MacroAssembler::Address(bufferGPR));9971 9935 9972 9936 base.use(); … … 10031 9995 ScratchBuffer* scratchBuffer = vm().scratchBufferForSize(scratchSize); 10032 9996 m_jit.move(TrustedImmPtr(static_cast<EncodedJSValue*>(scratchBuffer->dataBuffer())), bufferGPR); 10033 m_jit.move(TrustedImmPtr(scratchBuffer->addressOfActiveLength()), storageLengthGPR);10034 m_jit.storePtr(TrustedImmPtr(scratchSize), MacroAssembler::Address(storageLengthGPR));10035 9997 10036 9998 storageDone.link(&m_jit); … … 10048 10010 addSlowPathGenerator( 10049 10011 slowPathCall(m_jit.jump(), this, operationArrayPushMultiple, resultRegs, TrustedImmPtr::weakPointer(m_graph, m_graph.globalObjectFor(node->origin.semantic)), baseGPR, bufferGPR, TrustedImm32(elementCount))); 10050 10051 m_jit.move(TrustedImmPtr(scratchBuffer->addressOfActiveLength()), bufferGPR);10052 m_jit.storePtr(TrustedImmPtr(nullptr), MacroAssembler::Address(bufferGPR));10053 10012 10054 10013 base.use(); -
trunk/Source/JavaScriptCore/dfg/DFGThunks.cpp
r277928 r278875 32 32 #include "DFGJITCode.h" 33 33 #include "DFGOSRExit.h" 34 #include "DFGOSRExitCompilerCommon.h" 34 35 #include "FPRInfo.h" 35 36 #include "GPRInfo.h" 36 37 #include "LinkBuffer.h" 37 38 #include "MacroAssembler.h" 38 #include "DFGOSRExitCompilerCommon.h"39 39 40 40 namespace JSC { namespace DFG { … … 63 63 } 64 64 65 // Tell GC mark phase how much of the scratch buffer is active during call.66 jit.move(MacroAssembler::TrustedImmPtr(scratchBuffer->addressOfActiveLength()), GPRInfo::regT0);67 jit.storePtr(MacroAssembler::TrustedImmPtr(scratchSize), MacroAssembler::Address(GPRInfo::regT0));68 69 65 // Set up one argument. 70 66 jit.move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0); … … 72 68 73 69 MacroAssembler::Call functionCall = jit.call(OperationPtrTag); 74 75 jit.move(MacroAssembler::TrustedImmPtr(scratchBuffer->addressOfActiveLength()), GPRInfo::regT0);76 jit.storePtr(MacroAssembler::TrustedImmPtr(nullptr), MacroAssembler::Address(GPRInfo::regT0));77 70 78 71 for (unsigned i = 0; i < FPRInfo::numberOfRegisters; ++i) { -
trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp
r278696 r278875 6163 6163 ASSERT(scratchSize); 6164 6164 ScratchBuffer* scratchBuffer = vm().scratchBufferForSize(scratchSize); 6165 m_out.storePtr(m_out.constIntPtr(scratchSize), m_out.absolute(scratchBuffer->addressOfActiveLength()));6166 6165 ValueFromBlock slowBufferResult = m_out.anchor(m_out.constIntPtr(static_cast<EncodedJSValue*>(scratchBuffer->dataBuffer()))); 6167 6166 m_out.jump(setup); … … 6193 6192 operation = &operationArrayPushDoubleMultiple; 6194 6193 ValueFromBlock slowResult = m_out.anchor(vmCall(Int64, operation, weakPointer(globalObject), base, buffer, m_out.constInt32(elementCount))); 6195 m_out.storePtr(m_out.constIntPtr(0), m_out.absolute(scratchBuffer->addressOfActiveLength()));6196 6194 m_out.jump(continuation); 6197 6195 … … 6269 6267 ASSERT(scratchSize); 6270 6268 ScratchBuffer* scratchBuffer = vm().scratchBufferForSize(scratchSize); 6271 m_out.storePtr(m_out.constIntPtr(scratchSize), m_out.absolute(scratchBuffer->addressOfActiveLength()));6272 6269 ValueFromBlock slowBufferResult = m_out.anchor(m_out.constIntPtr(static_cast<EncodedJSValue*>(scratchBuffer->dataBuffer()))); 6273 6270 m_out.jump(setup); … … 6287 6284 m_out.appendTo(slowCallPath, continuation); 6288 6285 ValueFromBlock slowResult = m_out.anchor(vmCall(Int64, operationArrayPushMultiple, weakPointer(globalObject), base, buffer, m_out.constInt32(elementCount))); 6289 m_out.storePtr(m_out.constIntPtr(0), m_out.absolute(scratchBuffer->addressOfActiveLength()));6290 6286 m_out.jump(continuation); 6291 6287 … … 7279 7275 m_out.store64(valueToStore, m_out.absolute(buffer + operandIndex)); 7280 7276 } 7281 7282 m_out.storePtr( 7283 m_out.constIntPtr(scratchSize), m_out.absolute(scratchBuffer->addressOfActiveLength())); 7284 7277 7285 7278 LValue result = vmCall( 7286 7279 Int64, operationNewArray, weakPointer(globalObject), 7287 7280 weakStructure(structure), m_out.constIntPtr(buffer), 7288 7281 m_out.constIntPtr(m_node->numChildren())); 7289 7290 m_out.storePtr(m_out.intPtrZero, m_out.absolute(scratchBuffer->addressOfActiveLength())); 7291 7282 7292 7283 setJSValue(result); 7293 7284 } … … 7525 7516 } 7526 7517 7527 m_out.storePtr(m_out.constIntPtr(scratchSize), m_out.absolute(scratchBuffer->addressOfActiveLength()));7528 7518 LValue result = vmCall(Int64, operationNewArrayWithSpreadSlow, weakPointer(globalObject), m_out.constIntPtr(buffer), m_out.constInt32(m_node->numChildren())); 7529 m_out.storePtr(m_out.constIntPtr(0), m_out.absolute(scratchBuffer->addressOfActiveLength()));7530 7519 7531 7520 setJSValue(result); -
trunk/Source/JavaScriptCore/ftl/FTLOSRExitCompiler.cpp
r277928 r278875 524 524 525 525 VM& vm = callFrame->deprecatedVM(); 526 // Don't need an ActiveScratchBufferScope here because we DeferGCForAWhile below. 526 527 527 528 if constexpr (validateDFGDoesGC) { -
trunk/Source/JavaScriptCore/ftl/FTLOperations.cpp
r278351 r278875 1 1 /* 2 * Copyright (C) 2014-202 0Apple Inc. All rights reserved.2 * Copyright (C) 2014-2021 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 731 731 { 732 732 VM& vm = callFrame->deprecatedVM(); 733 // Don't need an ActiveScratchBufferScope here because we DeferGCForAWhile. 733 734 734 735 // We cannot GC. We've got pointers in evil places. -
trunk/Source/JavaScriptCore/ftl/FTLThunks.cpp
r278656 r278875 77 77 78 78 saveAllRegisters(jit, buffer); 79 80 // Tell GC mark phase how much of the scratch buffer is active during call.81 jit.move(MacroAssembler::TrustedImmPtr(scratchBuffer->addressOfActiveLength()), GPRInfo::nonArgGPR1);82 jit.storePtr(MacroAssembler::TrustedImmPtr(requiredScratchMemorySizeInBytes()), GPRInfo::nonArgGPR1);83 79 84 80 jit.loadPtr(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0); … … 95 91 96 92 jit.move(GPRInfo::returnValueGPR, GPRInfo::regT0); 97 98 // Make sure we tell the GC that we're not using the scratch buffer anymore. 99 jit.move(MacroAssembler::TrustedImmPtr(scratchBuffer->addressOfActiveLength()), GPRInfo::regT1); 100 jit.storePtr(MacroAssembler::TrustedImmPtr(nullptr), GPRInfo::regT1); 101 93 102 94 // Prepare for tail call. 103 95 while (numberOfRequiredPops--) -
trunk/Source/JavaScriptCore/jit/AssemblyHelpers.cpp
r278656 r278875 967 967 } 968 968 969 // Tell GC mark phase how much of the scratch buffer is active during call.970 move(TrustedImmPtr(scratchBuffer->addressOfActiveLength()), GPRInfo::regT0);971 storePtr(TrustedImmPtr(scratchSize), GPRInfo::regT0);972 973 969 #if CPU(X86_64) || CPU(ARM_THUMB2) || CPU(ARM64) || CPU(MIPS) 974 970 move(TrustedImmPtr(buffer), GPRInfo::argumentGPR2); … … 982 978 move(TrustedImmPtr(tagCFunctionPtr<OperationPtrTag>(function)), scratch); 983 979 call(scratch, OperationPtrTag); 984 985 move(TrustedImmPtr(scratchBuffer->addressOfActiveLength()), GPRInfo::regT0);986 storePtr(TrustedImmPtr(nullptr), GPRInfo::regT0);987 980 988 981 for (unsigned i = 0; i < FPRInfo::numberOfRegisters; ++i) { -
trunk/Source/JavaScriptCore/jit/ScratchRegisterAllocator.cpp
r261755 r278875 162 162 } 163 163 164 void ScratchRegisterAllocator::preserveUsedRegistersToScratchBufferForCall(MacroAssembler& jit, ScratchBuffer* scratchBuffer, GPRReg scratchGPR)165 {166 RegisterSet usedRegisters = usedRegistersForCall();167 if (!usedRegisters.numberOfSetRegisters())168 return;169 170 unsigned count = 0;171 for (GPRReg reg = MacroAssembler::firstRegister(); reg <= MacroAssembler::lastRegister(); reg = MacroAssembler::nextRegister(reg)) {172 if (usedRegisters.get(reg)) {173 jit.storePtr(reg, static_cast<EncodedJSValue*>(scratchBuffer->dataBuffer()) + count);174 count++;175 }176 if (GPRInfo::toIndex(reg) != GPRInfo::InvalidIndex177 && scratchGPR == InvalidGPRReg178 && !m_lockedRegisters.get(reg) && !m_scratchRegisters.get(reg))179 scratchGPR = reg;180 }181 RELEASE_ASSERT(scratchGPR != InvalidGPRReg);182 for (FPRReg reg = MacroAssembler::firstFPRegister(); reg <= MacroAssembler::lastFPRegister(); reg = MacroAssembler::nextFPRegister(reg)) {183 if (usedRegisters.get(reg)) {184 jit.move(MacroAssembler::TrustedImmPtr(static_cast<EncodedJSValue*>(scratchBuffer->dataBuffer()) + count), scratchGPR);185 count++;186 jit.storeDouble(reg, scratchGPR);187 }188 }189 RELEASE_ASSERT(count * sizeof(JSValue) == desiredScratchBufferSizeForCall());190 191 jit.move(MacroAssembler::TrustedImmPtr(scratchBuffer->addressOfActiveLength()), scratchGPR);192 jit.storePtr(MacroAssembler::TrustedImmPtr(static_cast<size_t>(count * sizeof(JSValue))), scratchGPR);193 }194 195 void ScratchRegisterAllocator::restoreUsedRegistersFromScratchBufferForCall(MacroAssembler& jit, ScratchBuffer* scratchBuffer, GPRReg scratchGPR)196 {197 RegisterSet usedRegisters = usedRegistersForCall();198 if (!usedRegisters.numberOfSetRegisters())199 return;200 201 if (scratchGPR == InvalidGPRReg) {202 // Find a scratch register.203 for (unsigned i = GPRInfo::numberOfRegisters; i--;) {204 if (m_lockedRegisters.getGPRByIndex(i) || m_scratchRegisters.getGPRByIndex(i))205 continue;206 scratchGPR = GPRInfo::toRegister(i);207 break;208 }209 }210 RELEASE_ASSERT(scratchGPR != InvalidGPRReg);211 212 jit.move(MacroAssembler::TrustedImmPtr(scratchBuffer->addressOfActiveLength()), scratchGPR);213 jit.storePtr(MacroAssembler::TrustedImmPtr(nullptr), scratchGPR);214 215 // Restore double registers first.216 unsigned count = usedRegisters.numberOfSetGPRs();217 for (FPRReg reg = MacroAssembler::firstFPRegister(); reg <= MacroAssembler::lastFPRegister(); reg = MacroAssembler::nextFPRegister(reg)) {218 if (usedRegisters.get(reg)) {219 jit.move(MacroAssembler::TrustedImmPtr(static_cast<EncodedJSValue*>(scratchBuffer->dataBuffer()) + (count++)), scratchGPR);220 jit.loadDouble(scratchGPR, reg);221 }222 }223 224 count = 0;225 for (GPRReg reg = MacroAssembler::firstRegister(); reg <= MacroAssembler::lastRegister(); reg = MacroAssembler::nextRegister(reg)) {226 if (usedRegisters.get(reg))227 jit.loadPtr(static_cast<EncodedJSValue*>(scratchBuffer->dataBuffer()) + (count++), reg);228 }229 }230 231 164 unsigned ScratchRegisterAllocator::preserveRegistersToStackForCall(MacroAssembler& jit, const RegisterSet& usedRegisters, unsigned extraBytesAtTopOfStack) 232 165 { -
trunk/Source/JavaScriptCore/jit/ScratchRegisterAllocator.h
r206525 r278875 92 92 unsigned desiredScratchBufferSizeForCall() const; 93 93 94 void preserveUsedRegistersToScratchBufferForCall(MacroAssembler& jit, ScratchBuffer* scratchBuffer, GPRReg scratchGPR = InvalidGPRReg);95 void restoreUsedRegistersFromScratchBufferForCall(MacroAssembler& jit, ScratchBuffer* scratchBuffer, GPRReg scratchGPR = InvalidGPRReg);96 97 94 static unsigned preserveRegistersToStackForCall(MacroAssembler& jit, const RegisterSet& usedRegisters, unsigned extraPaddingInBytes); 98 95 static void restoreRegistersFromStackForCall(MacroAssembler& jit, const RegisterSet& usedRegisters, const RegisterSet& ignore, unsigned numberOfStackBytesUsedForRegisterPreservation, unsigned extraPaddingInBytes); -
trunk/Source/JavaScriptCore/runtime/VM.h
r278656 r278875 280 280 #pragma warning(pop) 281 281 #endif 282 283 class ActiveScratchBufferScope { 284 public: 285 ActiveScratchBufferScope(VM&, size_t activeScratchBufferSizeInJSValues); 286 ~ActiveScratchBufferScope(); 287 288 private: 289 ScratchBuffer* m_scratchBuffer; 290 }; 282 291 283 292 class VM : public ThreadSafeRefCounted<VM>, public DoublyLinkedListNode<VM> { -
trunk/Source/JavaScriptCore/runtime/VMInlines.h
r252177 r278875 1 1 /* 2 * Copyright (C) 2015-20 19Apple Inc. All rights reserved.2 * Copyright (C) 2015-2021 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 32 32 33 33 namespace JSC { 34 34 35 inline ActiveScratchBufferScope::ActiveScratchBufferScope(VM& vm, size_t activeScratchBufferSizeInJSValues) 36 : m_scratchBuffer(vm.scratchBufferForSize(activeScratchBufferSizeInJSValues * sizeof(EncodedJSValue))) 37 { 38 // Tell GC mark phase how much of the scratch buffer is active during the call operation this scope is used in. 39 if (m_scratchBuffer) 40 m_scratchBuffer->u.m_activeLength = activeScratchBufferSizeInJSValues * sizeof(EncodedJSValue); 41 } 42 43 inline ActiveScratchBufferScope::~ActiveScratchBufferScope() 44 { 45 // Tell the GC that we're not using the scratch buffer anymore. 46 if (m_scratchBuffer) 47 m_scratchBuffer->u.m_activeLength = 0; 48 } 49 35 50 bool VM::ensureStackCapacityFor(Register* newTopOfStack) 36 51 {
Note:
See TracChangeset
for help on using the changeset viewer.