diff --git a/ANNOUNCE b/ANNOUNCE index 618ab6c..75950a3 100644 --- a/ANNOUNCE +++ b/ANNOUNCE @@ -1,50 +1,27 @@ -GNUstep Objective-C Runtime 1.6 +GNUstep Objective-C Runtime 1.6.1 =============================== -This is the seventh official release of the GNUstep Objective-C runtime (a.k.a. -libobjc2). This runtime was designed to support the features of Objective-C 2 -for use with GNUstep and other Objective-C programs. Highlights of this -release include: +This is a point release to the seventh official release of the GNUstep +Objective-C runtime (a.k.a. libobjc2). This runtime was designed to support +the features of Objective-C 2 for use with GNUstep and other Objective-C +programs. Highlights of this release include: -- Compatibility with the new runtime APIs introduced with Mac OS X 10.7 / iOS 5. +- Improved support for ARC autorelease pools. -- Support for small objects (ones hidden inside a pointer). On 32-bit systems, - the runtime permits one small object class, on 64-bit systems it permits 4. - This is used by GNUstep for small NSNumber and NSString instances, and these - are used by LanguageKit for message sending to small integers. +- Some small bug fixes in blocks support. -- Support for prototype-style object orientation. You can now add methods, as - well as associated references, to individual objects, and clone them. The - runtime now supports everything required for the JavaScript object model, - including the ability to use blocks as methods on x86, x86-64 and ARM. +- Improvements to the Objective-C++ unified exception model support. -- Support for Apple-compatible objc_msgSend() functions for x86, x86-64, and - ARM. Using these approximately halves the cost of message sending operations - and results in a 10% smaller total binary size. - -- A fully maintained POSIX Makefile to make bootstrapping builds and packaging - easier. This will be used automatically if GNUstep Make is not installed. - -- Improvements to the included LLVM optimisation passes. Testing on a 2.8GHz - Xeon, a loop of 200,000,000 class messages took 0.8 seconds with all - optimisations enabled (including speculative inlining). With -Os, the test - took 2 seconds. With explicit IMP caching in the source code, the test took - 1.2 seconds. For reference, the same test using the GCC Objective-C runtime - took 11 seconds (when compiled with either Clang/LLVM or GCC). - -Various features of this release required some per-platform assembly code. For -the 1.6.0 release, ARM, x86 and x86-64 (with the SysV ABI, not with the Win64 -ABI) are supported. Future releases in the 1.6.x series will extend this to -other architectures. +- Updated optimisation passes to work with LLVM 3.1 You may obtain the code for this release from subversion at the following subversion branch: -svn://svn.gna.org/svn/gnustep/libs/libobjc2/1.6 +svn://svn.gna.org/svn/gnustep/libs/libobjc2/1.6.1 Alternatively, a tarball is available from: -http://download.gna.org/gnustep/libobjc2-1.6.tar.bz2 +http://download.gna.org/gnustep/libobjc2-1.6.1.tar.bz2 The runtime library is responsible for implementing the core features of the object model, as well as exposing introspection features to the user. The diff --git a/opts/ClassLookupCache.cpp b/opts/ClassLookupCache.cpp index 6bdc8ff..0f74cf0 100644 --- a/opts/ClassLookupCache.cpp +++ b/opts/ClassLookupCache.cpp @@ -56,8 +56,13 @@ namespace GlobalVariable *classNameVar = dyn_cast( call->getOperand(0)->stripPointerCasts()); if (0 == classNameVar) { continue; } +#if (LLVM_MAJOR > 3) || ((LLVM_MAJOR == 3) && (LLVM_MINOR > 0)) + ConstantDataArray *init = dyn_cast( + classNameVar->getInitializer()); +#else ConstantArray *init = dyn_cast( classNameVar->getInitializer()); +#endif if (0 == init || !init->isCString()) { continue; } lookup.first = call; lookup.second = init->getAsString(); diff --git a/opts/ClassMethodInliner.cpp b/opts/ClassMethodInliner.cpp index f7a77e0..dff8b71 100644 --- a/opts/ClassMethodInliner.cpp +++ b/opts/ClassMethodInliner.cpp @@ -85,9 +85,14 @@ namespace if (0 == method || method->isDeclaration()) { continue; } +#if (LLVM_MAJOR > 3) || ((LLVM_MAJOR == 3) && (LLVM_MINOR > 0)) + InlineCost IC = CA.getInlineCost((*i), method, 200); +#else InlineCost IC = CA.getInlineCost((*i), method, NeverInline); +#define getCost getValue +#endif // FIXME: 200 is a random number. Pick a better one! - if (IC.isAlways() || (IC.isVariable() && IC.getValue() < 200)) { + if (IC.isAlways() || (IC.isVariable() && IC.getCost() < 200)) { cacher.SpeculativelyInline((*i).getInstruction(), method); i->getInstruction()->setMetadata(MessageSendMDKind, 0); modified = true; diff --git a/opts/IvarPass.cpp b/opts/IvarPass.cpp index a5f335c..648901b 100644 --- a/opts/IvarPass.cpp +++ b/opts/IvarPass.cpp @@ -47,7 +47,11 @@ namespace { User *super = cast(ClsStruct->getOperand(1)); if (isa(super)) return ""; GlobalVariable *name = cast(super->getOperand(0)); +#if (LLVM_MAJOR > 3) || ((LLVM_MAJOR == 3) && (LLVM_MINOR > 0)) + return cast(name->getInitializer())->getAsString(); +#else return cast(name->getInitializer())->getAsString(); +#endif } size_t sizeOfClass(const std::string &className) { @@ -88,7 +92,11 @@ namespace { cast( cast(ivar->getOperand(0))->getOperand(0)); std::string ivarNameStr = +#if (LLVM_MAJOR > 3) || ((LLVM_MAJOR == 3) && (LLVM_MINOR > 0)) + cast(name->getInitializer())->getAsString(); +#else cast(name->getInitializer())->getAsString(); +#endif // Remove the NULL terminator from the metadata string ivarNameStr.resize(ivarNameStr.size() - 1); if (ivarNameStr == ivarName.str()) diff --git a/opts/TypeFeedback.cpp b/opts/TypeFeedback.cpp index 09709d9..8c940ef 100644 --- a/opts/TypeFeedback.cpp +++ b/opts/TypeFeedback.cpp @@ -55,7 +55,11 @@ namespace { Int32Ty = IntegerType::get(VMContext, 32); LLVMPointerType *PtrTy = Type::getInt8PtrTy(VMContext); Constant *moduleName = +#if (LLVM_MAJOR > 3) || ((LLVM_MAJOR == 3) && (LLVM_MINOR > 0)) + ConstantDataArray::getString(VMContext, M.getModuleIdentifier(), true); +#else ConstantArray::get(VMContext, M.getModuleIdentifier(), true); +#endif moduleName = new GlobalVariable(M, moduleName->getType(), true, GlobalValue::InternalLinkage, moduleName, ".objc_profile_module_name"); @@ -75,7 +79,11 @@ namespace { functions.push_back(ConstantExpr::getBitCast(F, PtrTy)); Constant * ConstStr = +#if (LLVM_MAJOR > 3) || ((LLVM_MAJOR == 3) && (LLVM_MINOR > 0)) + llvm::ConstantDataArray::getString(VMContext, F->getName(), true); +#else llvm::ConstantArray::get(VMContext, F->getName()); +#endif ConstStr = new GlobalVariable(M, ConstStr->getType(), true, GlobalValue::PrivateLinkage, ConstStr, "str"); functions.push_back( diff --git a/opts/TypeFeedbackDrivenInliner.cpp b/opts/TypeFeedbackDrivenInliner.cpp index 2658b65..a189f03 100644 --- a/opts/TypeFeedbackDrivenInliner.cpp +++ b/opts/TypeFeedbackDrivenInliner.cpp @@ -68,9 +68,14 @@ namespace { Function *method = M.getFunction(Entry->begin()->getKey()); if (0 == method || method->isDeclaration()) { continue; } +#if (LLVM_MAJOR > 3) || ((LLVM_MAJOR == 3) && (LLVM_MINOR > 0)) + InlineCost IC = CA.getInlineCost((*i), method, 200); +#else InlineCost IC = CA.getInlineCost((*i), method, NeverInline); +#define getCost getValue +#endif // FIXME: 200 is a random number. Pick a better one! - if (IC.isAlways() || (IC.isVariable() && IC.getValue() < 200)) { + if (IC.isAlways() || (IC.isVariable() && IC.getCost() < 200)) { cacher.SpeculativelyInline((*i).getInstruction(), method); modified = true; }