gnustep-dev
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Exported Constant Strings


From: David Ayers
Subject: Exported Constant Strings
Date: Thu, 06 Nov 2003 18:17:44 +0100
User-agent: Mozilla/5.0 (Windows; U; Windows NT 5.0; en-US; rv:1.5) Gecko/20031007

Hello everyone,

The reason my GSLock/Unicode.m patch broke GNUMail had to do with the fact that the global strings (like NSWillBecomeMutliThreaded) defined in externs.m weren't initialized and notifications where unduely being dispatched. (One result was that NSNotifcationCenter was replacing locked locks (that may have been held by other threads) upon executing excess _becomeThreaded: invocations. But Richards recent reorganization of NSNotificationCenter code has already done away with that problem.)

Anyway, the reason why these identifiers weren't allocated statically is that they are often used in collection classes and are subject to many isEqual: calls implying -hash invocations. Now unlike dynamically created strings which can store their hash values, static strings calculate them on every invocation. I've included a patch for Testing/benchmark.m that shows this and it convinced me that using dynamically allocated strings is a good idea.

OTOH, we need valid values from the beginning. So my proposal is to consistently initialize our exported strings with static strings and then replace them with dynamically allocated versions. I've added a macro to GSPrivate.h that can be used for that purpose. I also propose to move the remaining strings from externs.m into the respective NS*.m files and have the replacement done in the corresponding +intialize methods. (It seems these strings have been moving out of this file bit by bit since the end of 2001.)

Some of the current constant strings on NS*.[hm] files ae currently declared:
NSString * const
These cannot be replaced. Personally I don't think guarding these identifiers from modification isn't work while the extra cost of performance. Others may think differently. I'd like to know what people would think if all these NSString * const's would be replaced by NSString * and than also have them replaced by dynamically allocated versions during +initialize, or if you'd rather make all the current constant strings NSString * const. (In which case I'd try to look into a scheme for NXConstantString's to store their hash values somehow... once I have the time as I'm actually working on a GDL2 audit and some private projects right now.)

Oh, I also added some -copy tests to benchmark.m while I was in there.

OK to install the patch?

   * Source/GSPrivate.h (GS_REPLACE_CONSTANT_STRING): New macro.
   * Source/externs.m: Initialize constant strings statically.
     (GSBuildStrings): Replace static strings with dynamic versions.
   * Testing/benchmark.m: Added tests for NSString -hash and -copy.
     Aligned ouput.
   * Testing/externs.m: New test.
* Testing/GNUmakefile: Added externs.m test.
Cheers,
David

Index: Source/GSPrivate.h
===================================================================
RCS file: /cvsroot/gnustep/gnustep/core/base/Source/GSPrivate.h,v
retrieving revision 1.8
diff -u -r1.8 GSPrivate.h
--- Source/GSPrivate.h  5 Nov 2003 02:11:49 -0000       1.8
+++ Source/GSPrivate.h  6 Nov 2003 15:27:03 -0000
@@ -48,6 +48,28 @@
     NSZoneFree(NSDefaultMallocZone(), _base); \
   }
 
+/**
+ * Macro to consistently replace public accessable
+ * constant strings with dynamically allocated versions.
+ * This method assumes an initialzed NSStringClass symbol
+ * which contains the Class object of NSString.  <br>
+ * Most public accesable strings are used in collection classes
+ * like NSDictionary, and therefor tend to receive -isEqual:
+ * messages (and therefore -hash) rather often.  Statically
+ * allocated strings must calculate thier hash values where
+ * dynamically allocated strings can store them.  This optimization
+ * is by far more effective than using NSString * const.  
+ * The backdraw is that the memory managent cannot enforce these values
+ * to remain unaltered as it would for variables declared NSString * const.
+ * Yet the optimization of the stored hash value is currently deemed
+ * more important.
+ */
+#define GS_REPLACE_CONSTANT_STRING(ID) \
+  ID = [[NSStringClass alloc] initWithCString: [ID cString]]
+/* Using cString here is OK here
+   because NXConstantString returns a pointer
+   to it's internal pointer.  */
+
 /*
  * Function to get the name of a string encoding as an NSString.
  */
Index: Source/NSNotificationCenter.m
===================================================================
RCS file: /cvsroot/gnustep/gnustep/core/base/Source/NSNotificationCenter.m,v
retrieving revision 1.41
diff -u -r1.41 NSNotificationCenter.m
--- Source/NSNotificationCenter.m       3 Nov 2003 12:32:46 -0000       1.41
+++ Source/NSNotificationCenter.m       6 Nov 2003 15:27:04 -0000
@@ -1052,8 +1052,10 @@
          while (count-- > arrayBase)
            {
              o = GSIArrayItemAtIndex(a, count).ext;
-             if (o->next != 0) 
-               (*o->method)(o->observer, o->selector, notification);
+             if (o->next != 0)
+               {
+                 (*o->method)(o->observer, o->selector, notification);
+               }
            }
          GSIArrayRemoveItemsFromIndex(a, arrayBase);
 
Index: Source/externs.m
===================================================================
RCS file: /cvsroot/gnustep/gnustep/core/base/Source/externs.m,v
retrieving revision 1.43
diff -u -r1.43 externs.m
--- Source/externs.m    28 Jul 2003 17:01:16 -0000      1.43
+++ Source/externs.m    6 Nov 2003 15:27:04 -0000
@@ -28,6 +28,8 @@
 #include "Foundation/NSArray.h"
 #include "Foundation/NSException.h"
 
+#include "GSPrivate.h"
+
 /* Global lock to be used by classes when operating on any global
    data that invoke other methods which also access global; thus,
    creating the potential for deadlock. */
@@ -35,39 +37,39 @@
 NSRecursiveLock *gnustep_global_lock = nil;
 
 /*
- * Connection Notification Strings.
+ * NSConnection Notification Strings.
  */
-NSString *NSConnectionDidDieNotification;
+NSString *NSConnectionDidDieNotification = @"NSConnectionDidDieNotification";
 
-NSString *NSConnectionDidInitializeNotification;
+NSString *NSConnectionDidInitializeNotification = 
@"NSConnectionDidInitializeNotification";
 
 
 /*
  * NSThread Notifications
  */
-NSString *NSWillBecomeMultiThreadedNotification;
+NSString *NSWillBecomeMultiThreadedNotification = 
@"NSWillBecomeMultiThreadedNotification";
 
