From: <bi...@us...> - 2007-11-13 00:23:21
|
Revision: 1227 http://oorexx.svn.sourceforge.net/oorexx/?rev=1227&view=rev Author: bigrixx Date: 2007-11-12 16:23:26 -0800 (Mon, 12 Nov 2007) Log Message: ----------- [ 1816531 ] Improve the hashing algorithm for String Modified Paths: -------------- interpreter-3.x/trunk/kernel/classes/ArrayClass.cpp interpreter-3.x/trunk/kernel/classes/ClassClass.cpp interpreter-3.x/trunk/kernel/classes/ClassClass.hpp interpreter-3.x/trunk/kernel/classes/DirectoryClass.cpp interpreter-3.x/trunk/kernel/classes/DirectoryClass.hpp interpreter-3.x/trunk/kernel/classes/IntegerClass.cpp interpreter-3.x/trunk/kernel/classes/IntegerClass.hpp interpreter-3.x/trunk/kernel/classes/ListClass.cpp interpreter-3.x/trunk/kernel/classes/MutableBufferClass.cpp interpreter-3.x/trunk/kernel/classes/NumberStringClass.cpp interpreter-3.x/trunk/kernel/classes/NumberStringClass.hpp interpreter-3.x/trunk/kernel/classes/ObjectClass.cpp interpreter-3.x/trunk/kernel/classes/ObjectClass.hpp interpreter-3.x/trunk/kernel/classes/QueueClass.cpp interpreter-3.x/trunk/kernel/classes/RelationClass.cpp interpreter-3.x/trunk/kernel/classes/RelationClass.hpp interpreter-3.x/trunk/kernel/classes/StringClass.cpp interpreter-3.x/trunk/kernel/classes/StringClass.hpp interpreter-3.x/trunk/kernel/classes/StringClassBit.cpp interpreter-3.x/trunk/kernel/classes/StringClassConversion.cpp interpreter-3.x/trunk/kernel/classes/StringClassMisc.cpp interpreter-3.x/trunk/kernel/classes/StringClassSub.cpp interpreter-3.x/trunk/kernel/classes/StringClassWord.cpp interpreter-3.x/trunk/kernel/classes/TableClass.cpp interpreter-3.x/trunk/kernel/classes/TableClass.hpp interpreter-3.x/trunk/kernel/expression/BuiltinFunctions.cpp interpreter-3.x/trunk/kernel/instructions/ParseTrigger.hpp interpreter-3.x/trunk/kernel/parser/Clause.cpp interpreter-3.x/trunk/kernel/parser/Scanner.cpp interpreter-3.x/trunk/kernel/parser/SourceFile.cpp interpreter-3.x/trunk/kernel/parser/Token.hpp interpreter-3.x/trunk/kernel/platform/unix/MiscSystem.cpp interpreter-3.x/trunk/kernel/platform/unix/PlatformDefinitions.h interpreter-3.x/trunk/kernel/platform/windows/MiscSystem.cpp interpreter-3.x/trunk/kernel/platform/windows/PlatformDefinitions.h interpreter-3.x/trunk/kernel/runtime/Initialization.cpp interpreter-3.x/trunk/kernel/runtime/PrimitiveClasses.h interpreter-3.x/trunk/kernel/runtime/RexxActivation.cpp interpreter-3.x/trunk/kernel/runtime/RexxActivation.hpp interpreter-3.x/trunk/kernel/runtime/RexxActivationStack.cpp interpreter-3.x/trunk/kernel/runtime/RexxActivationStack.hpp interpreter-3.x/trunk/kernel/runtime/RexxActivity.cpp interpreter-3.x/trunk/kernel/runtime/RexxActivity.hpp interpreter-3.x/trunk/kernel/runtime/RexxBehaviour.cpp interpreter-3.x/trunk/kernel/runtime/RexxBehaviour.hpp interpreter-3.x/trunk/kernel/runtime/RexxCollection.cpp interpreter-3.x/trunk/kernel/runtime/RexxCollection.hpp interpreter-3.x/trunk/kernel/runtime/RexxCompoundElement.cpp interpreter-3.x/trunk/kernel/runtime/RexxCompoundElement.hpp interpreter-3.x/trunk/kernel/runtime/RexxCompoundTail.cpp interpreter-3.x/trunk/kernel/runtime/RexxCore.h interpreter-3.x/trunk/kernel/runtime/RexxHashTable.cpp interpreter-3.x/trunk/kernel/runtime/RexxHashTable.hpp interpreter-3.x/trunk/kernel/runtime/RexxInternalStack.cpp interpreter-3.x/trunk/kernel/runtime/RexxInternalStack.hpp interpreter-3.x/trunk/kernel/runtime/RexxMemory.cpp interpreter-3.x/trunk/kernel/runtime/RexxMemory.hpp interpreter-3.x/trunk/kernel/runtime/RexxNativeActivation.cpp interpreter-3.x/trunk/kernel/runtime/RexxNativeMethod.cpp interpreter-3.x/trunk/kernel/runtime/RexxNativeMethod.hpp interpreter-3.x/trunk/kernel/runtime/RexxVariable.cpp interpreter-3.x/trunk/kernel/runtime/RexxVariable.hpp interpreter-3.x/trunk/kernel/runtime/RexxVariableDictionary.cpp interpreter-3.x/trunk/kernel/runtime/RexxVariableDictionary.hpp interpreter-3.x/trunk/kernel/runtime/Setup.cpp interpreter-3.x/trunk/lib/RexxPlatformInterface.h interpreter-3.x/trunk/rexxapi/windows/RexxAPIService.c Modified: interpreter-3.x/trunk/kernel/classes/ArrayClass.cpp =================================================================== --- interpreter-3.x/trunk/kernel/classes/ArrayClass.cpp 2007-11-12 23:59:16 UTC (rev 1226) +++ interpreter-3.x/trunk/kernel/classes/ArrayClass.cpp 2007-11-13 00:23:26 UTC (rev 1227) @@ -770,17 +770,17 @@ if (_start > this->size()) /* too big? */ /* return a zero element one */ - newArray = (RexxArray *)this->behaviour->getCreateClass()->sendMessage(OREF_NEW, IntegerZero); + newArray = (RexxArray *)this->behaviour->getOwningClass()->sendMessage(OREF_NEW, IntegerZero); else { if (_end > this->size() - _start + 1) /* go past the bounds? */ _end = this->size() - _start + 1;/* truncate to the end */ if (_end == 0) /* requesting zero? */ /* return a zero element one */ - newArray = (RexxArray *)this->behaviour->getCreateClass()->sendMessage(OREF_NEW, IntegerZero); + newArray = (RexxArray *)this->behaviour->getOwningClass()->sendMessage(OREF_NEW, IntegerZero); else { /* real sectioning to do */ /* create a new array */ - newArray = (RexxArray *)this->behaviour->getCreateClass()->sendMessage(OREF_NEW, new_integer(_end)); + newArray = (RexxArray *)this->behaviour->getOwningClass()->sendMessage(OREF_NEW, new_integer(_end)); save(newArray); /* protect the new one */ for (i = 1; i <= _end; i++) { /* loop through the elements */ /* copy an element */ @@ -1803,7 +1803,7 @@ /* create an empty array. */ temp = new ((size_t)0, arrayClass) RexxArray; save(temp); /* protect new object from GC */ - send_message0(temp, OREF_INIT); /* call any rexx init's */ + temp->sendMessage(OREF_INIT); /* call any rexx init's */ discard(temp); /* protect new object from GC */ return temp; } @@ -1831,7 +1831,7 @@ /* can't change Dimensions. */ OrefSet(temp, temp->dimensions, new_array(IntegerZero)); } - send_message0(temp, OREF_INIT); /* call any rexx init's */ + temp->sendMessage(OREF_INIT); /* call any rexx init's */ discard(temp); /* protect new object from GC */ return temp; /* Return the new array. */ } @@ -1864,7 +1864,7 @@ /* put dimension array in new arr */ OrefSet(temp, temp->dimensions, dim_array); save(temp); /* protect new object from GC */ - send_message0(temp, OREF_INIT); /* call any rexx init's */ + temp->sendMessage(OREF_INIT); /* call any rexx init's */ discard(temp); return temp; } @@ -2440,15 +2440,17 @@ if (TheArrayClass != (RexxClass *)this) { /* nope, better create properly */ /* send new to actual class. */ - newArray = (RexxArray *)send_message1(this, OREF_NEW, new_integer(argCount)); + newArray = (RexxArray *)this->sendMessage(OREF_NEW, new_integer(argCount)); + save(newArray); /* For each argument to of, send a */ /* put message */ for (i = 0; i < argCount; i++) { item = args[i]; /* get the item */ if (item != OREF_NULL) /* have a real item here? */ /* place it in the target array */ - send_message2(newArray, OREF_PUT, item, new_integer(i+1)); + newArray->sendMessage(OREF_PUT, item, new_integer(i+1)); } + discard_hold(newArray); return newArray; } else { Modified: interpreter-3.x/trunk/kernel/classes/ClassClass.cpp =================================================================== --- interpreter-3.x/trunk/kernel/classes/ClassClass.cpp 2007-11-12 23:59:16 UTC (rev 1226) +++ interpreter-3.x/trunk/kernel/classes/ClassClass.cpp 2007-11-13 00:23:26 UTC (rev 1227) @@ -136,13 +136,29 @@ * * @return A "hashed hash" that can be used by the map collections. */ -ULONG RexxClass::hash() +HashCode RexxClass::hash() { - // always, always, always return the hash value - return HASHVALUE(this); + // always, always, always return the hash value, which will be the + // hash value of our id string. This is important, since we need to + // have a hash value that will be the same before and after the image save + return getHashValue(); } +/** + * Get the primitive hash value of this String object. + * + * @return The calculated string hash for the string. + */ +HashCode RexxClass::getHashValue() +{ + // always, always, always return the hash value, which will be the + // hash value of our id string. This is important, since we need to + // have a hash value that will be the same before and after the image save + return id->getHashValue(); +} + + RexxObject *RexxClass::strictEqual( RexxObject *other) /* other comparison object */ /******************************************************************************/ @@ -377,7 +393,7 @@ * creation, so we delay setting this attribute until the * class is fully constructed. */ -void RexxClass::subClassable(const char *class_id, bool restricted) +void RexxClass::subClassable(bool restricted) { /* get a copy of the class instance */ /* behaviour mdict before the merge */ @@ -471,13 +487,11 @@ if (this != TheIntegerClass && this != TheNumberStringClass) TheObjectClass->addSubClass(this); } - /* initialize the class id */ - OrefSet(this, this->id, new_string(class_id)); /* and point the instance behaviour */ /* back to this class */ - this->instanceBehaviour->setClass(this); + this->instanceBehaviour->setOwningClass(this); /* and the class behaviour to CLASS */ - this->behaviour->setClass(TheClassClass); + this->behaviour->setOwningClass(TheClassClass); /* these are primitive classes */ this->classFlags |= PRIMITIVE_CLASS; @@ -636,7 +650,7 @@ if (this->behaviour->checkScope(class_object)) /* let the class specified return */ /* it's own methods */ - return (RexxSupplier *)send_message1(class_object, OREF_METHODS, TheNilObject); + return (RexxSupplier *)class_object->sendMessage(OREF_METHODS, TheNilObject); /* or just return a null supplier */ return (RexxSupplier *)TheNullArray->supplier(); } @@ -1052,7 +1066,7 @@ /* change the create_class in the */ /* instance behaviour to point to the*/ /* original class object */ - enhanced_object->behaviour->setClass(this); + enhanced_object->behaviour->setOwningClass(this); /* remember it was enhanced */ enhanced_object->behaviour->setEnhanced(); discard(dummy_subclass); /* now the dummy is not needed */ @@ -1108,7 +1122,6 @@ /* get a copy of the metaclass class */ new_class = (RexxClass *)meta_class->sendMessage(OREF_NEW, class_id); save(new_class); - new_class->setDefaultHash(); if (this->isMetaClass()) { /* if the superclass is a metaclass */ new_class->setMetaClass(); /* mark the new class as a meta class*/ /* and if the metaclass lists haven't */ @@ -1153,7 +1166,7 @@ new_class->createClassBehaviour(new_class->behaviour); /* set the class behaviour created */ /* class to the meta class */ - new_class->behaviour->setClass(meta_class); + new_class->behaviour->setOwningClass(meta_class); /* create the instance behaviour from */ /* the instance superclass list */ new_class->instanceBehaviour->setMethodDictionary(OREF_NULL); @@ -1161,7 +1174,7 @@ new_class->createInstanceBehaviour(new_class->instanceBehaviour); /* set the instance behaviour created */ /* class to the reciever class */ - new_class->instanceBehaviour->setClass(new_class); + new_class->instanceBehaviour->setOwningClass(new_class); /* update the receiver class' subclass*/ this->addSubClass(new_class); /* list to reflect the new class */ @@ -1262,9 +1275,9 @@ } - void *RexxClass::operator new(size_t size, - long size1, /* additional size */ + size_t size1, /* additional size */ + const char *className, // The id string of the class RexxBehaviour *class_behaviour, /* new class behaviour */ RexxBehaviour *instanceBehaviour) /* instance behaviour info */ /*****************************************************************************/ @@ -1282,14 +1295,16 @@ /* use the specified size */ new_class = (RexxClass *)new_object(size1); new_class->clearObject(); /* clear out the state data */ + // set this value immediately + new_class->id = new_string(className); /* set the class specific behaviour */ new_class->setBehaviour(class_behaviour); /* set the class into the behaviour */ - new_class->behaviour->setClass(new_class); + new_class->behaviour->setOwningClass(new_class); /* set the instance behaviour */ OrefSet(new_class, new_class->instanceBehaviour, instanceBehaviour); /* and the class of this behaviour */ - new_class->instanceBehaviour->setClass(new_class); + new_class->instanceBehaviour->setOwningClass(new_class); /* tell the mobile support to just */ new_class->makeProxiedObject(); /* make a proxy for this class */ return (void *)new_class; /* should be ready */ @@ -1313,8 +1328,12 @@ class_id = REQUIRED_STRING(class_id, ARG_ONE); /* and that it can be a string */ /* get a copy of this class object */ new_class = (RexxClass *)this->clone(); + + // NOTE: we do this before save() is called. The class object hash value + // is based off of the string name, so we need to set this before we + // attempt putting this into a hash collection. + OrefSet(new_class, new_class->id, class_id); /* update cloned hashvalue */ - new_class->setDefaultHash(); save(new_class); /* better protect this */ /* make this into an instance of the */ /* meta class */ @@ -1324,7 +1343,7 @@ OrefSet(new_class, new_class->classMethodDictionary, new_table()); /* make this class the superclass */ OrefSet(new_class, new_class->classSuperClasses, new_array(this)); - new_class->behaviour->setClass(this);/* and set the behaviour class */ + new_class->behaviour->setOwningClass(this);/* and set the behaviour class */ /* if this is a primitive class then */ /* there isn't any metaclass info */ if (this->isPrimitiveClass()) { /* set up yet */ @@ -1362,7 +1381,7 @@ /* with OBJECT in it */ OrefSet(new_class, new_class->instanceSuperClasses, new_array(TheObjectClass)); /* and set the behaviour class */ - new_class->instanceBehaviour->setClass(TheObjectClass); + new_class->instanceBehaviour->setOwningClass(TheObjectClass); /* and the instance behaviour scopes */ new_class->instanceBehaviour->setScopes(new_object_table()); /* set the scoping info */ @@ -1373,11 +1392,9 @@ /* set the new class as it's own */ /* baseclass */ OrefSet(new_class, new_class->baseClass, new_class); - /* set the id into the class object */ - OrefSet(new_class, new_class->id, class_id); /* clear the info area except for */ /* uninit */ - new_class->clearHasUninitDefined(); + new_class->setInitialFlagState(); /* if the class object has an UNINIT method defined, make sure we */ /* add this to the table of classes to be processed. */ if (new_class->hasUninitDefined()) { @@ -1389,7 +1406,7 @@ return new_class; /* return the new class */ } -void class_create (void) +void RexxClass::createClass() /******************************************************************************/ /* Function: Create the initial class object */ /******************************************************************************/ @@ -1400,6 +1417,11 @@ TheClassClass->setBehaviour(TheClassClassBehaviour); /* set the instance behaviour */ TheClassClass->setInstanceBehaviour(TheClassBehaviour); + + // the initial class needs to have an ID before it can be used for + // other purposes. + TheClassClass->id = new_string("Class"); + /* tell the mobile support to just */ /* make a proxy for this class */ TheClassClass->makeProxiedObject(); Modified: interpreter-3.x/trunk/kernel/classes/ClassClass.hpp =================================================================== --- interpreter-3.x/trunk/kernel/classes/ClassClass.hpp 2007-11-12 23:59:16 UTC (rev 1226) +++ interpreter-3.x/trunk/kernel/classes/ClassClass.hpp 2007-11-13 00:23:26 UTC (rev 1227) @@ -36,7 +36,7 @@ /* */ /*----------------------------------------------------------------------------*/ /******************************************************************************/ -/* REXX Kernel ClassClass.hpp */ +/* REXX Kernel ClassClass.hpp */ /* */ /* Primitive Class Class Definitions */ /* */ @@ -45,13 +45,11 @@ #define Included_RexxClass -void class_create (void); - class RexxClass : public RexxObject { public: inline RexxClass(){;}; inline RexxClass(RESTORETYPE restoreType) { ; }; - void *operator new(size_t, long, RexxBehaviour *, RexxBehaviour *); + void *operator new(size_t, size_t, const char *, RexxBehaviour *, RexxBehaviour *); inline void *operator new(size_t size, void *ptr) {return ptr;}; void live(); void liveGeneral(); @@ -60,7 +58,8 @@ RexxObject *makeProxy(RexxEnvelope*); BOOL isEqual(RexxObject *); - ULONG hash(); + HashCode hash(); + HashCode getHashValue(); RexxObject * equal(RexxObject *); RexxObject * strictEqual(RexxObject *); RexxObject * notEqual(RexxObject *); @@ -78,7 +77,7 @@ RexxTable *getInstanceBehaviourDictionary(); RexxTable *getBehaviourDictionary(); RexxString *defaultName(); - void subClassable(const char *, bool); + void subClassable(bool); RexxObject *defineMethod(RexxString *, RexxMethod *); RexxObject *defineMethods(RexxTable *); RexxObject *deleteMethod(RexxString *); @@ -108,6 +107,8 @@ inline bool hasUninitDefined() { return (classFlags & HAS_UNINIT) != 0; }; inline void setHasUninitDefined() { classFlags |= HAS_UNINIT; }; inline void clearHasUninitDefined() { classFlags &= ~HAS_UNINIT; }; + // NB: This clears every flag BUT the UNINIT flag + inline void setInitialFlagState() { classFlags &= HAS_UNINIT; }; inline bool parentHasUninitDefined() { return (classFlags & PARENT_HAS_UNINIT) != 0; }; inline void setParentHasUninitDefined() { classFlags |= PARENT_HAS_UNINIT; }; inline bool isPrimitiveClass() { return (classFlags & PRIMITIVE_CLASS) != 0; } @@ -117,6 +118,9 @@ inline void setMetaClass() { classFlags |= META_CLASS; } void addSubClass(RexxClass *); + + static void createClass(); + protected: enum { Modified: interpreter-3.x/trunk/kernel/classes/DirectoryClass.cpp =================================================================== --- interpreter-3.x/trunk/kernel/classes/DirectoryClass.cpp 2007-11-12 23:59:16 UTC (rev 1226) +++ interpreter-3.x/trunk/kernel/classes/DirectoryClass.cpp 2007-11-13 00:23:26 UTC (rev 1227) @@ -749,19 +749,12 @@ return newDirectory; /* return the new directory */ } -RexxDirectory *RexxMemory::newDirectory() +RexxDirectory *RexxDirectory::newInstance() /******************************************************************************/ /* Create a new directory item */ /******************************************************************************/ { - RexxDirectory *newObj; /* new directory object */ - /* get a new object and hash */ - newObj = (RexxDirectory *)new_hashCollection(DEFAULT_HASH_SIZE, sizeof(RexxDirectory)); - /* Give new object its behaviour */ - newObj->setBehaviour(TheDirectoryBehaviour); - /* set the virtual function table */ - newObj->setVirtualFunctions(VFTArray[T_directory]); - return newObj; /* return the new directory */ + return (RexxDirectory *)new_hashCollection(RexxHashTable::DEFAULT_HASH_SIZE, sizeof(RexxDirectory), T_directory); } Modified: interpreter-3.x/trunk/kernel/classes/DirectoryClass.hpp =================================================================== --- interpreter-3.x/trunk/kernel/classes/DirectoryClass.hpp 2007-11-12 23:59:16 UTC (rev 1226) +++ interpreter-3.x/trunk/kernel/classes/DirectoryClass.hpp 2007-11-13 00:23:26 UTC (rev 1227) @@ -88,5 +88,11 @@ RexxTable *method_table; /* table of added methods */ RexxMethod *unknown_method; /* unknown method entry */ + + static RexxDirectory *newInstance(); }; + + +inline RexxDirectory *new_directory() { return RexxDirectory::newInstance(); } + #endif Modified: interpreter-3.x/trunk/kernel/classes/IntegerClass.cpp =================================================================== --- interpreter-3.x/trunk/kernel/classes/IntegerClass.cpp 2007-11-12 23:59:16 UTC (rev 1226) +++ interpreter-3.x/trunk/kernel/classes/IntegerClass.cpp 2007-11-13 00:23:26 UTC (rev 1227) @@ -65,26 +65,18 @@ return (RexxObject *)this->string()->method(operand);\ } -ULONG RexxInteger::hash() -/******************************************************************************/ -/* Function: retrieve the hash value of an integer object */ -/******************************************************************************/ -{ - RexxString * string; /* integer string value */ - if (!isOfClass(Integer, this)) /* a nonprimitive object? */ - /* see if == overridden. */ - return this->sendMessage(OREF_STRICT_EQUAL)->requestString()->hash(); - else { - if (this->hashvalue == 0) { /* no hash generated yet? */ - string = this->stringValue(); /* generate the string value */ - /* get the string's hash value */ - this->hashvalue = string->getHashValue(); - } - return HASHVALUE(this); /* return the string hash */ - } +/** + * Get the primitive hash value of this String object. + * + * @return The calculated string hash for the string. + */ +HashCode RexxInteger::getHashValue() +{ + return stringValue()->getHashValue(); } + void RexxInteger::live() /******************************************************************************/ /* Function: Normal garbage collection live marking */ @@ -1045,7 +1037,7 @@ return newObject; /* return the new object. */ } -void integer_create (void) +void RexxInteger::createClass() /******************************************************************************/ /* Function: Create the integer class and set up the integer cache */ /******************************************************************************/ @@ -1055,7 +1047,7 @@ /* and needs to override the NEW */ /* method to provide caching */ /* support for integers. */ - create_udsubClass(Integer, RexxIntegerClass); + SUBCLASS_CREATE(Integer, "String", RexxIntegerClass); /* initialize our static array of */ /* cached integers */ new (TheIntegerClass) RexxIntegerClass(); Modified: interpreter-3.x/trunk/kernel/classes/IntegerClass.hpp =================================================================== --- interpreter-3.x/trunk/kernel/classes/IntegerClass.hpp 2007-11-12 23:59:16 UTC (rev 1226) +++ interpreter-3.x/trunk/kernel/classes/IntegerClass.hpp 2007-11-13 00:23:26 UTC (rev 1227) @@ -6,7 +6,7 @@ /* This program and the accompanying materials are made available under */ /* the terms of the Common Public License v1.0 which accompanies this */ /* distribution. A copy is also available at the following address: */ -/* http://www.oorexx.org/license.html */ +/* http://www.oorexx.org/license.html */ /* */ /* Redistribution and use in source and binary forms, with or */ /* without modification, are permitted provided that the following */ @@ -36,7 +36,7 @@ /* */ /*----------------------------------------------------------------------------*/ /******************************************************************************/ -/* REXX Kernel IntegerClass.hpp */ +/* REXX Kernel IntegerClass.hpp */ /* */ /* Primitive Integer Class Definitions */ /* */ @@ -52,13 +52,13 @@ class RexxInteger : public RexxObject { public: inline RexxInteger(RESTORETYPE restoreType) { ; }; - inline RexxInteger(long intValue) { this->value = intValue; this->hashvalue = 0; }; + inline RexxInteger(long intValue) { this->value = intValue; }; inline void *operator new(size_t size, void *ptr) {return ptr;}; void *operator new(size_t); void live(); void liveGeneral(); void flatten(RexxEnvelope*); - ULONG hash(); + virtual HashCode getHashValue(); long longValue(size_t); RexxNumberString *numberString(); @@ -142,12 +142,14 @@ inline int decrementValue() {return --this->value;} inline RexxString *getStringrep() {return this->stringrep;} + static void createClass(); + protected: - RexxString *stringrep; /* integer string representation */ - int value; /* actual integer value */ + RexxString *stringrep; /* integer string representation */ + int value; /* actual integer value */ - static int validMaxWhole[]; // table of maximum values per digits setting + static int validMaxWhole[]; // table of maximum values per digits setting }; class RexxIntegerClass : public RexxClass { @@ -155,7 +157,7 @@ RexxIntegerClass(RESTORETYPE restoreType) { ; }; void *operator new(size_t size, void *ptr) {return ptr;}; void *operator new (size_t); - void *operator new(size_t size, long size1, RexxBehaviour *classBehave, RexxBehaviour *instance) { return new (size, classBehave, instance) RexxClass; } + void *operator new(size_t size, size_t size1, const char *className, RexxBehaviour *classBehave, RexxBehaviour *instance) { return new (size, className, classBehave, instance) RexxClass; } RexxIntegerClass(); RexxInteger *newCache(int value) {if (value >= INTEGERCACHELOW && value < INTEGERCACHESIZE) return this->integercache[value - INTEGERCACHELOW]; Modified: interpreter-3.x/trunk/kernel/classes/ListClass.cpp =================================================================== --- interpreter-3.x/trunk/kernel/classes/ListClass.cpp 2007-11-12 23:59:16 UTC (rev 1226) +++ interpreter-3.x/trunk/kernel/classes/ListClass.cpp 2007-11-13 00:23:26 UTC (rev 1227) @@ -296,7 +296,7 @@ RexxList *newList; /* returned array */ /* create a new list */ - newList = (RexxList *)this->behaviour->getCreateClass()->sendMessage(OREF_NEW); + newList = (RexxList *)this->behaviour->getOwningClass()->sendMessage(OREF_NEW); save(newList); /* protect this */ /* while still more to go and not at */ /* the end of the list */ @@ -695,9 +695,9 @@ /******************************************************************************/ { if (isOfClass(List, this)) /* primitive level object? */ - return this->makeArray(); /* just do the makearray */ - else /* need to so full request mechanism */ - return (RexxArray *)send_message1(this, OREF_REQUEST, OREF_ARRAYSYM); + return this->makeArray(); /* just do the makearray */ + else /* need to so full request mechanism */ + return (RexxArray *)this->sendMessage( OREF_REQUEST, OREF_ARRAYSYM); } @@ -1021,7 +1021,7 @@ else { size = argCount; /* get the array size */ /* get a new list */ - newList = (RexxList *)send_message0(this, OREF_NEW); + newList = (RexxList *)this->sendMessage(OREF_NEW); save(newList); /* protect from garbage collection */ for (i = 0; i < size; i++) { /* step through the array */ item = args[i]; /* get the next item */ @@ -1031,7 +1031,7 @@ reportException(Error_Incorrect_method_noarg, i + 1); } /* add this to the list end */ - send_message1(newList, OREF_INSERT, item); + newList->sendMessage(OREF_INSERT, item); } } discard_hold(newList); /* release the collection lock */ Modified: interpreter-3.x/trunk/kernel/classes/MutableBufferClass.cpp =================================================================== --- interpreter-3.x/trunk/kernel/classes/MutableBufferClass.cpp 2007-11-12 23:59:16 UTC (rev 1226) +++ interpreter-3.x/trunk/kernel/classes/MutableBufferClass.cpp 2007-11-13 00:23:26 UTC (rev 1227) @@ -151,7 +151,6 @@ /* set the string length to the */ /* original length */ newBuffer->data->setLength(string->getLength()); - newBuffer->data->generateHash(); /* recalculate hash value */ save(newBuffer); /* protect new object from GC */ newBuffer->hasUninit(); /* important! we have an UNINT method*/ @@ -219,9 +218,6 @@ newObj->defaultSize = this->defaultSize; newObj->bufferLength = this->bufferLength; - - newObj->hashvalue = (long) newObj; - return newObj; } Modified: interpreter-3.x/trunk/kernel/classes/NumberStringClass.cpp =================================================================== --- interpreter-3.x/trunk/kernel/classes/NumberStringClass.cpp 2007-11-12 23:59:16 UTC (rev 1226) +++ interpreter-3.x/trunk/kernel/classes/NumberStringClass.cpp 2007-11-13 00:23:26 UTC (rev 1227) @@ -162,23 +162,15 @@ return newObj; /* return this */ } -ULONG RexxNumberString::hash() -/******************************************************************************/ -/* Function: retrieve the hash value of an integer object */ -/******************************************************************************/ -{ - RexxString * string; /* integer string value */ - if (!isOfClass(NumberString, this)) /* a nonprimitive object? */ - /* see if == overridden. */ - return this->sendMessage(OREF_STRICT_EQUAL)->requestString()->hash(); - else { - if (this->hashvalue == 0) { /* no hash generated yet? */ - string = this->stringValue(); /* generate the string value */ - this->hashvalue = string->hash();/* get the string's hash value */ - } - return HASHVALUE(this); /* return the string hash */ - } +/** + * Get the primitive hash value of this String object. + * + * @return The calculated string hash for the string. + */ +HashCode RexxNumberString::getHashValue() +{ + return stringValue()->getHashValue(); } void RexxNumberString::live() @@ -311,7 +303,6 @@ num = this->number[numindex] + ch_ZERO; StringObj->putChar(charpos++, num); } /* Done with Fast Path.... */ - StringObj->generateHash(); /* done building the string */ } else { /* We need to do this the long way */ @@ -447,7 +438,6 @@ StringObj->putChar(--charpos, ch_ONE); else /* or 0. if no carry. */ StringObj->putChar(--charpos, ch_ZERO); - StringObj->generateHash(); /* done building the string */ } /* do we need to add zeros at end? */ else if ((size_t)temp >= LenValue) @@ -499,7 +489,6 @@ } } /* end of non-fast path conversion. */ } /* End of conversion of number */ - StringObj->generateHash(); /* force the object to have a hash */ /* since string is created from */ /* number string, we can set the */ StringObj->setNumberString(this); /* lookaside right away */ @@ -1050,8 +1039,6 @@ strcpy(resultPtr, "0."); /* copy the leading part */ /* fill in the trailing zeros */ memset(resultPtr + 2, '0', needed_digits); - /* generate a hash value */ - result->generateHash(); return result; /* return the result */ } } @@ -1157,8 +1144,6 @@ } } } - /* go finish off the string */ - result->generateHash(); } return result; /* return the formatted number */ } @@ -1493,7 +1478,6 @@ resultPtr += mathexp; /* and step past them */ /* add on the spaces */ } - result->generateHash(); /* go generate the hash */ return result; /* return the result */ } @@ -1797,7 +1781,7 @@ /* representation */ /******************************************************************************/ { - return send_message((RexxObject *)this->stringValue(), msgname, arguments); + return this->stringValue()->sendMessage(msgname, arguments); } @@ -2694,10 +2678,7 @@ { RexxNumberString *newNumber; - newNumber = (RexxNumberString *)new_object(size + length); - newNumber->hashvalue = 0; /* Undefine the hash value */ - /* Give new object its behaviour */ - newNumber->setBehaviour(TheNumberStringBehaviour); + newNumber = (RexxNumberString *)new_object(size + length, T_numberstring); /* initialize the new object */ newNumber->setHasNoReferences(); /* Let GC know no to bother with LIVE*/ return newNumber; /* return the new numberstring */ Modified: interpreter-3.x/trunk/kernel/classes/NumberStringClass.hpp =================================================================== --- interpreter-3.x/trunk/kernel/classes/NumberStringClass.hpp 2007-11-12 23:59:16 UTC (rev 1226) +++ interpreter-3.x/trunk/kernel/classes/NumberStringClass.hpp 2007-11-13 00:23:26 UTC (rev 1227) @@ -36,7 +36,7 @@ /* */ /*----------------------------------------------------------------------------*/ /******************************************************************************/ -/* REXX Kernel NumberStringClass.hpp */ +/* REXX Kernel NumberStringClass.hpp */ /* */ /* Primitive NumberString Class Definitions */ /* */ @@ -105,7 +105,7 @@ inline void *operator new(size_t size, void *ptr) {return ptr;}; RexxNumberString(size_t) ; inline RexxNumberString(RESTORETYPE restoreType) { ; }; - ULONG hash(); + virtual HashCode getHashValue(); void live(); void liveGeneral(); void flatten(RexxEnvelope *); Modified: interpreter-3.x/trunk/kernel/classes/ObjectClass.cpp =================================================================== --- interpreter-3.x/trunk/kernel/classes/ObjectClass.cpp 2007-11-12 23:59:16 UTC (rev 1226) +++ interpreter-3.x/trunk/kernel/classes/ObjectClass.cpp 2007-11-13 00:23:26 UTC (rev 1227) @@ -353,9 +353,9 @@ RexxObject *RexxObject::hashCode() { // get the hash value directly, then turn it into a binary string value - unsigned long h = HASHVALUE(this); + HashCode h = getHashValue(); /* create a string value */ - return (RexxObject *)new_string((char *)&h, sizeof(long)); + return (RexxObject *)new_string((char *)&h, sizeof(HashCode)); } @@ -366,43 +366,19 @@ * * @return A "hashed hash" that can be used by the map collections. */ -ULONG RexxObject::hash() +HashCode RexxObject::hash() { - // if this is a primitive object, we can just return the stored hash code. + // if this is a primitive object, we can just return the primitive hash code. if (this->isBaseClass()) { - return HASHVALUE(this); + return getHashValue(); } else { - ULONG h; - // we have some other type of object, so we need to request a hash code // by sending the HASHCODE() message. - RexxString *hashString = this->sendMessage(OREF_HASHCODE)->stringValue(); - - // ok, we need to pick this string apart and turn this into a numeric code - // a null string is simple. - if (hashString->getLength() == 0) - { - h = 1; - } - - // if we have at least 4 characters, use them as binary, since that's - // what is normally returned here. - else if (hashString->getLength() >= sizeof(LONG)) - { - h = *((PULONG)hashString->getStringData()); - } - - else - { - // either 1 or 2 characters. Just pick up a short value, which will - // also pick up terminating null if only a single character - h = *((short *)hashString->getStringData()); - } - return h; - } + return this->sendMessage(OREF_HASHCODE)->stringValue()->getObjectHashCode(); + } } @@ -1367,7 +1343,7 @@ /* use the class id as the default */ /* name */ - defaultname = this->behaviour->getCreateClass()->getId(); + defaultname = this->behaviour->getOwningClass()->getId(); /* check if it is from an enhanced */ if (this->behaviour->isEnhanced()) { /* class */ /* return the 'enhanced' id */ @@ -1411,7 +1387,7 @@ /******************************************************************************/ { /* just return class from behaviour */ - return this->behaviour->getCreateClass(); + return this->behaviour->getOwningClass(); } RexxObject *RexxObject::setMethod( @@ -1749,7 +1725,7 @@ /* got an option? */ if (option) { if (!stricmp("OBJECT",option->getStringData())) - targetClass = this->behaviour->getCreateClass(); + targetClass = this->behaviour->getOwningClass(); else reportException(Error_Incorrect_call_list, CHAR_SETMETHOD, IntegerThree, "\"FLOAT\", \"OBJECT\"", option); } @@ -1909,7 +1885,7 @@ RexxClass *createClass; /* class associated with the object */ /* get the class */ - createClass = this->behaviourObject()->getCreateClass(); + createClass = this->behaviourObject()->getOwningClass(); if (createClass == OREF_NULL) /* no class object? */ return OREF_NULL; /* return nothing */ else @@ -2194,6 +2170,40 @@ printf("Object at %p, of type %d\n", this, this->getObjectTypeNumber()); } +/** + * Create the NIL object instance. + */ +RexxNilObject::RexxNilObject() +{ + // use the initial identify hash and save this. + hashValue = identityHash(); +} + +/** + * Override of the default hash value method. + */ +HashCode RexxNilObject::getHashValue() +{ + return hashValue; +} + + +/** + * new operator for creating a RexxNilObject + */ +void *RexxNilObject::operator new(size_t size) +{ + // At this point, this will be an instance of object. After we've removed + // some of the methods during setup but before the image save, we'll update the + // behaviour type information so that it will restore with the correct virtual + // function table pointer. + RexxObject *newObj = new_object(size, T_object); + // we need to switch the virtual method table pointer new. + newObj->setVirtualFunctions(VFTArray[T_nil_object]); + return newObj; +} + + #include "RexxNativeAPI.h" native0 (REXXOBJECT, OBJECT_NEW) Modified: interpreter-3.x/trunk/kernel/classes/ObjectClass.hpp =================================================================== --- interpreter-3.x/trunk/kernel/classes/ObjectClass.hpp 2007-11-12 23:59:16 UTC (rev 1226) +++ interpreter-3.x/trunk/kernel/classes/ObjectClass.hpp 2007-11-13 00:23:26 UTC (rev 1227) @@ -36,7 +36,7 @@ /* */ /*----------------------------------------------------------------------------*/ /******************************************************************************/ -/* REXX Kernel ObjectClass.hpp */ +/* REXX Kernel ObjectClass.hpp */ /* */ /* Primitive Object Class Definitions */ /* */ @@ -47,9 +47,6 @@ #include <stddef.h> -/* default size of the scope table...these are normally very small */ -#define DEFAULT_SCOPE_SIZE 6 - #define getAttributeIndex 0 /* location of getAttribute method */ #define setAttributeIndex 1 /* location of setAttribute method */ #define abstractIndex 2 /* location of the abstractMethod */ @@ -68,6 +65,7 @@ OldSpaceBit = 0x0010, // location of the OldSpace bit }; +typedef size_t HashCode; // a hash code value /* used ofor special constructor */ typedef enum {RESTOREIMAGE, MOBILEUNFLATTEN, METHODUNFLATTEN} RESTORETYPE; @@ -190,7 +188,6 @@ inline void clearObject() { memset(getObjectDataSpace(), '\0', getObjectDataSize()); } inline void clearObject(size_t l) { memset(getObjectDataSpace(), '\0', l - getObjectHeaderSize()); } inline void setVirtualFunctions(void *t) { *((void **)this) = t; } - inline void setDefaultHash() { hashvalue = identityHash(); } inline void setInitHeader(size_t s, uint16_t markword) { header.initHeader(s, markword); } inline void setInitHeader(uint16_t markword) { header.initHeader(markword); } @@ -237,10 +234,10 @@ virtual RexxObject *getValue(RexxActivation *) { return OREF_NULL; } virtual RexxObject *getValue(RexxVariableDictionary *) { return OREF_NULL; } virtual void uninit() {;} - virtual ULONG hash() { return HASHVALUE(this); } - ULONG getHashValue() { return HASHVALUE(this); } + virtual HashCode hash() { return getHashValue(); } + virtual HashCode getHashValue() { return identityHash(); } - inline ULONG identityHash() { return HASHOREF(this); } + inline HashCode identityHash() { return HASHOREF(this); } virtual BOOL truthValue(LONG); virtual RexxString *makeString(); @@ -265,14 +262,8 @@ void printObject(); RexxObject *clone(); - ObjectHeader header; /* memory management header */ RexxBehaviour *behaviour; /* the object's behaviour */ - /* Following defined as union to */ - /* Allow for overloading of */ - /* hashValue usage/value by */ - /* other classes. */ - size_t hashvalue; /* Default usage. */ }; @@ -314,8 +305,6 @@ header.initHeader(size, mark); // make sure the object variables are cleared in case this has to get marked objectVariables = OREF_NULL; - // set the default hash in case there's nothing special being used - setDefaultHash(); } inline void initializeNewObject(uint32_t mark, void *vft, RexxBehaviour *b) @@ -329,8 +318,6 @@ header.initHeader(mark); // make sure the object variables are cleared in case this has to get marked objectVariables = OREF_NULL; - // set the default hash in case there's nothing special being used - setDefaultHash(); } @@ -349,7 +336,7 @@ void liveGeneral(); void flatten(RexxEnvelope *); RexxObject *copy(); - ULONG hash(); + HashCode hash(); BOOL truthValue(LONG); long longValue(size_t); long longValueNoNOSTRING(size_t); @@ -512,13 +499,22 @@ typedef int (RexxObject::*DispatchMethod)(RexxActivity *, void *); + class RexxNilObject : public RexxObject { - public: - RexxNilObject(); - inline RexxNilObject(RESTORETYPE restoreType) { ; }; +public: + void * operator new(size_t); + void * operator new(size_t size, void *objectPtr) { return objectPtr; }; + inline void operator delete(void *) { ; } + RexxNilObject(); + inline RexxNilObject(RESTORETYPE restoreType) { ; }; + virtual ~RexxNilObject() {;}; - RexxString * nilString(); + virtual HashCode getHashValue(); +protected: + // we want .NIL to have a static hash value after the image restore, so + // this needs to be included in the object state + HashCode hashValue; }; Modified: interpreter-3.x/trunk/kernel/classes/QueueClass.cpp =================================================================== --- interpreter-3.x/trunk/kernel/classes/QueueClass.cpp 2007-11-12 23:59:16 UTC (rev 1226) +++ interpreter-3.x/trunk/kernel/classes/QueueClass.cpp 2007-11-13 00:23:26 UTC (rev 1227) @@ -511,7 +511,7 @@ else { arraysize = argCount; /* get the array size */ /* get a new list */ - newQueue = (RexxQueue *)send_message0(this, OREF_NEW); + newQueue = (RexxQueue *)this->sendMessage(OREF_NEW); save(newQueue); /* protect from garbage collection */ for (i = 0; i < arraysize; i++) { /* step through the array */ item = args[i]; /* get the next item */ @@ -521,7 +521,7 @@ reportException(Error_Incorrect_method_noarg, i + 1); } /* add this to the list end */ - send_message1(newQueue, OREF_QUEUENAME, item); + newQueue->sendMessage(OREF_QUEUENAME, item); } } discard_hold(newQueue); /* release the collection lock */ Modified: interpreter-3.x/trunk/kernel/classes/RelationClass.cpp =================================================================== --- interpreter-3.x/trunk/kernel/classes/RelationClass.cpp 2007-11-12 23:59:16 UTC (rev 1226) +++ interpreter-3.x/trunk/kernel/classes/RelationClass.cpp 2007-11-13 00:23:26 UTC (rev 1227) @@ -213,20 +213,13 @@ return newObj; /* return the new object */ } -RexxRelation *RexxMemory::newRelation() +RexxRelation *RexxRelation::newInstance() /******************************************************************************/ /* Function: Create a new relation item */ /******************************************************************************/ { - RexxRelation *newObj; - /* Get new object */ /* get a new object and hash */ - newObj = (RexxRelation *)new_hashCollection(DEFAULT_HASH_SIZE, sizeof(RexxRelation)); - /* Give new object its behaviour */ - newObj->setBehaviour(TheRelationBehaviour); - /* set the virtual function table */ - newObj->setVirtualFunctions(VFTArray[T_relation]); - return newObj; /* return the new object */ + return (RexxRelation *)new_hashCollection(RexxHashTable::DEFAULT_HASH_SIZE, sizeof(RexxRelation), T_relation); } Modified: interpreter-3.x/trunk/kernel/classes/RelationClass.hpp =================================================================== --- interpreter-3.x/trunk/kernel/classes/RelationClass.hpp 2007-11-12 23:59:16 UTC (rev 1226) +++ interpreter-3.x/trunk/kernel/classes/RelationClass.hpp 2007-11-13 00:23:26 UTC (rev 1227) @@ -64,5 +64,9 @@ RexxObject *newRexx(RexxObject **, size_t); + static RexxRelation *newInstance(); }; + +inline RexxRelation *new_relation() { return RexxRelation::newInstance(); } + #endif Modified: interpreter-3.x/trunk/kernel/classes/StringClass.cpp =================================================================== --- interpreter-3.x/trunk/kernel/classes/StringClass.cpp 2007-11-12 23:59:16 UTC (rev 1226) +++ interpreter-3.x/trunk/kernel/classes/StringClass.cpp 2007-11-13 00:23:26 UTC (rev 1227) @@ -56,18 +56,68 @@ #include "RexxBuiltinFunctions.h" /* Gneral purpose BIF Header file */ -ULONG RexxString::hash() +HashCode RexxString::hash() /******************************************************************************/ /* Function: retrieve the hash value of a string object */ /******************************************************************************/ { - if (!isOfClass(String, this)) /* a nonprimitive object? */ + if (!isString(this)) /* a nonprimitive object? */ /* see if == overridden. */ - return this->sendMessage(OREF_STRICT_EQUAL)->requestString()->getHashValue(); + return this->sendMessage(OREF_STRICT_EQUAL)->requestString()->getStringHash(); else - return HASHVALUE(this); /* return the string hash */ + { + return this->getHashValue(); /* return the string hash */ + } } + +/** + * Get the primitive hash value of this String object. + * + * @return The calculated string hash for the string. + */ +HashCode RexxString::getHashValue() +{ + // this will calculate the hash if it hasn't been done yet + return getStringHash(); +} + + +/** + * Convert a string returned from an object HashCode() method into + * a binary hashcode suitable for the hash collections. + * + * @return A binary hash code from a string value. + */ +HashCode RexxString::getObjectHashCode() +{ + HashCode h; + + // ok, we need to pick this string apart and turn this into a numeric code + // a null string is simple. + if (getLength() == 0) + { + h = 1; + } + + // if we have at least 4 characters, use them as binary, since that's + // what is normally returned here. + else if (getLength() >= sizeof(HashCode)) + { + h = *((HashCode *)getStringData()); + } + + else + { + // either 1 or 2 characters. Just pick up a short value, which will + // also pick up terminating null if only a single character + h = *((short *)getStringData()); + } + return h; +} + + + void RexxString::live() /******************************************************************************/ /* Function: Normal garbage collection live marking */ @@ -315,9 +365,6 @@ other = REQUEST_STRING(otherObj); /* force into string form */ otherLen = other->getLength(); /* get length of second string. */ - /* do quick compare on the hash */ - if (this->hashvalue != other->hashvalue) - return FALSE; /* can't be equal */ if (otherLen != this->getLength()) /* lengths different? */ return FALSE; /* also unequal */ /* now compare the actual string */ @@ -342,9 +389,6 @@ other = REQUEST_STRING(otherObj); /* force into string form */ otherLen = other->getLength(); /* get length of second string. */ - /* do quick compare on the hash */ - if (this->hashvalue != other->hashvalue) - return FALSE; /* can't be equal */ if (otherLen != this->getLength()) /* lengths different? */ return FALSE; /* also unequal */ /* now compare the actual string */ @@ -888,7 +932,6 @@ /* copy the front part */ memcpy(data, this->getStringData(), len1); memcpy(data + len1, other->getStringData(), len2); - result->generateHash(); /* done building the string */ return result; /* return the result */ } @@ -929,7 +972,6 @@ if (len2 != 0) /* have a second length */ /* and the second part */ memcpy(data, other->getStringData(), len2); - result->generateHash(); /* done building the string */ return result; /* return the result */ } @@ -950,7 +992,6 @@ memcpy(result->getWritableData(), other, len2); /* and the second part */ memcpy(result->getWritableData() + len2, this->getStringData(), len1); - result->generateHash(); /* done building the string */ return result; } @@ -971,7 +1012,6 @@ memcpy(result->getWritableData(), this->getStringData(), len1); /* copy the ASCII-Z string */ memcpy(result->getWritableData() + len1, other, len2); - result->generateHash(); /* done building the string */ return result; } @@ -1018,7 +1058,6 @@ if (len2 != 0) /* have a second string? */ /* and the second part */ memcpy(data, other->getStringData(), len2); - result->generateHash(); /* rebuild the hash value */ return result; } @@ -1092,7 +1131,6 @@ data++; /* step the position */ ... [truncated message content] |