From: Fariborz Jahanian Date: Tue, 18 Nov 2008 22:37:34 +0000 (+0000) Subject: Patch for generation of weak write barriers for objc X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=3e283e344595e0bd499b13b30a92b7d9c10a2140;p=clang Patch for generation of weak write barriers for objc __weak objects. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@59560 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp index d537c9ca81..98a54c6863 100644 --- a/lib/CodeGen/CGExpr.cpp +++ b/lib/CodeGen/CGExpr.cpp @@ -154,7 +154,7 @@ RValue CodeGenFunction::EmitLoadOfLValue(LValue LV, QualType ExprType) { if (LV.isObjcWeak()) { // load of a __weak object. llvm::Value *AddrWeakObj = LV.getAddress(); - llvm::Value *read_weak = CGM.getObjCRuntime().EmitObjCWeakCall(*this, + llvm::Value *read_weak = CGM.getObjCRuntime().EmitObjCWeakRead(*this, AddrWeakObj); return RValue::get(read_weak); } @@ -335,6 +335,14 @@ RValue CodeGenFunction::EmitLoadOfExtVectorElementLValue(LValue LV, /// is 'Ty'. void CodeGenFunction::EmitStoreThroughLValue(RValue Src, LValue Dst, QualType Ty) { + if (Dst.isObjcWeak()) { + // load of a __weak object. + llvm::Value *LvalueDst = Dst.getAddress(); + llvm::Value *src = Src.getScalarVal(); + CGM.getObjCRuntime().EmitObjCWeakAssign(*this, src, LvalueDst); + return; + } + if (!Dst.isSimple()) { if (Dst.isVectorElt()) { // Read/modify/write the vector, inserting the new element. diff --git a/lib/CodeGen/CGObjCGNU.cpp b/lib/CodeGen/CGObjCGNU.cpp index d57710c5e5..91b8587e1a 100644 --- a/lib/CodeGen/CGObjCGNU.cpp +++ b/lib/CodeGen/CGObjCGNU.cpp @@ -130,8 +130,10 @@ public: const ObjCAtThrowStmt &S); virtual void EmitSynchronizedStmt(CodeGen::CodeGenFunction &CGF, const ObjCAtSynchronizedStmt &S); - virtual llvm::Value * EmitObjCWeakCall(CodeGen::CodeGenFunction &CGF, + virtual llvm::Value * EmitObjCWeakRead(CodeGen::CodeGenFunction &CGF, llvm::Value *AddrWeakObj); + virtual void EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF, + llvm::Value *src, llvm::Value *dst); }; } // end anonymous namespace @@ -970,12 +972,18 @@ void CGObjCGNU::EmitSynchronizedStmt(CodeGen::CodeGenFunction &CGF, CGF.ErrorUnsupported(&S, "@synchronized statement"); } -llvm::Value * CGObjCGNU::EmitObjCWeakCall(CodeGen::CodeGenFunction &CGF, +llvm::Value * CGObjCGNU::EmitObjCWeakRead(CodeGen::CodeGenFunction &CGF, llvm::Value *AddrWeakObj) { return 0; } +void CGObjCGNU::EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF, + llvm::Value *src, llvm::Value *dst) +{ + return; +} + CodeGen::CGObjCRuntime *CodeGen::CreateGNUObjCRuntime(CodeGen::CodeGenModule &CGM){ return new CGObjCGNU(CGM); } diff --git a/lib/CodeGen/CGObjCMac.cpp b/lib/CodeGen/CGObjCMac.cpp index f3cf21eb31..e6c2650a2e 100644 --- a/lib/CodeGen/CGObjCMac.cpp +++ b/lib/CodeGen/CGObjCMac.cpp @@ -454,8 +454,10 @@ public: const ObjCAtThrowStmt &S); virtual void EmitSynchronizedStmt(CodeGen::CodeGenFunction &CGF, const ObjCAtSynchronizedStmt &S); - virtual llvm::Value * EmitObjCWeakCall(CodeGen::CodeGenFunction &CGF, + virtual llvm::Value * EmitObjCWeakRead(CodeGen::CodeGenFunction &CGF, llvm::Value *AddrWeakObj); + virtual void EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF, + llvm::Value *src, llvm::Value *dst); }; } // end anonymous namespace @@ -1776,17 +1778,28 @@ void CodeGenFunction::EmitJumpThroughFinally(ObjCEHEntry *E, EmitBranch(ExecuteTryExit ? E->FinallyBlock : E->FinallyNoExit); } -/// EmitObjCWeakCall - Code gen for loading value of a __weak +/// EmitObjCWeakRead - Code gen for loading value of a __weak /// object: objc_read_weak (id *src) /// -llvm::Value * CGObjCMac::EmitObjCWeakCall(CodeGen::CodeGenFunction &CGF, +llvm::Value * CGObjCMac::EmitObjCWeakRead(CodeGen::CodeGenFunction &CGF, llvm::Value *AddrWeakObj) { llvm::Value *read_weak = CGF.Builder.CreateCall(ObjCTypes.GcReadWeakFn, - AddrWeakObj, "weakobj"); + AddrWeakObj, "weakread"); return read_weak; } +/// EmitObjCWeakAssign - Code gen for assigning to a __weak object. +/// objc_assign_weak (id src, id *dst) +/// +void CGObjCMac::EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF, + llvm::Value *src, llvm::Value *dst) +{ + CGF.Builder.CreateCall2(ObjCTypes.GcAssignWeakFn, + src, dst, "weakassign"); + return; +} + /// EmitSynchronizedStmt - Code gen for @synchronized(expr) stmt; /// Effectively generating code for: /// objc_sync_enter(expr); diff --git a/lib/CodeGen/CGObjCRuntime.h b/lib/CodeGen/CGObjCRuntime.h index 37544e47e1..24288b1e44 100644 --- a/lib/CodeGen/CGObjCRuntime.h +++ b/lib/CodeGen/CGObjCRuntime.h @@ -145,8 +145,10 @@ public: const ObjCAtThrowStmt &S) = 0; virtual void EmitSynchronizedStmt(CodeGen::CodeGenFunction &CGF, const ObjCAtSynchronizedStmt &S) = 0; - virtual llvm::Value * EmitObjCWeakCall(CodeGen::CodeGenFunction &CGF, + virtual llvm::Value * EmitObjCWeakRead(CodeGen::CodeGenFunction &CGF, llvm::Value *AddrWeakObj) = 0; + virtual void EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF, + llvm::Value *src, llvm::Value *dest) = 0; }; /// Creates an instance of an Objective-C runtime class.