-NSString *NSThreadDidStartNotification;
+NSString *NSThreadDidStartNotification = @"NSThreadDidStartNotification";
 
-NSString *NSThreadWillExitNotification;
+NSString *NSThreadWillExitNotification = @"NSThreadWillExitNotification";
 
 
 /*
  * Port Notifications
  */
-NSString *PortBecameInvalidNotification;
+NSString *PortBecameInvalidNotification = @"PortBecameInvalidNotification";
 
-NSString *InPortClientBecameInvalidNotification;
+NSString *InPortClientBecameInvalidNotification = 
@"InPortClientBecameInvalidNotification";
 
-NSString *InPortAcceptedClientNotification;
+NSString *InPortAcceptedClientNotification = 
@"InPortAcceptedClientNotification";
 
 
-NSString *NSPortDidBecomeInvalidNotification;
+NSString *NSPortDidBecomeInvalidNotification = 
@"NSPortDidBecomeInvalidNotification";
 
 
 
 /* RunLoop modes */
-NSString *NSConnectionReplyMode;
+NSString *NSConnectionReplyMode = @"NSConnectionReplyMode";
 
 
 
@@ -75,133 +77,137 @@
 NSUncaughtExceptionHandler *_NSUncaughtExceptionHandler;
 
 /* NSBundle */
-NSString *NSBundleDidLoadNotification;
+NSString *NSBundleDidLoadNotification = @"NSBundleDidLoadNotification";
 
-NSString *NSShowNonLocalizedStrings;
+NSString *NSShowNonLocalizedStrings = @"NSShowNonLocalizedStrings";
 
-NSString *NSLoadedClasses;
+NSString *NSLoadedClasses = @"NSLoadedClasses";
 
 
 /* Stream */
-NSString *StreamException;
+NSString *StreamException = @"StreamException";
 
 
 
 /* Standard domains */
-NSString *NSArgumentDomain;
+NSString *NSArgumentDomain = @"NSArgumentDomain";
 
-NSString *NSGlobalDomain;
+NSString *NSGlobalDomain = @"NSGlobalDomain";
 
-NSString *NSRegistrationDomain;
+NSString *NSRegistrationDomain = @"NSRegistrationDomain";
 
 
 /* Public notification */
-NSString *NSUserDefaultsDidChangeNotification;
+NSString *NSUserDefaultsDidChangeNotification = 
@"NSUserDefaultsDidChangeNotification";
 
 
 /* Keys for language-dependent information */
-NSString *NSWeekDayNameArray;
+NSString *NSWeekDayNameArray = @"NSWeekDayNameArray";
 
-NSString *NSShortWeekDayNameArray;
+NSString *NSShortWeekDayNameArray = @"NSShortWeekDayNameArray";
 
-NSString *NSMonthNameArray;
+NSString *NSMonthNameArray = @"NSMonthNameArray";
 
-NSString *NSShortMonthNameArray;
+NSString *NSShortMonthNameArray = @"NSShortMonthNameArray";
 
-NSString *NSTimeFormatString;
+NSString *NSTimeFormatString = @"NSTimeFormatString";
 
-NSString *NSDateFormatString;
+NSString *NSDateFormatString = @"NSDateFormatString";
 
-NSString *NSShortDateFormatString;
+NSString *NSShortDateFormatString = @"NSShortDateFormatString";
 
-NSString *NSTimeDateFormatString;
+NSString *NSTimeDateFormatString = @"NSTimeDateFormatString";
 
-NSString *NSShortTimeDateFormatString;
+NSString *NSShortTimeDateFormatString = @"NSShortTimeDateFormatString";
 
-NSString *NSCurrencySymbol;
+NSString *NSCurrencySymbol = @"NSCurrencySymbol";
 
-NSString *NSDecimalSeparator;
+NSString *NSDecimalSeparator = @"NSDecimalSeparator";
 
-NSString *NSThousandsSeparator;
+NSString *NSThousandsSeparator = @"NSThousandsSeparator";
 
-NSString *NSInternationalCurrencyString;
+NSString *NSInternationalCurrencyString = @"NSInternationalCurrencyString";
 
-NSString *NSCurrencyString;
+NSString *NSCurrencyString = @"NSCurrencyString";
 
-NSString *NSNegativeCurrencyFormatString;
+NSString *NSNegativeCurrencyFormatString = @"NSNegativeCurrencyFormatString";
 
-NSString *NSPositiveCurrencyFormatString;
+NSString *NSPositiveCurrencyFormatString = @"NSPositiveCurrencyFormatString";
 
-NSString *NSDecimalDigits;
+NSString *NSDecimalDigits = @"NSDecimalDigits";
 
-NSString *NSAMPMDesignation;
+NSString *NSAMPMDesignation = @"NSAMPMDesignation";
 
 
-NSString *NSHourNameDesignations;
+NSString *NSHourNameDesignations = @"NSHourNameDesignations";
 
-NSString *NSYearMonthWeekDesignations;
+NSString *NSYearMonthWeekDesignations = @"NSYearMonthWeekDesignations";
 
-NSString *NSEarlierTimeDesignations;
+NSString *NSEarlierTimeDesignations = @"NSEarlierTimeDesignations";
 
-NSString *NSLaterTimeDesignations;
+NSString *NSLaterTimeDesignations = @"NSLaterTimeDesignations";
 
-NSString *NSThisDayDesignations;
+NSString *NSThisDayDesignations = @"NSThisDayDesignations";
 
-NSString *NSNextDayDesignations;
+NSString *NSNextDayDesignations = @"NSNextDayDesignations";
 
-NSString *NSNextNextDayDesignations;
+NSString *NSNextNextDayDesignations = @"NSNextNextDayDesignations";
 
-NSString *NSPriorDayDesignations;
+NSString *NSPriorDayDesignations = @"NSPriorDayDesignations";
 
-NSString *NSDateTimeOrdering;
+NSString *NSDateTimeOrdering = @"NSDateTimeOrdering";
 
 
 /* These are in OPENSTEP 4.2 */
-NSString *NSLanguageCode;
+NSString *NSLanguageCode = @"NSLanguageCode";
 
-NSString *NSLanguageName;
+NSString *NSLanguageName = @"NSLanguageName";
 
