Convert the ObjC @synchronized cleanups to laziness. This is not actually

a big deal, except that I want to eliminate the shared-code EH cleanups
in preparation for a significant algorithmic fix.

llvm-svn: 108973
This commit is contained in:
John McCall 2010-07-21 00:41:47 +00:00
parent 8f51041184
commit c20acd31f7
2 changed files with 32 additions and 13 deletions

View File

@ -1855,6 +1855,19 @@ llvm::Constant *CGObjCGNU::EnumerationMutationFunction() {
return CGM.CreateRuntimeFunction(FTy, "objc_enumerationMutation");
}
namespace {
struct CallSyncExit : EHScopeStack::LazyCleanup {
llvm::Value *SyncExitFn;
llvm::Value *SyncArg;
CallSyncExit(llvm::Value *SyncExitFn, llvm::Value *SyncArg)
: SyncExitFn(SyncExitFn), SyncArg(SyncArg) {}
void Emit(CodeGenFunction &CGF, bool IsForEHCleanup) {
CGF.Builder.CreateCall(SyncExitFn, SyncArg)->setDoesNotThrow();
}
};
}
void CGObjCGNU::EmitSynchronizedStmt(CodeGen::CodeGenFunction &CGF,
const ObjCAtSynchronizedStmt &S) {
std::vector<const llvm::Type*> Args(1, IdTy);
@ -1871,13 +1884,9 @@ void CGObjCGNU::EmitSynchronizedStmt(CodeGen::CodeGenFunction &CGF,
CGF.Builder.CreateCall(SyncEnter, SyncArg);
// Register an all-paths cleanup to release the lock.
{
CodeGenFunction::CleanupBlock ReleaseScope(CGF, NormalAndEHCleanup);
llvm::Value *SyncExit = CGM.CreateRuntimeFunction(FTy, "objc_sync_exit");
SyncArg = CGF.Builder.CreateBitCast(SyncArg, IdTy);
CGF.Builder.CreateCall(SyncExit, SyncArg);
}
llvm::Value *SyncExit = CGM.CreateRuntimeFunction(FTy, "objc_sync_exit");
CGF.EHStack.pushLazyCleanup<CallSyncExit>(NormalAndEHCleanup,
SyncExit, SyncArg);
// Emit the body of the statement.
CGF.EmitStmt(S.getSynchBody());

View File

@ -5695,6 +5695,19 @@ void CGObjCNonFragileABIMac::EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF,
return;
}
namespace {
struct CallSyncExit : EHScopeStack::LazyCleanup {
llvm::Value *SyncExitFn;
llvm::Value *SyncArg;
CallSyncExit(llvm::Value *SyncExitFn, llvm::Value *SyncArg)
: SyncExitFn(SyncExitFn), SyncArg(SyncArg) {}
void Emit(CodeGenFunction &CGF, bool IsForEHCleanup) {
CGF.Builder.CreateCall(SyncExitFn, SyncArg)->setDoesNotThrow();
}
};
}
void
CGObjCNonFragileABIMac::EmitSynchronizedStmt(CodeGen::CodeGenFunction &CGF,
const ObjCAtSynchronizedStmt &S) {
@ -5707,12 +5720,9 @@ CGObjCNonFragileABIMac::EmitSynchronizedStmt(CodeGen::CodeGenFunction &CGF,
->setDoesNotThrow();
// Register an all-paths cleanup to release the lock.
{
CodeGenFunction::CleanupBlock ReleaseScope(CGF, NormalAndEHCleanup);
CGF.Builder.CreateCall(ObjCTypes.getSyncExitFn(), SyncArg)
->setDoesNotThrow();
}
CGF.EHStack.pushLazyCleanup<CallSyncExit>(NormalAndEHCleanup,
ObjCTypes.getSyncExitFn(),
SyncArg);
// Emit the body of the statement.
CGF.EmitStmt(S.getSynchBody());