Changeset 293154 in webkit
- Timestamp:
- Apr 21, 2022, 2:51:18 AM (4 years ago)
- Location:
- releases/WebKitGTK/webkit-2.36/Source/JavaScriptCore
- Files:
-
- 4 edited
-
ChangeLog (modified) (1 diff)
-
jit/JITOperations.cpp (modified) (1 diff)
-
jit/JITOperations.h (modified) (1 diff)
-
jit/ThunkGenerators.cpp (modified) (4 diffs)
Legend:
- Unmodified
- Added
- Removed
-
releases/WebKitGTK/webkit-2.36/Source/JavaScriptCore/ChangeLog
r293153 r293154 1 2022-03-24 Yusuke Suzuki <ysuzuki@apple.com> 2 3 [JSC] JSRemoteFunction thunk should materialize code-pointer 4 https://bugs.webkit.org/show_bug.cgi?id=238313 5 6 Reviewed by Mark Lam. 7 8 When invoking a JSRemoteFunction, we must first wrap the arguments passed to it. 9 The wrapping operation may trigger a GC, and GC can jettison JIT code. As a result, 10 even though we know that the target JSFunction has JIT code that we want to execute, 11 the JIT code may be jettisoned (while wrapping the arguments for it) before we get 12 to the call. This resulted in occasional crashes on the JSTests/stress/shadow-realm-evaluate.js test. 13 14 This patch fixes this by doing a null check on the JIT code just before calling it, 15 and if null (i.e. the JIT code has been jettisoned), re-materializing the JIT code 16 first before making the call. 17 18 * jit/JITOperations.cpp: 19 (JSC::JSC_DEFINE_JIT_OPERATION): 20 * jit/JITOperations.h: 21 * jit/ThunkGenerators.cpp: 22 (JSC::remoteFunctionCallGenerator): 23 1 24 2022-03-23 Geza Lore <glore@igalia.com> 2 25 -
releases/WebKitGTK/webkit-2.36/Source/JavaScriptCore/jit/JITOperations.cpp
r289417 r293154 159 159 160 160 RELEASE_AND_RETURN(scope, JSValue::encode(getWrappedValue(globalObject, globalObject, JSValue::decode(encodedValue)))); 161 } 162 163 JSC_DEFINE_JIT_OPERATION(operationMaterializeRemoteFunctionTargetCode, void*, (JSRemoteFunction* callee)) 164 { 165 JSGlobalObject* globalObject = callee->globalObject(); 166 VM& vm = globalObject->vm(); 167 168 CallFrame* callFrame = DECLARE_CALL_FRAME(vm); 169 JITOperationPrologueCallFrameTracer tracer(vm, callFrame); 170 auto throwScope = DECLARE_THROW_SCOPE(vm); 171 172 ASSERT(isRemoteFunction(vm, callee)); 173 174 auto* targetFunction = jsCast<JSFunction*>(callee->targetFunction()); // We call this function only when JSRemoteFunction's target is JSFunction. 175 ExecutableBase* executable = targetFunction->executable(); 176 177 // Force the executable to cache its arity entrypoint. 178 { 179 DeferTraps deferTraps(vm); // We can't jettison any code until after we link the call. 180 if (!executable->isHostFunction()) { 181 JSScope* scope = targetFunction->scopeUnchecked(); 182 FunctionExecutable* functionExecutable = static_cast<FunctionExecutable*>(executable); 183 CodeBlock* codeBlockSlot = nullptr; 184 functionExecutable->prepareForExecution<FunctionExecutable>(vm, targetFunction, scope, CodeForCall, codeBlockSlot); 185 RETURN_IF_EXCEPTION(throwScope, nullptr); 186 } 187 return executable->entrypointFor(CodeForCall, MustCheckArity).executableAddress(); 188 } 161 189 } 162 190 -
releases/WebKitGTK/webkit-2.36/Source/JavaScriptCore/jit/JITOperations.h
r289417 r293154 159 159 JSC_DECLARE_JIT_OPERATION(operationGetWrappedValueForCaller, EncodedJSValue, (JSRemoteFunction*, EncodedJSValue)); 160 160 JSC_DECLARE_JIT_OPERATION(operationGetWrappedValueForTarget, EncodedJSValue, (JSRemoteFunction*, EncodedJSValue)); 161 JSC_DECLARE_JIT_OPERATION(operationMaterializeRemoteFunctionTargetCode, void*, (JSRemoteFunction*)); 161 162 JSC_DECLARE_JIT_OPERATION(operationThrowRemoteFunctionException, EncodedJSValue, (JSRemoteFunction*)); 162 163 -
releases/WebKitGTK/webkit-2.36/Source/JavaScriptCore/jit/ThunkGenerators.cpp
r293153 r293154 1528 1528 jit.storePtr(GPRInfo::regT1, jit.addressFor(loopIndex)); 1529 1529 1530 jit.setupArguments<decltype(operationGetWrappedValueForTarget)>(GPRInfo::regT0, valueRegs); 1530 1531 jit.prepareCallOperation(vm); 1531 jit.setupArguments<decltype(operationGetWrappedValueForTarget)>(GPRInfo::regT0, valueRegs);1532 1532 jit.move(CCallHelpers::TrustedImmPtr(tagCFunction<OperationPtrTag>(operationGetWrappedValueForTarget)), GPRInfo::nonArgGPR0); 1533 1533 emitPointerValidation(jit, GPRInfo::nonArgGPR0, OperationPtrTag); … … 1550 1550 jit.storeCell(GPRInfo::regT2, CCallHelpers::calleeFrameSlot(CallFrameSlot::callee)); 1551 1551 1552 jit.loadPtr(CCallHelpers::Address(GPRInfo::regT2, JSFunction::offsetOfExecutableOrRareData()), GPRInfo::regT 0);1553 auto hasExecutable = jit.branchTestPtr(CCallHelpers::Zero, GPRInfo::regT 0, CCallHelpers::TrustedImm32(JSFunction::rareDataTag));1554 jit.loadPtr(CCallHelpers::Address(GPRInfo::regT 0, FunctionRareData::offsetOfExecutable() - JSFunction::rareDataTag), GPRInfo::regT0);1552 jit.loadPtr(CCallHelpers::Address(GPRInfo::regT2, JSFunction::offsetOfExecutableOrRareData()), GPRInfo::regT1); 1553 auto hasExecutable = jit.branchTestPtr(CCallHelpers::Zero, GPRInfo::regT1, CCallHelpers::TrustedImm32(JSFunction::rareDataTag)); 1554 jit.loadPtr(CCallHelpers::Address(GPRInfo::regT1, FunctionRareData::offsetOfExecutable() - JSFunction::rareDataTag), GPRInfo::regT1); 1555 1555 hasExecutable.link(&jit); 1556 1556 1557 1557 jit.loadPtr( 1558 1558 CCallHelpers::Address( 1559 GPRInfo::regT0, ExecutableBase::offsetOfJITCodeWithArityCheckFor(CodeForCall)), 1560 GPRInfo::regT0); 1561 1559 GPRInfo::regT1, ExecutableBase::offsetOfJITCodeWithArityCheckFor(CodeForCall)), 1560 GPRInfo::regT1); 1561 auto codeExists = jit.branchTestPtr(CCallHelpers::NonZero, GPRInfo::regT1); 1562 1563 // The calls to operationGetWrappedValueForTarget above may GC, and any GC can potentially jettison the JIT code in the target JSFunction. 1564 // If we find that the JIT code is null (i.e. has been jettisoned), then we need to re-materialize it for the call below. Note that we know 1565 // that operationMaterializeRemoteFunctionTargetCode should be able to re-materialize the JIT code (except for any OOME) because we only 1566 // went down this code path after we found a non-null JIT code (in the noCode check) above i.e. it should be possible to materialize the JIT code. 1567 jit.setupArguments<decltype(operationMaterializeRemoteFunctionTargetCode)>(GPRInfo::regT0); 1568 jit.prepareCallOperation(vm); 1569 jit.move(CCallHelpers::TrustedImmPtr(tagCFunction<OperationPtrTag>(operationMaterializeRemoteFunctionTargetCode)), GPRInfo::nonArgGPR0); 1570 emitPointerValidation(jit, GPRInfo::nonArgGPR0, OperationPtrTag); 1571 jit.call(GPRInfo::nonArgGPR0, OperationPtrTag); 1572 exceptionChecks.append(jit.emitJumpIfException(vm)); 1573 jit.move(GPRInfo::returnValueGPR, GPRInfo::regT1); 1574 1575 codeExists.link(&jit); 1562 1576 // Based on the check above, we should be good with this. On ARM64, emitPointerValidation will do this. 1563 1577 #if ASSERT_ENABLED && !CPU(ARM64E) 1564 1578 { 1565 CCallHelpers::Jump checkNotNull = jit.branchTestPtr(CCallHelpers::NonZero, GPRInfo::regT 0);1579 CCallHelpers::Jump checkNotNull = jit.branchTestPtr(CCallHelpers::NonZero, GPRInfo::regT1); 1566 1580 jit.abortWithReason(TGInvalidPointer); 1567 1581 checkNotNull.link(&jit); … … 1569 1583 #endif 1570 1584 1571 emitPointerValidation(jit, GPRInfo::regT 0, JSEntryPtrTag);1572 jit.call(GPRInfo::regT 0, JSEntryPtrTag);1585 emitPointerValidation(jit, GPRInfo::regT1, JSEntryPtrTag); 1586 jit.call(GPRInfo::regT1, JSEntryPtrTag); 1573 1587 1574 1588 // Wrap return value … … 1583 1597 resultIsPrimitive.append(jit.branchIfNotObject(resultRegs.payloadGPR())); 1584 1598 1585 jit.move(CCallHelpers::TrustedImmPtr(tagCFunction<OperationPtrTag>(operationGetWrappedValueForCaller)), GPRInfo::nonArgGPR0);1586 emitPointerValidation(jit, GPRInfo::nonArgGPR0, OperationPtrTag);1587 1588 1599 jit.loadCell(CCallHelpers::addressFor(CallFrameSlot::callee), GPRInfo::regT2); 1589 1600 jit.setupArguments<decltype(operationGetWrappedValueForCaller)>(GPRInfo::regT2, resultRegs); 1590 1601 jit.prepareCallOperation(vm); 1602 jit.move(CCallHelpers::TrustedImmPtr(tagCFunction<OperationPtrTag>(operationGetWrappedValueForCaller)), GPRInfo::nonArgGPR0); 1603 emitPointerValidation(jit, GPRInfo::nonArgGPR0, OperationPtrTag); 1591 1604 jit.call(GPRInfo::nonArgGPR0, OperationPtrTag); 1592 1605 exceptionChecks.append(jit.emitJumpIfException(vm));
Note:
See TracChangeset
for help on using the changeset viewer.