-NSString *NSFormalName;
+NSString *NSFormalName = @"NSFormalName";
 
 /* For GNUstep */
-NSString *NSLocale;
+NSString *NSLocale = @"NSLocale";
 
 
 /*
  * Keys for the NSDictionary returned by [NSConnection -statistics]
  */
 /* These in OPENSTEP 4.2 */
-NSString *NSConnectionRepliesReceived;
+NSString *NSConnectionRepliesReceived = @"NSConnectionRepliesReceived";
 
-NSString *NSConnectionRepliesSent;
+NSString *NSConnectionRepliesSent = @"NSConnectionRepliesSent";
 
-NSString *NSConnectionRequestsReceived;
+NSString *NSConnectionRequestsReceived = @"NSConnectionRequestsReceived";
 
-NSString *NSConnectionRequestsSent;
+NSString *NSConnectionRequestsSent = @"NSConnectionRequestsSent";
 
 /* These Are GNUstep extras */
-NSString *NSConnectionLocalCount;
+NSString *NSConnectionLocalCount = @"NSConnectionLocalCount";
 
-NSString *NSConnectionProxyCount;
+NSString *NSConnectionProxyCount = @"NSConnectionProxyCount";
 
 /* Class description notification */
-NSString *NSClassDescriptionNeededForClassNotification;
+NSString *NSClassDescriptionNeededForClassNotification = 
@"NSClassDescriptionNeededForClassNotification";
 
 
 /*
- *     Setup function called when NSString is initialised.
- *     We make all the constant strings not be constant strings so they can
- *     cache their hash values and be used much more efficiently as keys in
- *     dictionaries etc.
+ * Opimization function called when NSObject is initialised.
+ * We replace all the constant strings so they can
+ * cache their hash values and be used much more efficiently as keys in
+ * dictionaries etc.
+ * We initialize with constant strings so that
+ * code executed before NSObject +initialize calls us,
+ * will have valid values.
  */
+
 void
 GSBuildStrings()
 {
-  static Class SClass = 0;
+  static Class NSStringClass = 0;
 
-  if (SClass == 0)
+  if (NSStringClass == 0)
     {
-      SClass = [NSString class];
+      NSStringClass = [NSString class];
 
       /*
        * Ensure that NSString is initialized ... because we are called
@@ -210,131 +216,64 @@
        * Use performSelector: to avoid compiler warning about clash of
        * return value types in two different versions of initialize.
        */
-      [SClass performSelector: @selector(initialize)];
+      [NSStringClass performSelector: @selector(initialize)];
 
-      InPortAcceptedClientNotification
-       = [[SClass alloc] initWithCString:
-       "InPortAcceptedClientNotification"];
-      InPortClientBecameInvalidNotification
-       = [[SClass alloc] initWithCString:
-       "InPortClientBecameInvalidNotification"];
-      NSAMPMDesignation
-       = [[SClass alloc] initWithCString: "NSAMPMDesignation"];
-      NSArgumentDomain
-       = [[SClass alloc] initWithCString: "NSArgumentDomain"];
-      NSBundleDidLoadNotification
-       = [[SClass alloc] initWithCString: "NSBundleDidLoadNotification"];
-      NSConnectionDidDieNotification
-       = [[SClass alloc] initWithCString:
-       "NSConnectionDidDieNotification"];
-      NSConnectionDidInitializeNotification
-       = [[SClass alloc] initWithCString:
-       "NSConnectionDidInitializeNotification"];
-      NSConnectionLocalCount
-       = [[SClass alloc] initWithCString: "NSConnectionLocalCount"];
-      NSConnectionProxyCount
-       = [[SClass alloc] initWithCString: "NSConnectionProxyCount"];
-      NSConnectionRepliesReceived
-       = [[SClass alloc] initWithCString: "NSConnectionRepliesReceived"];
-      NSConnectionRepliesSent
-       = [[SClass alloc] initWithCString: "NSConnectionRepliesSent"];
-      NSConnectionReplyMode
-       = [[SClass alloc] initWithCString: "NSConnectionReplyMode"];
-      NSConnectionRequestsReceived
-       = [[SClass alloc] initWithCString: "NSConnectionRequestsReceived"];
-      NSConnectionRequestsSent
-       = [[SClass alloc] initWithCString: "NSConnectionRequestsSent"];
-      NSCurrencyString
-       = [[SClass alloc] initWithCString: "NSCurrencyString"];
-      NSCurrencySymbol
-       = [[SClass alloc] initWithCString: "NSCurrencySymbol"];
-      NSDateFormatString
-       = [[SClass alloc] initWithCString: "NSDateFormatString"];
-      NSDateTimeOrdering
-       = [[SClass alloc] initWithCString: "NSDateTimeOrdering"];
-      NSDecimalDigits
-       = [[SClass alloc] initWithCString: "NSDecimalDigits"];
-      NSDecimalSeparator
-       = [[SClass alloc] initWithCString: "NSDecimalSeparator"];
-      NSEarlierTimeDesignations
-       = [[SClass alloc] initWithCString: "NSEarlierTimeDesignations"];
-      NSFormalName
-        = [[SClass alloc] initWithCString: "NSFormalName"];
-      NSGlobalDomain
-       = [[SClass alloc] initWithCString: "NSGlobalDomain"];
-      NSHourNameDesignations
-       = [[SClass alloc] initWithCString: "NSHourNameDesignations"];
-      NSInternationalCurrencyString
-       = [[SClass alloc] initWithCString: "NSInternationalCurrencyString"];
-      NSLanguageCode
-        = [[SClass alloc] initWithCString: "NSLanguageCode"];
-      NSLanguageName
-        = [[SClass alloc] initWithCString: "NSLanguageName"];
-      NSLaterTimeDesignations
-       = [[SClass alloc] initWithCString: "NSLaterTimeDesignations"];
-      NSLoadedClasses
-       = [[SClass alloc] initWithCString: "NSLoadedClasses"];
-      NSLocale
-       = [[SClass alloc] initWithCString: "NSLocale"];
-      NSMonthNameArray
-       = [[SClass alloc] initWithCString: "NSMonthNameArray"];
-      NSNegativeCurrencyFormatString
-        = [[SClass alloc] initWithCString:
-       "NSNegativeCurrencyFormatString"];
-      NSNextDayDesignations
-       = [[SClass alloc] initWithCString: "NSNextDayDesignations"];
-      NSNextNextDayDesignations
-       = [[SClass alloc] initWithCString: "NSNextNextDayDesignations"];
-      NSPortDidBecomeInvalidNotification
-       = [[SClass alloc] initWithCString:
-       "NSPortDidBecomeInvalidNotification"];
-      NSPositiveCurrencyFormatString
-        = [[SClass alloc] initWithCString:
-       "NSPositiveCurrencyFormatString"];
-      NSPriorDayDesignations
-       = [[SClass alloc] initWithCString: "NSPriorDayDesignations"];
-      NSRegistrationDomain
-       = [[SClass alloc] initWithCString: "NSRegistrationDomain"];
-      NSShortDateFormatString
-        = [[SClass alloc] initWithCString: "NSShortDateFormatString"];
-      NSShortMonthNameArray
-       = [[SClass alloc] initWithCString: "NSShortMonthNameArray"];
-      NSShortTimeDateFormatString
-       = [[SClass alloc] initWithCString: "NSShortTimeDateFormatString"];
-      NSShortWeekDayNameArray
-       = [[SClass alloc] initWithCString: "NSShortWeekDayNameArray"];
-      NSShowNonLocalizedStrings
-       = [[SClass alloc] initWithCString: "NSShowNonLocalizedStrings"];
-      NSThisDayDesignations
-       = [[SClass alloc] initWithCString: "NSThisDayDesignations"];
-      NSThousandsSeparator
-       = [[SClass alloc] initWithCString: "NSThousandsSeparator"];
-      NSThreadDidStartNotification
-       = [[SClass alloc] initWithCString: "NSThreadDidStartNotification"];
-      NSThreadWillExitNotification
-       = [[SClass alloc] initWithCString: "NSThreadWillExitNotification"];
-      NSTimeDateFormatString
-       = [[SClass alloc] initWithCString: "NSTimeDateFormatString"];
-      NSTimeFormatString
-       = [[SClass alloc] initWithCString: "NSTimeFormatString"];
-      NSUserDefaultsDidChangeNotification
-       = [[SClass alloc] initWithCString:
-       "NSUserDefaultsDidChangeNotification"];
-      NSWeekDayNameArray
-       = [[SClass alloc] initWithCString: "NSWeekDayNameArray"];
-      NSWillBecomeMultiThreadedNotification
-       = [[SClass alloc] initWithCString:
-       "NSWillBecomeMultiThreadedNotification"];
-      NSYearMonthWeekDesignations
-       = [[SClass alloc] initWithCString: "NSYearMonthWeekDesignations"];
-      PortBecameInvalidNotification
-       = [[SClass alloc] initWithCString: "PortBecameInvalidNotification"];
-      StreamException
-       = [[SClass alloc] initWithCString: "StreamException"];
-
-      NSClassDescriptionNeededForClassNotification
-        = [[SClass alloc] initWithCString:
-       "NSClassDescriptionNeededForClassNotification"];
+      GS_REPLACE_CONSTANT_STRING(InPortAcceptedClientNotification);
+      GS_REPLACE_CONSTANT_STRING(InPortClientBecameInvalidNotification);
+      GS_REPLACE_CONSTANT_STRING(NSAMPMDesignation);
+      GS_REPLACE_CONSTANT_STRING(NSArgumentDomain);
+      GS_REPLACE_CONSTANT_STRING(NSBundleDidLoadNotification);
+      GS_REPLACE_CONSTANT_STRING(NSClassDescriptionNeededForClassNotification);
+      GS_REPLACE_CONSTANT_STRING(NSConnectionDidDieNotification);
+      GS_REPLACE_CONSTANT_STRING(NSConnectionDidInitializeNotification);
+      GS_REPLACE_CONSTANT_STRING(NSConnectionLocalCount);
+      GS_REPLACE_CONSTANT_STRING(NSConnectionProxyCount);
+      GS_REPLACE_CONSTANT_STRING(NSConnectionRepliesReceived);
+      GS_REPLACE_CONSTANT_STRING(NSConnectionRepliesSent);
+      GS_REPLACE_CONSTANT_STRING(NSConnectionReplyMode);
+      GS_REPLACE_CONSTANT_STRING(NSConnectionRequestsReceived);
+      GS_REPLACE_CONSTANT_STRING(NSConnectionRequestsSent);
+      GS_REPLACE_CONSTANT_STRING(NSCurrencyString);
+      GS_REPLACE_CONSTANT_STRING(NSCurrencySymbol);
+      GS_REPLACE_CONSTANT_STRING(NSDateFormatString);
+      GS_REPLACE_CONSTANT_STRING(NSDateTimeOrdering);
+      GS_REPLACE_CONSTANT_STRING(NSDecimalDigits);
+      GS_REPLACE_CONSTANT_STRING(NSDecimalSeparator);
+      GS_REPLACE_CONSTANT_STRING(NSEarlierTimeDesignations);
+      GS_REPLACE_CONSTANT_STRING(NSFormalName);
+      GS_REPLACE_CONSTANT_STRING(NSGlobalDomain);
+      GS_REPLACE_CONSTANT_STRING(NSHourNameDesignations);
+      GS_REPLACE_CONSTANT_STRING(NSInternationalCurrencyString);
+      GS_REPLACE_CONSTANT_STRING(NSLanguageCode);
+      GS_REPLACE_CONSTANT_STRING(NSLanguageName);
+      GS_REPLACE_CONSTANT_STRING(NSLaterTimeDesignations);
+      GS_REPLACE_CONSTANT_STRING(NSLoadedClasses);
+      GS_REPLACE_CONSTANT_STRING(NSLocale);
+      GS_REPLACE_CONSTANT_STRING(NSMonthNameArray);
+      GS_REPLACE_CONSTANT_STRING(NSNegativeCurrencyFormatString);
+      GS_REPLACE_CONSTANT_STRING(NSNextDayDesignations);
+      GS_REPLACE_CONSTANT_STRING(NSNextNextDayDesignations);
+      GS_REPLACE_CONSTANT_STRING(NSPortDidBecomeInvalidNotification);
+      GS_REPLACE_CONSTANT_STRING(NSPositiveCurrencyFormatString);
+      GS_REPLACE_CONSTANT_STRING(NSPriorDayDesignations);
+      GS_REPLACE_CONSTANT_STRING(NSRegistrationDomain);
+      GS_REPLACE_CONSTANT_STRING(NSShortDateFormatString);
+      GS_REPLACE_CONSTANT_STRING(NSShortMonthNameArray);
+      GS_REPLACE_CONSTANT_STRING(NSShortTimeDateFormatString);
+      GS_REPLACE_CONSTANT_STRING(NSShortWeekDayNameArray);
+      GS_REPLACE_CONSTANT_STRING(NSShowNonLocalizedStrings);
+      GS_REPLACE_CONSTANT_STRING(NSThisDayDesignations);
+      GS_REPLACE_CONSTANT_STRING(NSThousandsSeparator);
+      GS_REPLACE_CONSTANT_STRING(NSThreadDidStartNotification);
+      GS_REPLACE_CONSTANT_STRING(NSThreadWillExitNotification);
+      GS_REPLACE_CONSTANT_STRING(NSTimeDateFormatString);
+      GS_REPLACE_CONSTANT_STRING(NSTimeFormatString);
+      GS_REPLACE_CONSTANT_STRING(NSUserDefaultsDidChangeNotification);
+      GS_REPLACE_CONSTANT_STRING(NSWeekDayNameArray);
+      GS_REPLACE_CONSTANT_STRING(NSWillBecomeMultiThreadedNotification);
+      GS_REPLACE_CONSTANT_STRING(NSYearMonthWeekDesignations);
+      GS_REPLACE_CONSTANT_STRING(PortBecameInvalidNotification);
+      GS_REPLACE_CONSTANT_STRING(StreamException);
     }
 }
 
Index: Source/Additions/GSCategories.m
===================================================================
RCS file: /cvsroot/gnustep/gnustep/core/base/Source/Additions/GSCategories.m,v
retrieving revision 1.17
diff -u -r1.17 GSCategories.m
--- Source/Additions/GSCategories.m     1 Nov 2003 07:09:12 -0000       1.17
+++ Source/Additions/GSCategories.m     6 Nov 2003 15:27:05 -0000
@@ -880,7 +880,7 @@
  * GNUstep specific (non-standard) additions to the NSLock class.
  */
 
-static NSRecursiveLock *local_lock = nil;
+static GSLazyRecursiveLock *local_lock = nil;
 
 /* 
    This class only exists to provide 
@@ -897,9 +897,13 @@
 {
   if (local_lock == nil)
     {
+      /* As we do not know whether creating custom locks
+        may implicitly create other locks,
+        we use a recursive lock.  */
       local_lock = [GSLazyRecursiveLock new];
     }
 }
+
 @end
 
 GS_STATIC_INLINE id
Index: Testing/GNUmakefile
===================================================================
RCS file: /cvsroot/gnustep/gnustep/core/base/Testing/GNUmakefile,v
retrieving revision 1.33
diff -u -r1.33 GNUmakefile
--- Testing/GNUmakefile 30 Oct 2003 13:44:55 -0000      1.33
+++ Testing/GNUmakefile 6 Nov 2003 15:27:05 -0000
@@ -35,6 +35,7 @@
                benchmark \
                call \
                containers \
+               externs \
                fref \
                gslock \
                nsarchiver \
@@ -70,13 +71,11 @@
 # Don't make these normally
 ADDITIONAL_TOOLS = \
                diningPhilosophers \
-               gstcpport-client \
-               gstcpport-server \
                nsconnection_client \
                nsconnection_server \
 
-# TEST_TOOL_NAME += nsconnection_client nsconnection_server
-TEST_TOOL_NAME += nsconnection_client nsconnection_server $(ADDITIONAL_TOOLS)
+TEST_TOOL_NAME += $(ADDITIONAL_TOOLS)
+# TEST_TOOL_NAME += gstcpport-client gstcpport-server 
 
 # The tool Objective-C source files to be compiled
 awake_OBJC_FILES = awake.m
@@ -85,6 +84,7 @@
 call_OBJC_FILES = call.m
 containers_OBJC_FILES = containers.m
 diningPhilosophers_OBJC_FILES = diningPhilosophers.m
+externs_OBJC_FILES = externs.m
 fref_OBJC_FILES = fref.m
 gslock_OBJC_FILES = gslock.m
 gstcpport-client_OBJC_FILES = gstcpport-client.m
Index: Testing/benchmark.m
===================================================================
RCS file: /cvsroot/gnustep/gnustep/core/base/Testing/benchmark.m,v
retrieving revision 1.14
diff -u -r1.14 benchmark.m
--- Testing/benchmark.m 15 Oct 2002 04:55:51 -0000      1.14
+++ Testing/benchmark.m 6 Nov 2003 15:27:05 -0000
@@ -80,7 +80,7 @@
     }
   END_TIMER;
   baseline = [eTime timeIntervalSinceDate: sTime];
-  PRINT_TIMER("Baseline: 10 method calls");
+  PRINT_TIMER("Baseline: 10 method calls\t\t");
 
   START_TIMER;
   for (i = 0; i < MAX_COUNT; i++)
@@ -99,7 +99,7 @@
       i = [NSMutableDictionary class];
     }
   END_TIMER;
-  PRINT_TIMER("Class: 10 class method calls");
+  PRINT_TIMER("Class: 10 class method calls\t\t");
   
   obj = [MyObject new];
   
@@ -110,7 +110,7 @@
       i = [obj self];
     }
   END_TIMER;
-  PRINT_TIMER_NO_BASELINE("Category: 10 super calls");
+  PRINT_TIMER_NO_BASELINE("Category: 10 super calls\t\t");
   
   START_TIMER;
   for (i = 0; i < MAX_COUNT; i++)
@@ -129,7 +129,7 @@
       i = NSClassFromString (@"NSMutableDictionary");
     }
   END_TIMER;
-  PRINT_TIMER("Function: 10 NSClassFromStr");
+  PRINT_TIMER("Function: 10 NSClassFromStr\t\t");
 
   START_TIMER;
   myZone = NSCreateZone(2048, 2048, 1);
@@ -140,7 +140,7 @@
     }
   NSRecycleZone(myZone);
   END_TIMER;
-  PRINT_TIMER("Function: 1 zone alloc/free");
+  PRINT_TIMER("Function: 1 zone alloc/free\t\t");
 
   START_TIMER;
   myZone = NSCreateZone(2048, 2048, 0);
@@ -151,7 +151,7 @@
     }
   NSRecycleZone(myZone);
   END_TIMER;
-  PRINT_TIMER("Function: 1 zone2alloc/free");
+  PRINT_TIMER("Function: 1 zone2alloc/free\t\t");
 
   myZone = NSDefaultMallocZone();
   START_TIMER;
@@ -161,7 +161,7 @@
       NSZoneFree(myZone, mem);
     }
   END_TIMER;
-  PRINT_TIMER("Function: 1 def alloc/free");
+  PRINT_TIMER("Function: 1 def alloc/free\t\t");
 
   START_TIMER;
   myZone = NSCreateZone(2048, 2048, 1);
@@ -172,7 +172,7 @@
     }
   NSRecycleZone(myZone);
   END_TIMER;
-  PRINT_TIMER("NSObject: 1 zone all/init/rel");
+  PRINT_TIMER("NSObject: 1 zone all/init/rel\t\t");
 
   START_TIMER;
   myZone = NSCreateZone(2048, 2048, 0);
@@ -183,7 +183,7 @@
     }
   NSRecycleZone(myZone);
   END_TIMER;
-  PRINT_TIMER("NSObject: 1 zone2all/init/rel");
+  PRINT_TIMER("NSObject: 1 zone2all/init/rel\t\t");
 
   myZone = NSDefaultMallocZone();
   START_TIMER;
@@ -193,7 +193,7 @@
       [obj release];
     }
   END_TIMER;
-  PRINT_TIMER("NSObject: 1 def all/init/rel");
+  PRINT_TIMER("NSObject: 1 def all/init/rel\t\t");
 
   obj = [rootClass new];
   START_TIMER;
@@ -203,7 +203,7 @@
       [obj release];
     }
   END_TIMER;
-  PRINT_TIMER("NSObject: 10 retain/rel");
+  PRINT_TIMER("NSObject: 10 retain/rel\t\t");
   [obj release];
 
   obj = [rootClass new];
@@ -214,7 +214,7 @@
       [obj retain];
     }
   END_TIMER;
-  PRINT_TIMER("NSObject: 10 autorel/ret");
+  PRINT_TIMER("NSObject: 10 autorel/ret\t\t");
   [obj release];
 
   START_TIMER;
@@ -223,7 +223,7 @@
       [rootClass instancesRespondToSelector: @selector(hash)];
     }
   END_TIMER;
-  PRINT_TIMER("ObjC: 10 inst responds to sel");
+  PRINT_TIMER("ObjC: 10 inst responds to sel\t\t");
 
   mutex = objc_mutex_allocate();
   START_TIMER;
@@ -233,7 +233,7 @@
       objc_mutex_unlock(mutex);
     }
   END_TIMER;
-  PRINT_TIMER("ObjC: 10 objc_mutex_lock/unl");
+  PRINT_TIMER("ObjC: 10 objc_mutex_lock/unl\t\t");
   objc_mutex_deallocate(mutex);
 
   obj = [NSLock new];
@@ -244,7 +244,7 @@
       [obj unlock];
     }
   END_TIMER;
-  PRINT_TIMER("NSLock: 10 lock/unlock");
+  PRINT_TIMER("NSLock: 10 lock/unlock\t\t");
   [obj release];
 
 
@@ -273,7 +273,7 @@
       [array addObject: strings[i/10]];
     }
   END_TIMER;
-  PRINT_TIMER("NSArray (10 addObject:)");
+  PRINT_TIMER("NSArray (10 addObject:)\t\t");
 
   START_TIMER;
   for (i = 0; i < MAX_COUNT/100; i++)
@@ -281,7 +281,7 @@
       [array indexOfObject: strings[i]];
     }
   END_TIMER;
-  PRINT_TIMER("NSArray (1/100 indexOfObj)");
+  PRINT_TIMER("NSArray (1/100 indexOfObj)\t\t");
 
   START_TIMER;
   for (i = 0; i < MAX_COUNT/100; i++)
@@ -289,7 +289,7 @@
       [array indexOfObjectIdenticalTo: strings[i]];
     }
   END_TIMER;
-  PRINT_TIMER("NSArray (1/100 indexIdent)");
+  PRINT_TIMER("NSArray (1/100 indexIdent)\t\t");
 
   START_TIMER;
   for (i = 0; i < 1; i++)
@@ -297,7 +297,7 @@
       [array makeObjectsPerformSelector: @selector(hash)];
     }
   END_TIMER;
-  PRINT_TIMER("NSArray (once perform)");
+  PRINT_TIMER("NSArray (once perform)\t\t");
   AUTO_END;
 }
 
@@ -332,7 +332,7 @@
        }
     }
   END_TIMER;
-  PRINT_TIMER("NSDict (1 setObject:) ");
+  PRINT_TIMER("NSDict (1 setObject:) \t\t");
 
   START_TIMER;
   for (i = 0; i < MAX_COUNT; i++)
@@ -345,7 +345,7 @@
         }
     }
   END_TIMER;
-  PRINT_TIMER("NSDict (10 objectFor:) ");
+  PRINT_TIMER("NSDict (10 objectFor:) \t\t");
 
   START_TIMER;
   for (i = 0; i < MAX_COUNT*10; i++)
@@ -353,7 +353,7 @@
       [dict count];
     }
   END_TIMER;
-  PRINT_TIMER("NSDictionary (10 count)");
+  PRINT_TIMER("NSDictionary (10 count)\t\t");
 
   obj2 = [dict copy];
   START_TIMER;
@@ -362,7 +362,7 @@
       [dict isEqual: obj2];
     }
   END_TIMER;
-  PRINT_TIMER("NSDict (ten times isEqual:)");
+  PRINT_TIMER("NSDict (ten times isEqual:)\t\t");
   AUTO_END;
 }
 
@@ -414,7 +414,7 @@
       str = [stringClass stringWithCString: "hello world"];
     }
   END_TIMER;
-  PRINT_TIMER("NSString (1 cstring:) ");
+  PRINT_TIMER("NSString (1 cstring:) \t\t");
 
   START_TIMER;
   for (i = 0; i < MAX_COUNT*10; i++)
@@ -422,7 +422,64 @@
       [str length];
     }
   END_TIMER;
-  PRINT_TIMER("NSString (10 length)   ");
+  PRINT_TIMER("NSString (10 length)   \t\t");
+
+  START_TIMER;
+  for (i = 0; i < MAX_COUNT*10; i++)
+    {
+      [str copy];
+    }
+  END_TIMER;
+  PRINT_TIMER("NSString (10 copy) <initWithCString:>   ");
+
+  str = @"ConstantString";
+  START_TIMER;
+  for (i = 0; i < MAX_COUNT*10; i++)
+    {
+      [str copy];
+    }
+  END_TIMER;
+  PRINT_TIMER("NSString (10 copy) <@'ConstantString'>   ");
+
+  str = [[NSString alloc] initWithCStringNoCopy: (char *)[str cString]
+                         length: [str length]
+                         freeWhenDone: NO];
+  START_TIMER;
+  for (i = 0; i < MAX_COUNT*10; i++)
+    {
+      [str copy];
+    }
+  END_TIMER;
+  PRINT_TIMER("NSString (10 copy) <NoCopy:free:NO>   ");
+
+  str = [[NSString alloc] initWithCStringNoCopy: (char *)[str cString]
+                         length: [str length]
+                         freeWhenDone: YES];
+  START_TIMER;
+  for (i = 0; i < MAX_COUNT*10; i++)
+    {
+      [str copy];
+    }
+  END_TIMER;
+  PRINT_TIMER("NSString (10 copy) <NoCopy:free:YES>   ");
+
+  str = [stringClass stringWithCString: "hello world"];
+  START_TIMER;
+  for (i = 0; i < MAX_COUNT*10; i++)
+    {
+      [str hash];
+    }
+  END_TIMER;
+  PRINT_TIMER("NSString (10 hash) <initWithCString:>   ");
+
+  str = @"ConstantString";
+  START_TIMER;
+  for (i = 0; i < MAX_COUNT*10; i++)
+    {
+      [str hash];
+    }
+  END_TIMER;
+  PRINT_TIMER("NSString (10 hash) <@'ConstantString'>   ");
 
   START_TIMER;
   for (i = 0; i < MAX_COUNT/100; i++)
@@ -432,7 +489,7 @@
       [arp release];
     }
   END_TIMER;
-  PRINT_TIMER("NSString (1/100 mkplist) ");
+  PRINT_TIMER("NSString (1/100 mkplist) \t\t");
 
   START_TIMER;
   for (i = 0; i < MAX_COUNT/1000; i++)
@@ -440,7 +497,7 @@
       [plstr propertyList];
     }
   END_TIMER;
-  PRINT_TIMER("NSString (1/1000 plparse)");
+  PRINT_TIMER("NSString (1/1000 plparse)\t\t");
 
   START_TIMER;
   for (i = 0; i < MAX_COUNT/1000; i++)
@@ -455,7 +512,7 @@
       [arp release];
     }
   END_TIMER;
-  PRINT_TIMER("NSString (1/1000 plcomp)");
+  PRINT_TIMER("NSString (1/1000 plcomp)\t\t");
 
   START_TIMER;
   for (i = 0; i < MAX_COUNT/100; i++)
@@ -464,7 +521,7 @@
       [des deserializePropertyListFromData: d mutableContainers: NO];
     }
   END_TIMER;
-  PRINT_TIMER("NSString (1/100 ser/des)");
+  PRINT_TIMER("NSString (1/100 ser/des)\t\t");
 
   [NSDeserializer uniquing: YES];
   START_TIMER;
@@ -474,7 +531,7 @@
       [des deserializePropertyListFromData: d mutableContainers: NO];
     }
   END_TIMER;
-  PRINT_TIMER("NSString (1/100 ser/des - uniquing)");
+  PRINT_TIMER("NSString (1/100 ser/des - uniquing)\t");
   [NSDeserializer uniquing: NO];
 
   START_TIMER;
@@ -484,7 +541,7 @@
       [una unarchiveObjectWithData: d];
     }
   END_TIMER;
-  PRINT_TIMER("NSString (1/100 arc/una)");
+  PRINT_TIMER("NSString (1/100 arc/una)\t\t");
 
   AUTO_END;
 }
@@ -508,7 +565,7 @@
       [d release];
     }
   END_TIMER;
-  PRINT_TIMER("NSCalendarDate (various)");
+  PRINT_TIMER("NSCalendarDate (various)\t\t");
   AUTO_END;
 }
 
@@ -533,7 +590,7 @@
       [d release];
     }
   END_TIMER;
-  PRINT_TIMER("NSData (various)");
+  PRINT_TIMER("NSData (various)\t\t\t");
   AUTO_END;
 }
 
@@ -553,7 +610,7 @@
   stringClass = [NSString class];
  
   pool = [NSAutoreleasePool new];
-  printf(" Test                \t time (sec) \t index\n");
+  printf(" Test                \t\t\t\t time (sec) \t index\n");
   bench_object();
   bench_str();
   bench_array();

/** externs.m Program to test correct initialization of externs.
   Copyright (C) 2003 Free Software Foundation, Inc.

   Written by:  David Ayers  <address@hidden>

   This file is part of the GNUstep Base Library.

   This library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Library General Public
   License as published by the Free Software Foundation; either
   version 2 of the License, or (at your option) any later version.
   
   This library is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Library General Public License for more details.

   You should have received a copy of the GNU Library General Public
   License along with this library; if not, write to the Free
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
*/

#include <Foundation/Foundation.h>

#include <assert.h>

#define MyAssert1(IDENT) do { \
                           cache[i++] = IDENT; \
                           assert (IDENT != 0); \
                         } while (0)

#define MyAssert2(IDENT) do { \
                           NSCAssert2([IDENT isEqual: \
                                       [NSString stringWithCString: #IDENT]], \
                                      @"Invalid value: %@ for: %s", \
                                      IDENT, #IDENT); \
                           NSCAssert2([cache[i++] isEqual: IDENT], \
                                      @"Initial values differ:%@ %@", \
                                      cache[i-1], IDENT); \
                         } while (0)

#define CACHE_SIZE  256
NSString *cache[CACHE_SIZE];

int
main()
{
  NSAutoreleasePool *pool;
  int i = 0;

  /* Insure extern identifiers are initialized
     before ObjC code is executed.  */
  MyAssert1(NSConnectionDidDieNotification);
  MyAssert1(NSConnectionDidInitializeNotification);
  MyAssert1(NSWillBecomeMultiThreadedNotification);
  MyAssert1(NSThreadDidStartNotification);
  MyAssert1(NSThreadWillExitNotification);
  //  MyAssert1(PortBecameInvalidNotification);
  //  MyAssert1(InPortClientBecameInvalidNotification);
  //  MyAssert1(InPortAcceptedClientNotification);
  MyAssert1(NSPortDidBecomeInvalidNotification);
  MyAssert1(NSConnectionReplyMode);
  MyAssert1(NSBundleDidLoadNotification);
  MyAssert1(NSShowNonLocalizedStrings);
  MyAssert1(NSLoadedClasses);
  //  MyAssert1(StreamException);
  MyAssert1(NSArgumentDomain);
  MyAssert1(NSGlobalDomain);
  MyAssert1(NSRegistrationDomain);
  MyAssert1(NSUserDefaultsDidChangeNotification);
  MyAssert1(NSWeekDayNameArray);
  MyAssert1(NSShortWeekDayNameArray);
  MyAssert1(NSMonthNameArray);
  MyAssert1(NSShortMonthNameArray);
  MyAssert1(NSTimeFormatString);
  MyAssert1(NSDateFormatString);
  MyAssert1(NSShortDateFormatString);
  MyAssert1(NSTimeDateFormatString);
  MyAssert1(NSShortTimeDateFormatString);
  MyAssert1(NSCurrencySymbol);
  MyAssert1(NSDecimalSeparator);
  MyAssert1(NSThousandsSeparator);
  MyAssert1(NSInternationalCurrencyString);
  MyAssert1(NSCurrencyString);
  //  MyAssert1(NSNegativeCurrencyFormatString);
  //  MyAssert1(NSPositiveCurrencyFormatString);
  MyAssert1(NSDecimalDigits);
  MyAssert1(NSAMPMDesignation);
  MyAssert1(NSHourNameDesignations);
  MyAssert1(NSYearMonthWeekDesignations);
  MyAssert1(NSEarlierTimeDesignations);
  MyAssert1(NSLaterTimeDesignations);
  MyAssert1(NSThisDayDesignations);
  MyAssert1(NSNextDayDesignations);
  MyAssert1(NSNextNextDayDesignations);
  MyAssert1(NSPriorDayDesignations);
  MyAssert1(NSDateTimeOrdering);
  MyAssert1(NSLanguageCode);
  MyAssert1(NSLanguageName);
  MyAssert1(NSFormalName);
  MyAssert1(NSLocale);
  MyAssert1(NSConnectionRepliesReceived);
  MyAssert1(NSConnectionRepliesSent);
  MyAssert1(NSConnectionRequestsReceived);
  MyAssert1(NSConnectionRequestsSent);
  MyAssert1(NSConnectionLocalCount);
  MyAssert1(NSConnectionProxyCount);
  MyAssert1(NSClassDescriptionNeededForClassNotification);

  assert(i < CACHE_SIZE);  /* incread the cache size.  */

  [NSAutoreleasePool enableDoubleReleaseCheck:YES];
  pool = [[NSAutoreleasePool alloc] init];

  i = 0;
  MyAssert2(NSConnectionDidDieNotification);
  MyAssert2(NSConnectionDidInitializeNotification);
  MyAssert2(NSWillBecomeMultiThreadedNotification);
  MyAssert2(NSThreadDidStartNotification);
  MyAssert2(NSThreadWillExitNotification);
  //  MyAssert2(PortBecameInvalidNotification);
  //  MyAssert2(InPortClientBecameInvalidNotification);
  //  MyAssert2(InPortAcceptedClientNotification);
  MyAssert2(NSPortDidBecomeInvalidNotification);
  MyAssert2(NSConnectionReplyMode);
  MyAssert2(NSBundleDidLoadNotification);
  MyAssert2(NSShowNonLocalizedStrings);
  MyAssert2(NSLoadedClasses);
  MyAssert2(NSArgumentDomain);
  MyAssert2(NSGlobalDomain);
  MyAssert2(NSRegistrationDomain);
  MyAssert2(NSUserDefaultsDidChangeNotification);
  MyAssert2(NSWeekDayNameArray);
  MyAssert2(NSShortWeekDayNameArray);
  MyAssert2(NSMonthNameArray);
  MyAssert2(NSShortMonthNameArray);
  MyAssert2(NSTimeFormatString);
  MyAssert2(NSDateFormatString);
  MyAssert2(NSShortDateFormatString);
  MyAssert2(NSTimeDateFormatString);
  MyAssert2(NSShortTimeDateFormatString);
  MyAssert2(NSCurrencySymbol);
  MyAssert2(NSDecimalSeparator);
  MyAssert2(NSThousandsSeparator);
  MyAssert2(NSInternationalCurrencyString);
  MyAssert2(NSCurrencyString);
  //  MyAssert2(NSNegativeCurrencyFormatString);
  //  MyAssert2(NSPositiveCurrencyFormatString);
  MyAssert2(NSDecimalDigits);
  MyAssert2(NSAMPMDesignation);
  MyAssert2(NSHourNameDesignations);
  MyAssert2(NSYearMonthWeekDesignations);
  MyAssert2(NSEarlierTimeDesignations);
  MyAssert2(NSLaterTimeDesignations);
  MyAssert2(NSThisDayDesignations);
  MyAssert2(NSNextDayDesignations);
  MyAssert2(NSNextNextDayDesignations);
  MyAssert2(NSPriorDayDesignations);
  MyAssert2(NSDateTimeOrdering);
  MyAssert2(NSLanguageCode);
  MyAssert2(NSLanguageName);
  MyAssert2(NSFormalName);
  MyAssert2(NSLocale);
  MyAssert2(NSConnectionRepliesReceived);
  MyAssert2(NSConnectionRepliesSent);
  MyAssert2(NSConnectionRequestsReceived);
  MyAssert2(NSConnectionRequestsSent);
  MyAssert2(NSConnectionLocalCount);
  MyAssert2(NSConnectionProxyCount);
  MyAssert2(NSClassDescriptionNeededForClassNotification);

  [pool release];

  exit(0);
}


reply via email to

[Prev in Thread] Current Thread [Next in Thread]