Reviewed by John.
authordarin <darin@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 9 May 2005 23:57:33 +0000 (23:57 +0000)
committerdarin <darin@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 9 May 2005 23:57:33 +0000 (23:57 +0000)
        - turn on conservative GC unconditionally and start on SPI changes to
          eliminate the now-unneeded smart pointers since we don't ref count any more

        * kjs/value.h: Removed macros to turn conservative GC on and off.
        Removed ref and deref functions.
        (KJS::ValueImp::ValueImp): Removed non-conservative-GC code path.
        (KJS::ValueImp::isUndefined): Added. New SPI to make it easier to deal with ValueImp directly.
        (KJS::ValueImp::isNull): Ditto.
        (KJS::ValueImp::isBoolean): Ditto.
        (KJS::ValueImp::isNumber): Ditto.
        (KJS::ValueImp::isString): Ditto.
        (KJS::ValueImp::isObject): Ditto.
        (KJS::Value::Value): Removed non-conservative-GC code path and made constructor no
        longer explicit so we can quietly create Value wrappers from ValueImp *; inexpensive with
        conservative GC and eases the transition.
        (KJS::Value::operator ValueImp *): Added. Quietly creates ValueImp * from Value.
        (KJS::ValueImp::marked): Removed non-conservative-GC code path.

        * kjs/value.cpp:
        (KJS::ValueImp::mark): Removed non-conservative-GC code path.
        (KJS::ValueImp::isUndefinedOrNull): Added. New SPI to make it easier to deal with ValueImp directly.
        (KJS::ValueImp::isBoolean): Ditto.
        (KJS::ValueImp::isNumber): Ditto.
        (KJS::ValueImp::isString): Ditto.
        (KJS::ValueImp::asString): Ditto.
        (KJS::ValueImp::isObject): Ditto.
        (KJS::undefined): Ditto.
        (KJS::null): Ditto.
        (KJS::boolean): Ditto.
        (KJS::string): Ditto.
        (KJS::zero): Ditto.
        (KJS::one): Ditto.
        (KJS::two): Ditto.
        (KJS::number): Ditto.

        * kjs/object.h: Made constructor no longer explicit so we can quietly create Object
        wrappers from ObjectImp *; inexpensive with conservative GC and eases the transition.
        (KJS::Object::operator ObjectImp *): Added. Quietly creates ObjectImp * from Object.
        (KJS::ValueImp::isObject): Added. Implementation of new object-related ValueImp function.
        (KJS::ValueImp::asObject): Ditto.

        * kjs/object.cpp:
        (KJS::ObjectImp::setInternalValue): Remove non-conservative-GC code path.
        (KJS::ObjectImp::putDirect): Ditto.
        (KJS::error): Added. Function in the new SPI style to create an error object.

        * kjs/internal.h: Added the new number-constructing functions as friends of NumberImp.
        There may be a more elegant way to do this later; what's important now is the new SPI.

        * kjs/collector.h:  Remove non-conservative-GC code path and also take out some
        unneeded APPLE_CHANGES.

        * bindings/runtime_root.cpp:
        (KJS::Bindings::addNativeReference): Remove non-conservative-GC code path.
        (KJS::Bindings::removeNativeReference): Ditto.
        (RootObject::removeAllNativeReferences): Ditto.
        * bindings/runtime_root.h:
        (KJS::Bindings::RootObject::~RootObject): Ditto.
        (KJS::Bindings::RootObject::setRootObjectImp): Ditto.
        * kjs/collector.cpp:
        (KJS::Collector::allocate): Ditto.
        (KJS::Collector::collect): Ditto.
        (KJS::Collector::numGCNotAllowedObjects): Ditto.
        (KJS::Collector::numReferencedObjects): Ditto.
        (KJS::Collector::rootObjectClasses): Ditto.
        * kjs/internal.cpp:
        (NumberImp::create): Ditto.
        (InterpreterImp::globalInit): Ditto.
        (InterpreterImp::globalClear): Ditto.
        * kjs/list.cpp:
        (KJS::List::markProtectedLists): Ditto.
        (KJS::List::clear): Ditto.
        (KJS::List::append): Ditto.
        * kjs/list.h:
        (KJS::List::List): Ditto.
        (KJS::List::deref): Ditto.
        (KJS::List::operator=): Ditto.
        * kjs/protect.h:
        (KJS::gcProtect): Ditto.
        (KJS::gcUnprotect): Ditto.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@9145 268f45cc-cd09-0410-ab3c-d52691b4dbfc

14 files changed:
JavaScriptCore/ChangeLog
JavaScriptCore/bindings/runtime_root.cpp
JavaScriptCore/bindings/runtime_root.h
JavaScriptCore/kjs/collector.cpp
JavaScriptCore/kjs/collector.h
JavaScriptCore/kjs/internal.cpp
JavaScriptCore/kjs/internal.h
JavaScriptCore/kjs/list.cpp
JavaScriptCore/kjs/list.h
JavaScriptCore/kjs/object.cpp
JavaScriptCore/kjs/object.h
JavaScriptCore/kjs/protect.h
JavaScriptCore/kjs/value.cpp
JavaScriptCore/kjs/value.h

index f18cc852e4a8d685dcd7848fa3545b91844f938f..94fb7d9f0fc936826bff496b63acb5f785feb49a 100644 (file)
@@ -1,3 +1,88 @@
+2005-05-09  Darin Adler  <darin@apple.com>
+
+        Reviewed by John.
+
+        - turn on conservative GC unconditionally and start on SPI changes to
+          eliminate the now-unneeded smart pointers since we don't ref count any more
+
+        * kjs/value.h: Removed macros to turn conservative GC on and off.
+        Removed ref and deref functions.
+        (KJS::ValueImp::ValueImp): Removed non-conservative-GC code path.
+        (KJS::ValueImp::isUndefined): Added. New SPI to make it easier to deal with ValueImp directly.
+        (KJS::ValueImp::isNull): Ditto.
+        (KJS::ValueImp::isBoolean): Ditto.
+        (KJS::ValueImp::isNumber): Ditto.
+        (KJS::ValueImp::isString): Ditto.
+        (KJS::ValueImp::isObject): Ditto.
+        (KJS::Value::Value): Removed non-conservative-GC code path and made constructor no
+        longer explicit so we can quietly create Value wrappers from ValueImp *; inexpensive with
+        conservative GC and eases the transition.
+        (KJS::Value::operator ValueImp *): Added. Quietly creates ValueImp * from Value.
+        (KJS::ValueImp::marked): Removed non-conservative-GC code path.
+
+        * kjs/value.cpp:
+        (KJS::ValueImp::mark): Removed non-conservative-GC code path.
+        (KJS::ValueImp::isUndefinedOrNull): Added. New SPI to make it easier to deal with ValueImp directly.
+        (KJS::ValueImp::isBoolean): Ditto.
+        (KJS::ValueImp::isNumber): Ditto.
+        (KJS::ValueImp::isString): Ditto.
+        (KJS::ValueImp::asString): Ditto.
+        (KJS::ValueImp::isObject): Ditto.
+        (KJS::undefined): Ditto.
+        (KJS::null): Ditto.
+        (KJS::boolean): Ditto.
+        (KJS::string): Ditto.
+        (KJS::zero): Ditto.
+        (KJS::one): Ditto.
+        (KJS::two): Ditto.
+        (KJS::number): Ditto.
+
+        * kjs/object.h: Made constructor no longer explicit so we can quietly create Object
+        wrappers from ObjectImp *; inexpensive with conservative GC and eases the transition.
+        (KJS::Object::operator ObjectImp *): Added. Quietly creates ObjectImp * from Object.
+        (KJS::ValueImp::isObject): Added. Implementation of new object-related ValueImp function.
+        (KJS::ValueImp::asObject): Ditto.
+
+        * kjs/object.cpp:
+        (KJS::ObjectImp::setInternalValue): Remove non-conservative-GC code path.
+        (KJS::ObjectImp::putDirect): Ditto.
+        (KJS::error): Added. Function in the new SPI style to create an error object.
+
+        * kjs/internal.h: Added the new number-constructing functions as friends of NumberImp.
+        There may be a more elegant way to do this later; what's important now is the new SPI.
+
+        * kjs/collector.h:  Remove non-conservative-GC code path and also take out some
+        unneeded APPLE_CHANGES.
+
+        * bindings/runtime_root.cpp:
+        (KJS::Bindings::addNativeReference): Remove non-conservative-GC code path.
+        (KJS::Bindings::removeNativeReference): Ditto.
+        (RootObject::removeAllNativeReferences): Ditto.
+        * bindings/runtime_root.h:
+        (KJS::Bindings::RootObject::~RootObject): Ditto.
+        (KJS::Bindings::RootObject::setRootObjectImp): Ditto.
+        * kjs/collector.cpp:
+        (KJS::Collector::allocate): Ditto.
+        (KJS::Collector::collect): Ditto.
+        (KJS::Collector::numGCNotAllowedObjects): Ditto.
+        (KJS::Collector::numReferencedObjects): Ditto.
+        (KJS::Collector::rootObjectClasses): Ditto.
+        * kjs/internal.cpp:
+        (NumberImp::create): Ditto.
+        (InterpreterImp::globalInit): Ditto.
+        (InterpreterImp::globalClear): Ditto.
+        * kjs/list.cpp:
+        (KJS::List::markProtectedLists): Ditto.
+        (KJS::List::clear): Ditto.
+        (KJS::List::append): Ditto.
+        * kjs/list.h:
+        (KJS::List::List): Ditto.
+        (KJS::List::deref): Ditto.
+        (KJS::List::operator=): Ditto.
+        * kjs/protect.h:
+        (KJS::gcProtect): Ditto.
+        (KJS::gcUnprotect): Ditto.
+
 2005-05-09  Chris Blumenberg  <cblu@apple.com>
 
        Workaround gcc 3.3 internal compiler errors.
index c48543918ae86bf18cf17228e12ac1b126dbfc52..19b5db447ffc533f94ba0a623b0c31f1e2b306a7 100644 (file)
@@ -160,12 +160,7 @@ void KJS::Bindings::addNativeReference (const Bindings::RootObject *root, Object
         
         unsigned int numReferences = (unsigned int)CFDictionaryGetValue (referencesDictionary, imp);
         if (numReferences == 0) {
-#if !USE_CONSERVATIVE_GC
-           imp->ref();
-#endif
-#if USE_CONSERVATIVE_GC | TEST_CONSERVATIVE_GC
            gcProtect(imp);
-#endif 
             CFDictionaryAddValue (referencesDictionary, imp,  (const void *)1);
         }
         else {
@@ -184,12 +179,7 @@ void KJS::Bindings::removeNativeReference (ObjectImp *imp)
     if (referencesDictionary) {
         unsigned int numReferences = (unsigned int)CFDictionaryGetValue (referencesDictionary, imp);
         if (numReferences == 1) {
-#if !USE_CONSERVATIVE_GC
-           imp->deref();
-#endif
-#if USE_CONSERVATIVE_GC | TEST_CONSERVATIVE_GC
            gcUnprotect(imp);
-#endif 
             CFDictionaryRemoveValue (referencesDictionary, imp);
         }
         else {
@@ -336,12 +326,7 @@ void RootObject::removeAllNativeReferences ()
         CFDictionaryGetKeysAndValues (referencesDictionary, (const void **)allImps, NULL);
         for(i = 0; i < count; i++) {
             ObjectImp *anImp = static_cast<ObjectImp*>(allImps[i]);
-#if !USE_CONSERVATIVE_GC
-            anImp->deref();
-#endif
-#if USE_CONSERVATIVE_GC | TEST_CONSERVATIVE_GC
            gcUnprotect(anImp);
-#endif
         }
         free ((void *)allImps);
         CFDictionaryRemoveAllValues (referencesDictionary);
index 0f506bb80b940ddaa4e7c79f8508f7df4dc91aac..0f1516baeb0635bdb220afb79ef32cdfb3805bf1 100644 (file)
@@ -48,24 +48,13 @@ class RootObject
 friend class JSObject;
 public:
     RootObject (const void *nativeHandle) : _nativeHandle(nativeHandle), _imp(0), _interpreter(0) {}
-    ~RootObject (){
-#if !USE_CONSERVATIVE_GC
-        _imp->deref();
-#endif
-#if USE_CONSERVATIVE_GC | TEST_CONSERVATIVE_GC
+    ~RootObject () {
        gcUnprotect(_imp);
-#endif
     }
     
     void setRootObjectImp (ObjectImp *i) { 
         _imp = i;
-#if !USE_CONSERVATIVE_GC
-        _imp->ref();
-
-#endif
-#if USE_CONSERVATIVE_GC | TEST_CONSERVATIVE_GC
        gcProtect(_imp);
-#endif
     }
     
     ObjectImp *rootObjectImp() const { return _imp; }
index f37010fe58c1223ac6897773e8478a56b6d4385a..8fa955d6cafe6ea6db37249812fd309803699146 100644 (file)
@@ -111,10 +111,6 @@ void* Collector::allocate(size_t s)
     heap.usedOversizeCells++;
     heap.numLiveObjects = numLiveObjects + 1;
 
-#if !USE_CONSERVATIVE_GC
-    ((ValueImp *)(newCell))->_flags = 0;
-#endif
-
     return newCell;
   }
   
@@ -156,15 +152,9 @@ void* Collector::allocate(size_t s)
   targetBlock->usedCells++;
   heap.numLiveObjects = numLiveObjects + 1;
 
-#if !USE_CONSERVATIVE_GC
-  ((ValueImp *)(newCell))->_flags = 0;
-#endif
-
   return newCell;
 }
 
-#if TEST_CONSERVATIVE_GC || USE_CONSERVATIVE_GC
-
 struct Collector::Thread {
   Thread(pthread_t pthread, mach_port_t mthread) : posixThread(pthread), machThread(mthread) {}
   Thread *next;
@@ -340,20 +330,12 @@ void Collector::markProtectedObjects()
   }
 }
 
-#endif
-
 bool Collector::collect()
 {
   assert(Interpreter::lockCount() > 0);
 
   bool deleted = false;
 
-#if TEST_CONSERVATIVE_GC
-  // CONSERVATIVE MARK: mark the root set using conservative GC bit (will compare later)
-  ValueImp::useConservativeMark(true);
-#endif
-
-#if USE_CONSERVATIVE_GC || TEST_CONSERVATIVE_GC
   if (InterpreterImp::s_hook) {
     InterpreterImp *scr = InterpreterImp::s_hook;
     do {
@@ -363,61 +345,11 @@ bool Collector::collect()
     } while (scr != InterpreterImp::s_hook);
   }
 
+  // MARK: first mark all referenced objects recursively starting out from the set of root objects
+
   markStackObjectsConservatively();
   markProtectedObjects();
   List::markProtectedLists();
-#endif
-
-#if TEST_CONSERVATIVE_GC
-  ValueImp::useConservativeMark(false);
-#endif
-
-#if !USE_CONSERVATIVE_GC
-  // MARK: first mark all referenced objects recursively
-  // starting out from the set of root objects
-  if (InterpreterImp::s_hook) {
-    InterpreterImp *scr = InterpreterImp::s_hook;
-    do {
-      //fprintf( stderr, "Collector marking interpreter %p\n",(void*)scr);
-      scr->mark();
-      scr = scr->next;
-    } while (scr != InterpreterImp::s_hook);
-  }
-  
-  // mark any other objects that we wouldn't delete anyway
-  for (int block = 0; block < heap.usedBlocks; block++) {
-
-    int minimumCellsToProcess = heap.blocks[block]->usedCells;
-    CollectorBlock *curBlock = heap.blocks[block];
-
-    for (int cell = 0; cell < CELLS_PER_BLOCK; cell++) {
-      if (minimumCellsToProcess < cell) {
-       goto skip_block_mark;
-      }
-       
-      ValueImp *imp = (ValueImp *)(curBlock->cells + cell);
-
-      if (((CollectorCell *)imp)->u.freeCell.zeroIfFree != 0) {
-       
-       if ((imp->_flags & (ValueImp::VI_CREATED|ValueImp::VI_MARKED)) == ValueImp::VI_CREATED &&
-           ((imp->_flags & ValueImp::VI_GCALLOWED) == 0 || imp->refcount != 0)) {
-         imp->mark();
-       }
-      } else {
-       minimumCellsToProcess++;
-      }
-    }
-  skip_block_mark: ;
-  }
-  
-  for (int cell = 0; cell < heap.usedOversizeCells; cell++) {
-    ValueImp *imp = (ValueImp *)heap.oversizeCells[cell];
-    if ((imp->_flags & (ValueImp::VI_CREATED|ValueImp::VI_MARKED)) == ValueImp::VI_CREATED &&
-       ((imp->_flags & ValueImp::VI_GCALLOWED) == 0 || imp->refcount != 0)) {
-      imp->mark();
-    }
-  }
-#endif
 
   // SWEEP: delete everything with a zero refcount (garbage) and unmark everything else
   
@@ -438,11 +370,7 @@ bool Collector::collect()
       ValueImp *imp = reinterpret_cast<ValueImp *>(cell);
 
       if (cell->u.freeCell.zeroIfFree != 0) {
-#if USE_CONSERVATIVE_GC
        if (!imp->_marked)
-#else
-       if (!imp->refcount && imp->_flags == (ValueImp::VI_GCALLOWED | ValueImp::VI_CREATED))
-#endif
        {
          //fprintf( stderr, "Collector::deleting ValueImp %p (%s)\n", (void*)imp, typeid(*imp).name());
          // emulate destructing part of 'operator delete()'
@@ -457,13 +385,7 @@ bool Collector::collect()
          curBlock->freeList = cell;
 
        } else {
-#if USE_CONSERVATIVE_GC
-         imp->_marked = 0;
-#elif TEST_CONSERVATIVE_GC
-         imp->_flags &= ~(ValueImp::VI_MARKED | ValueImp::VI_CONSERVATIVE_MARKED);
-#else
-         imp->_flags &= ~ValueImp::VI_MARKED;
-#endif
+         imp->_marked = false;
        }
       } else {
        minimumCellsToProcess++;
@@ -499,13 +421,7 @@ bool Collector::collect()
   while (cell < heap.usedOversizeCells) {
     ValueImp *imp = (ValueImp *)heap.oversizeCells[cell];
     
-#if USE_CONSERVATIVE_GC
     if (!imp->_marked) {
-#else
-    if (!imp->refcount && 
-       imp->_flags == (ValueImp::VI_GCALLOWED | ValueImp::VI_CREATED)) {
-#endif
-
       imp->~ValueImp();
 #if DEBUG_COLLECTOR
       heap.oversizeCells[cell]->u.freeCell.zeroIfFree = 0;
@@ -526,13 +442,7 @@ bool Collector::collect()
       }
 
     } else {
-#if USE_CONSERVATIVE_GC
-      imp->_marked = 0;
-#elif TEST_CONSERVATIVE_GC
-      imp->_flags &= ~(ValueImp::VI_MARKED | ValueImp::VI_CONSERVATIVE_MARKED);
-#else
-      imp->_flags &= ~ValueImp::VI_MARKED;
-#endif
+      imp->_marked = false;
       cell++;
     }
   }
@@ -556,8 +466,6 @@ void Collector::finalCheck()
 }
 #endif
 
-#if APPLE_CHANGES
-
 int Collector::numInterpreters()
 {
   int count = 0;
@@ -573,37 +481,13 @@ int Collector::numInterpreters()
 
 int Collector::numGCNotAllowedObjects()
 {
-  int count = 0;
-#if !USE_CONSERVATIVE_GC
-  for (int block = 0; block < heap.usedBlocks; block++) {
-    CollectorBlock *curBlock = heap.blocks[block];
-
-    for (int cell = 0; cell < CELLS_PER_BLOCK; cell++) {
-      ValueImp *imp = (ValueImp *)(curBlock->cells + cell);
-      
-      if (((CollectorCell *)imp)->u.freeCell.zeroIfFree != 0 &&
-         (imp->_flags & ValueImp::VI_GCALLOWED) == 0) {
-       ++count;
-      }
-    }
-  }
-  
-  for (int cell = 0; cell < heap.usedOversizeCells; cell++) {
-    ValueImp *imp = (ValueImp *)heap.oversizeCells[cell];
-    if ((imp->_flags & ValueImp::VI_GCALLOWED) == 0) {
-      ++count;
-    }
-  }
-#endif
-
-  return count;
+  return 0;
 }
 
 int Collector::numReferencedObjects()
 {
   int count = 0;
 
-#if USE_CONSERVATIVE_GC
   int size = ProtectedValues::_tableSize;
   ProtectedValues::KeyValue *table = ProtectedValues::_table;
   for (int i = 0; i < size; i++) {
@@ -613,37 +497,15 @@ int Collector::numReferencedObjects()
     }
   }
 
-#else
-
-  for (int block = 0; block < heap.usedBlocks; block++) {
-    CollectorBlock *curBlock = heap.blocks[block];
-
-    for (int cell = 0; cell < CELLS_PER_BLOCK; cell++) {
-      ValueImp *imp = (ValueImp *)(curBlock->cells + cell);
-      
-      if (((CollectorCell *)imp)->u.freeCell.zeroIfFree != 0 &&
-         imp->refcount != 0) {
-       ++count;
-      }
-    }
-  }
-  
-  for (int cell = 0; cell < heap.usedOversizeCells; cell++) {
-    ValueImp *imp = (ValueImp *)heap.oversizeCells[cell];
-      if (imp->refcount != 0) {
-        ++count;
-      }
-  }
-#endif
-
   return count;
 }
 
+#if APPLE_CHANGES
+
 const void *Collector::rootObjectClasses()
 {
   CFMutableSetRef classes = CFSetCreateMutable(NULL, 0, &kCFTypeSetCallBacks);
 
-#if USE_CONSERVATIVE_GC
   int size = ProtectedValues::_tableSize;
   ProtectedValues::KeyValue *table = ProtectedValues::_table;
   for (int i = 0; i < size; i++) {
@@ -659,41 +521,6 @@ const void *Collector::rootObjectClasses()
       CFRelease(className);
     }
   }
-#else
-  for (int block = 0; block < heap.usedBlocks; block++) {
-    CollectorBlock *curBlock = heap.blocks[block];
-    for (int cell = 0; cell < CELLS_PER_BLOCK; cell++) {
-      ValueImp *imp = (ValueImp *)(curBlock->cells + cell);
-      
-      if (((CollectorCell *)imp)->u.freeCell.zeroIfFree != 0 &&
-         ((imp->_flags & ValueImp::VI_GCALLOWED) == 0 || imp->refcount != 0)) {
-       const char *mangled_name = typeid(*imp).name();
-       int status;
-       char *demangled_name = __cxxabiv1::__cxa_demangle (mangled_name, NULL, NULL, &status);
-       
-       CFStringRef className = CFStringCreateWithCString(NULL, demangled_name, kCFStringEncodingASCII);
-       free(demangled_name);
-       CFSetAddValue(classes, className);
-       CFRelease(className);
-      }
-    }
-  }
-  
-  for (int cell = 0; cell < heap.usedOversizeCells; cell++) {
-    ValueImp *imp = (ValueImp *)heap.oversizeCells[cell];
-    
-    if ((imp->_flags & ValueImp::VI_GCALLOWED) == 0 || imp->refcount != 0) {
-      const char *mangled_name = typeid(*imp).name();
-      int status;
-      char *demangled_name = __cxxabiv1::__cxa_demangle (mangled_name, NULL, NULL, &status);
-      
-      CFStringRef className = CFStringCreateWithCString(NULL, demangled_name, kCFStringEncodingASCII);
-      free(demangled_name);
-      CFSetAddValue(classes, className);
-      CFRelease(className);
-    }
-  }
-#endif
   
   return classes;
 }
index 2e1d259bee83b00849e15e306299a7243b380b02..895983ffde274866b1775347f444e75af44efe0f 100644 (file)
@@ -63,26 +63,23 @@ namespace KJS {
     static void finalCheck();
 #endif
 
-#if APPLE_CHANGES
     static int numInterpreters();
     static int numGCNotAllowedObjects();
     static int numReferencedObjects();
+#if APPLE_CHANGES
     static const void *rootObjectClasses(); // actually returns CFSetRef
 #endif
-#if TEST_CONSERVATIVE_GC | USE_CONSERVATIVE_GC
-    class Thread;
 
+    class Thread;
     static void registerThread();
-#endif
+
   private:
 
-#if TEST_CONSERVATIVE_GC | USE_CONSERVATIVE_GC
     static void markProtectedObjects();
     static void markCurrentThreadConservatively();
     static void markOtherThreadConservatively(Thread *thread);
     static void markStackObjectsConservatively();
     static void markStackObjectsConservatively(void *start, void *end);
-#endif
 
     static bool memoryFull;
   };
index 12adc7786212d59e54998b9d48d0587932e11bfa..e8007d8665c953fd534b2f82bdfcaca611918ef0 100644 (file)
@@ -236,11 +236,7 @@ ValueImp *NumberImp::create(int i)
 {
     if (SimpleNumber::fits(i))
         return SimpleNumber::make(i);
-    NumberImp *imp = new NumberImp(static_cast<double>(i));
-#if !USE_CONSERVATIVE_GC
-    imp->setGcAllowedFast();
-#endif
-    return imp;
+    return new NumberImp(static_cast<double>(i));
 }
 
 ValueImp *NumberImp::create(double d)
@@ -249,11 +245,7 @@ ValueImp *NumberImp::create(double d)
         return SimpleNumber::make((int)d);
     if (isNaN(d))
         return staticNaN;
-    NumberImp *imp = new NumberImp(d);
-#if !USE_CONSERVATIVE_GC
-    imp->setGcAllowedFast();
-#endif
-    return imp;
+    return new NumberImp(d);
 }
 
 Value NumberImp::toPrimitive(ExecState *, Type) const
@@ -488,54 +480,19 @@ void InterpreterImp::globalInit()
 {
   //fprintf( stderr, "InterpreterImp::globalInit()\n" );
   UndefinedImp::staticUndefined = new UndefinedImp();
-#if !USE_CONSERVATIVE_GC
-  UndefinedImp::staticUndefined->ref();
-#endif
   NullImp::staticNull = new NullImp();
-#if !USE_CONSERVATIVE_GC
-  NullImp::staticNull->ref();
-#endif
   BooleanImp::staticTrue = new BooleanImp(true);
-#if !USE_CONSERVATIVE_GC
-  BooleanImp::staticTrue->ref();
-#endif
   BooleanImp::staticFalse = new BooleanImp(false);
-#if !USE_CONSERVATIVE_GC
-  BooleanImp::staticFalse->ref();
-#endif
   NumberImp::staticNaN = new NumberImp(NaN);
-#if !USE_CONSERVATIVE_GC
-  NumberImp::staticNaN->ref();
-#endif
 }
 
 void InterpreterImp::globalClear()
 {
   //fprintf( stderr, "InterpreterImp::globalClear()\n" );
-#if !USE_CONSERVATIVE_GC
-  UndefinedImp::staticUndefined->deref();
-  UndefinedImp::staticUndefined->setGcAllowed();
-#endif
-  UndefinedImp::staticUndefined = 0L;
-#if !USE_CONSERVATIVE_GC
-  NullImp::staticNull->deref();
-  NullImp::staticNull->setGcAllowed();
-#endif
-  NullImp::staticNull = 0L;
-#if !USE_CONSERVATIVE_GC
-  BooleanImp::staticTrue->deref();
-  BooleanImp::staticTrue->setGcAllowed();
-#endif
-  BooleanImp::staticTrue = 0L;
-#if !USE_CONSERVATIVE_GC
-  BooleanImp::staticFalse->deref();
-  BooleanImp::staticFalse->setGcAllowed();
-#endif
-  BooleanImp::staticFalse = 0L;
-#if !USE_CONSERVATIVE_GC
-  NumberImp::staticNaN->deref();
-  NumberImp::staticNaN->setGcAllowed();
-#endif
+  UndefinedImp::staticUndefined = 0;
+  NullImp::staticNull = 0;
+  BooleanImp::staticTrue = 0;
+  BooleanImp::staticFalse = 0;
   NumberImp::staticNaN = 0;
 }
 
index fff73c818526eb3bb2ee6990dba19456b646a764..c2273f3b31397dc10ebf459ea01b4bb74f08f7fd 100644 (file)
@@ -123,6 +123,12 @@ namespace KJS {
     friend class Value;
     friend class Number;
     friend class InterpreterImp;
+    friend ValueImp *number(int);
+    friend ValueImp *number(unsigned);
+    friend ValueImp *number(long);
+    friend ValueImp *number(unsigned long);
+    friend ValueImp *number(double);
+    friend ValueImp *number(double, bool);
   public:
     static ValueImp *create(int);
     static ValueImp *create(double);
index 3a959e1cf8393818b39a7ff588457a3c83c7e4a2..325def3235d86f79f7e8dd5ff256064dad86eab3 100644 (file)
@@ -111,7 +111,6 @@ inline void ListImp::markValues()
 
 void List::markProtectedLists()
 {
-#if TEST_CONSERVATIVE_GC || USE_CONSERVATIVE_GC
     int seen = 0;
     for (int i = 0; i < poolSize; i++) {
         if (seen >= poolUsed)
@@ -130,7 +129,6 @@ void List::markProtectedLists()
             l->markValues();
         }
     }
-#endif
 }
 
 
@@ -214,43 +212,6 @@ List::List(bool needsMarking) : _impBase(allocateListImp()), _needsMarking(needs
 #endif
 }
 
-void List::derefValues()
-{
-#if !USE_CONSERVATIVE_GC
-    ListImp *imp = static_cast<ListImp *>(_impBase);
-    
-    int size = imp->size;
-    
-    int inlineSize = MIN(size, inlineValuesSize);
-    for (int i = 0; i != inlineSize; ++i)
-        imp->values[i]->deref();
-
-    int overflowSize = size - inlineSize;
-    ValueImp **overflow = imp->overflow;
-
-    for (int i = 0; i != overflowSize; ++i)
-        overflow[i]->deref();
-#endif
-}
-
-void List::refValues()
-{
-#if !USE_CONSERVATIVE_GC
-    ListImp *imp = static_cast<ListImp *>(_impBase);
-    
-    int size = imp->size;
-    
-    int inlineSize = MIN(size, inlineValuesSize);
-    for (int i = 0; i != inlineSize; ++i)
-        imp->values[i]->ref();
-    
-    int overflowSize = size - inlineSize;
-    ValueImp **overflow = imp->overflow;
-    for (int i = 0; i != overflowSize; ++i)
-        overflow[i]->ref();
-#endif
-}
-
 void List::markValues()
 {
     static_cast<ListImp *>(_impBase)->markValues();
@@ -284,9 +245,6 @@ ValueImp *List::impAt(int i) const
 
 void List::clear()
 {
-    if (_impBase->valueRefCount > 0) {
-       derefValues();
-    }
     _impBase->size = 0;
 }
 
@@ -301,12 +259,6 @@ void List::append(ValueImp *v)
         listSizeHighWaterMark = imp->size;
 #endif
 
-    if (imp->valueRefCount > 0) {
-#if !USE_CONSERVATIVE_GC
-       v->ref();
-#endif
-    }
-    
     if (i < inlineValuesSize) {
         imp->values[i] = v;
         return;
index 130d6a7398568e1658271bbf592b6e46da3a119f..d3e2fce24ec4a51ad93fec17fb0a445491332eab 100644 (file)
@@ -30,7 +30,7 @@ namespace KJS {
     struct ListImpBase {
         int size;
         int refCount;
-       int valueRefCount;
+       int valueRefCount; // FIXME: Get rid of this.
     };
     
     class ListIterator;
@@ -53,7 +53,6 @@ namespace KJS {
 
         List(const List &b) : _impBase(b._impBase), _needsMarking(false) {
            ++_impBase->refCount; 
-           if (!_impBase->valueRefCount) refValues(); 
            ++_impBase->valueRefCount; 
        }
         List &operator=(const List &);
@@ -126,11 +125,9 @@ namespace KJS {
         ListImpBase *_impBase;
        bool _needsMarking;
         
-        void deref() { if (!_needsMarking && --_impBase->valueRefCount == 0) derefValues(); if (--_impBase->refCount == 0) release(); }
+        void deref() { if (!_needsMarking) --_impBase->valueRefCount; if (--_impBase->refCount == 0) release(); }
 
         void release();
-        void refValues();
-        void derefValues();
         void markValues();
     };
   
@@ -194,16 +191,9 @@ namespace KJS {
         ++bImpBase->refCount;
         deref();
         _impBase = bImpBase;
-       if (!_needsMarking) {
-           if (!_impBase->valueRefCount) {
-               refValues();
-           }
-           _impBase->valueRefCount++;
-       }
-
         return *this;
     }
 
- }; // namespace KJS
+} // namespace KJS
 
 #endif // KJS_LIST_H
index 94f75af4f6527b3a857c9fe039694a8bece9cb2a..1e389cf73f7616a3d8bf469c3457408165fddcb7 100644 (file)
@@ -479,9 +479,6 @@ void ObjectImp::setInternalValue(const Value &v)
 
 void ObjectImp::setInternalValue(ValueImp *v)
 {
-#if !USE_CONSERVATIVE_GC
-  v->setGcAllowed();
-#endif
   _internalValue = v;
 }
 
@@ -518,9 +515,6 @@ Object ObjectImp::toObject(ExecState */*exec*/) const
 
 void ObjectImp::putDirect(const Identifier &propertyName, ValueImp *value, int attr)
 {
-#if !USE_CONSERVATIVE_GC
-    value->setGcAllowed();
-#endif
     _prop.put(propertyName, value, attr);
 }
 
@@ -600,4 +594,9 @@ Object Error::create(ExecState *exec, ErrorType errtype, const char *message,
 */
 }
 
+ObjectImp *error(ExecState *exec, ErrorType type, const char *message, int line, int sourceId, const UString *sourceURL)
+{
+    return Error::create(exec, type, message, line, sourceId, sourceURL).imp();
+}
+
 } // namespace KJS
index 64a076a0afbb7dba9585fff2aae47549af687778..b649ce2e9053271849901ee71f3e60bf6a219e92 100644 (file)
@@ -89,7 +89,8 @@ namespace KJS {
   class Object : public Value {
   public:
     Object() { }
-    explicit Object(ObjectImp *v);
+    Object(ObjectImp *);
+    operator ObjectImp *() const { return imp(); }
     
     ObjectImp *imp() const;
 
@@ -621,6 +622,9 @@ namespace KJS {
                    TypeError      = 5,
                    URIError       = 6};
 
+  ObjectImp *error(ExecState *exec, ErrorType type = GeneralError,
+    const char *message = 0, int lineno = -1, int sourceId = -1, const UString *sourceURL = 0);
+
   /**
    * @short Factory methods for error objects.
    */
@@ -645,9 +649,16 @@ namespace KJS {
     static const char * const * const errorNames;
   };
 
-  inline Object::Object(ObjectImp *v) : Value(v) { }
+  inline bool ValueImp::isObject(const ClassInfo *info) const
+    { return isObject() && static_cast<const ObjectImp *>(this)->inherits(info); }
+
+  inline ObjectImp *ValueImp::asObject()
+    { return isObject() ? static_cast<ObjectImp *>(this) : 0; }
+
+  inline Object::Object(ObjectImp *o) : Value(o) { }
 
-  inline ObjectImp *Object::imp() const { return static_cast<ObjectImp*>(rep); }
+  inline ObjectImp *Object::imp() const
+    { return static_cast<ObjectImp *>(Value::imp()); }
 
   inline const ClassInfo *Object::classInfo() const
     { return imp()->classInfo(); }
@@ -729,6 +740,6 @@ namespace KJS {
   inline void Object::restoreProperties(const SavedProperties &p)
     { imp()->restoreProperties(p); }
 
-}; // namespace
+} // namespace
 
 #endif // _KJS_OBJECT_H_
index f94cec7b8f8233ca76e0684fa9697d04daff78b9..783bedbdb2f95515a491bab1bbe441b88540b24b 100644 (file)
@@ -33,15 +33,11 @@ namespace KJS {
 
     inline void gcProtect(ValueImp *val) 
       { 
-#if TEST_CONSERVATIVE_GC | USE_CONSERVATIVE_GC
        ProtectedValues::increaseProtectCount(val);
-#endif
       }
     inline void gcUnprotect(ValueImp *val)
       { 
-#if TEST_CONSERVATIVE_GC | USE_CONSERVATIVE_GC
        ProtectedValues::decreaseProtectCount(val);
-#endif
       }
 
     inline void gcProtectNullTolerant(ValueImp *val) 
index f7c1a139b8993aad7113a3ff1e5d5ce80fff97c7..eddf30896deaf83d18512b18dff91704c2009ca9 100644 (file)
 #include "nodes.h"
 #include "simple_number.h"
 
-using namespace KJS;
+namespace KJS {
 
 // ----------------------------- ValueImp -------------------------------------
 
-#if !USE_CONSERVATIVE_GC
-ValueImp::ValueImp() :
-  refcount(0),
-  // Tell the garbage collector that this memory block corresponds to a real object now
-  _flags(VI_CREATED)
-{
-  //fprintf(stderr,"ValueImp::ValueImp %p\n",(void*)this);
-}
-
-ValueImp::~ValueImp()
-{
-  //fprintf(stderr,"ValueImp::~ValueImp %p\n",(void*)this);
-}
-#endif
-
-#if TEST_CONSERVATIVE_GC
-static bool conservativeMark = false;
-
-void ValueImp::useConservativeMark(bool use)
-{
-  conservativeMark = use;
-}
-#endif
-
 void ValueImp::mark()
 {
-  //fprintf(stderr,"ValueImp::mark %p\n",(void*)this);
-#if USE_CONSERVATIVE_GC
   _marked = true;
-#elif TEST_CONSERVATIVE_GC
-  if (conservativeMark) {
-    _flags |= VI_CONSERVATIVE_MARKED;
-  } else {
-    if (!(_flags & VI_CONSERVATIVE_MARKED)) {
-      printf("Conservative collector missed ValueImp 0x%x. refcount %d, protect count %d\n", (int)this, refcount, ProtectedValues::getProtectCount(this));
-    }
-    _flags |= VI_MARKED;
-  }
-#else
-  _flags |= VI_MARKED;
-#endif
-}
-
-#if !USE_CONSERVATIVE_GC
-void ValueImp::setGcAllowed()
-{
-  //fprintf(stderr,"ValueImp::setGcAllowed %p\n",(void*)this);
-  // simple numbers are never seen by the collector so setting this
-  // flag is irrelevant
-  if (!SimpleNumber::is(this))
-    _flags |= VI_GCALLOWED;
 }
-#endif
 
 void* ValueImp::operator new(size_t s)
 {
@@ -181,63 +132,62 @@ Object ValueImp::dispatchToObject(ExecState *exec) const
   return toObject(exec);
 }
 
-// ------------------------------ Value ----------------------------------------
+bool ValueImp::isUndefinedOrNull() const
+{
+    switch (dispatchType()) {
+        case BooleanType:
+        case NumberType:
+        case ObjectType:
+        case StringType:
+            break;
+        case NullType:
+        case UndefinedType:
+            return true;
+        case UnspecifiedType:
+            assert(false);
+            break;
+    }
+    return false;
+}
 
-#if !USE_CONSERVATIVE_GC
+bool ValueImp::isBoolean(bool &booleanValue) const
+{
+    if (!isBoolean())
+        return false;
+    booleanValue = static_cast<const BooleanImp *>(this)->value();
+    return true;
+}
 
-Value::Value(ValueImp *v)
+bool ValueImp::isNumber(double &numericValue) const
 {
-  rep = v;
-#if DEBUG_COLLECTOR
-  assert (!(rep && !SimpleNumber::is(rep) && *((uint32_t *)rep) == 0 ));
-  assert (!(rep && !SimpleNumber::is(rep) && rep->_flags & ValueImp::VI_MARKED));
-#endif
-  if (v)
-  {
-    v->ref();
-    //fprintf(stderr, "Value::Value(%p) imp=%p ref=%d\n", this, rep, rep->refcount);
-    v->setGcAllowed();
-  }
+    if (!isNumber())
+        return false;
+    numericValue = static_cast<const NumberImp *>(this)->value();
+    return true;
 }
 
-Value::Value(const Value &v)
+bool ValueImp::isString(UString &stringValue) const
 {
-  rep = v.imp();
-#if DEBUG_COLLECTOR
-  assert (!(rep && !SimpleNumber::is(rep) && *((uint32_t *)rep) == 0 ));
-  assert (!(rep && !SimpleNumber::is(rep) && rep->_flags & ValueImp::VI_MARKED));
-#endif
-  if (rep)
-  {
-    rep->ref();
-    //fprintf(stderr, "Value::Value(%p)(copying %p) imp=%p ref=%d\n", this, &v, rep, rep->refcount);
-  }
+    if (!isString())
+        return false;
+    stringValue = static_cast<const StringImp *>(this)->value();
+    return true;
 }
 
-Value::~Value()
+UString ValueImp::asString() const
 {
-  if (rep)
-  {
-    rep->deref();
-    //fprintf(stderr, "Value::~Value(%p) imp=%p ref=%d\n", this, rep, rep->refcount);
-  }
+    return isString() ? static_cast<const StringImp *>(this)->value() : UString();
 }
 
-Value& Value::operator=(const Value &v)
+bool ValueImp::isObject(ObjectImp *&object)
 {
-  if (rep) {
-    rep->deref();
-    //fprintf(stderr, "Value::operator=(%p)(copying %p) old imp=%p ref=%d\n", this, &v, rep, rep->refcount);
-  }
-  rep = v.imp();
-  if (rep)
-  {
-    rep->ref();
-    //fprintf(stderr, "Value::operator=(%p)(copying %p) imp=%p ref=%d\n", this, &v, rep, rep->refcount);
-  }
-  return *this;
+    if (!isObject())
+        return false;
+    object = static_cast<ObjectImp *>(this);
+    return true;
 }
-#endif
+
+// ------------------------------ Value ----------------------------------------
 
 Value::Value(bool b) : rep(b ? BooleanImp::staticTrue : BooleanImp::staticFalse) { }
 
@@ -398,3 +348,79 @@ bool Number::isInf() const
     return false;
   return KJS::isInf(((NumberImp*)rep)->value());
 }
+
+ValueImp *undefined()
+{
+    return UndefinedImp::staticUndefined;
+}
+
+ValueImp *null()
+{
+    return NullImp::staticNull;
+}
+
+ValueImp *boolean(bool b)
+{
+    return b ? BooleanImp::staticTrue : BooleanImp::staticFalse;
+}
+
+ValueImp *string(const char *s)
+{
+    return new StringImp(s ? s : "");
+}
+
+ValueImp *string(const UString &s)
+{
+    return s.isNull() ? new StringImp("") : new StringImp(s);
+}
+
+ValueImp *zero()
+{
+    return SimpleNumber::make(0);
+}
+
+ValueImp *one()
+{
+    return SimpleNumber::make(1);
+}
+
+ValueImp *two()
+{
+    return SimpleNumber::make(2);
+}
+
+ValueImp *number(int i)
+{
+    return SimpleNumber::fits(i) ? SimpleNumber::make(i) : new NumberImp(static_cast<double>(i));
+}
+
+ValueImp *number(unsigned i)
+{
+    return SimpleNumber::fits(i) ? SimpleNumber::make(i) : new NumberImp(static_cast<double>(i));
+}
+
+ValueImp *number(long i)
+{
+    return SimpleNumber::fits(i) ? SimpleNumber::make(i) : new NumberImp(static_cast<double>(i));
+}
+
+ValueImp *number(unsigned long i)
+{
+    return SimpleNumber::fits(i) ? SimpleNumber::make(i) : new NumberImp(static_cast<double>(i));
+}
+
+ValueImp *number(double d)
+{
+    return SimpleNumber::fits(d)
+        ? SimpleNumber::make(static_cast<long>(d))
+        : (isNaN(d) ? NumberImp::staticNaN : new NumberImp(d));
+}
+
+ValueImp *number(double d, bool knownToBeInteger)
+{
+    return (knownToBeInteger ? SimpleNumber::integerFits(d) : SimpleNumber::fits(d))
+        ? SimpleNumber::make(static_cast<long>(d))
+        : ((!knownToBeInteger && isNaN(d)) ? NumberImp::staticNaN : new NumberImp(d));
+}
+
+}
index 12c4e7574fc16507dc2418f16c76b8e588cb2c5e..1a249305eabea6b124ea77074b3f886c14328088 100644 (file)
@@ -25,9 +25,6 @@
 #ifndef _KJS_VALUE_H_
 #define _KJS_VALUE_H_
 
-#define USE_CONSERVATIVE_GC 1
-#define TEST_CONSERVATIVE_GC 0
-
 #ifndef NDEBUG // protection against problems if committing with KJS_VERBOSE on
 
 // Uncomment this to enable very verbose output from KJS
@@ -68,6 +65,7 @@ namespace KJS {
   class ListImp;
   class Completion;
   class ExecState;
+  class ClassInfo;
 
   /**
    * Primitive types
@@ -96,36 +94,14 @@ namespace KJS {
     friend class ContextImp;
     friend class FunctionCallNode;
   public:
-#if USE_CONSERVATIVE_GC
-    ValueImp() : _marked(0) {}
-    virtual ~ValueImp() {}
-#else
-    ValueImp();
-    virtual ~ValueImp();
-#endif
-
-#if !USE_CONSERVATIVE_GC
-    ValueImp* ref() { if (!SimpleNumber::is(this)) refcount++; return this; }
-    bool deref() { if (SimpleNumber::is(this)) return false; else return (!--refcount); }
-#endif
+    ValueImp() : _marked(false) { }
+    virtual ~ValueImp() { }
 
     virtual void mark();
     bool marked() const;
     void* operator new(size_t);
     void operator delete(void*);
 
-#if !USE_CONSERVATIVE_GC
-    /**
-     * @internal
-     *
-     * set by Object() so that the collector is allowed to delete us
-     */
-    void setGcAllowed();
-    
-    // Will crash if called on a simple number.
-    void setGcAllowedFast() { _flags |= VI_GCALLOWED; }
-#endif
-
     double toInteger(ExecState *exec) const;
     int32_t toInt32(ExecState *exec) const;
     uint32_t toUInt32(ExecState *exec) const;
@@ -142,9 +118,24 @@ namespace KJS {
     bool dispatchToUInt32(uint32_t&) const;
     Object dispatchToObject(ExecState *exec) const;
 
-#if !USE_CONSERVATIVE_GC
-    unsigned short int refcount;
-#endif
+    bool isUndefined() const { return dispatchType() == UndefinedType; }
+    bool isNull() const { return dispatchType() == NullType; }
+    bool isUndefinedOrNull() const;
+
+    bool isBoolean() const { return dispatchType() == BooleanType; }
+    bool isBoolean(bool &booleanValue) const;
+
+    bool isNumber() const { return dispatchType() == NumberType; }
+    bool isNumber(double &numericValue) const;
+
+    bool isString() const { return dispatchType() == StringType; }
+    bool isString(UString &stringValue) const;
+    UString asString() const; // null string if not a string
+
+    bool isObject() const { return dispatchType() == ObjectType; }
+    bool isObject(ObjectImp *&object);
+    ObjectImp *asObject(); // 0 if not an object
+    bool isObject(const ClassInfo *) const; // combine an isObject check with an inherits check
 
   private:
     virtual Type type() const = 0;
@@ -158,30 +149,37 @@ namespace KJS {
     virtual Object toObject(ExecState *exec) const = 0;
     virtual bool toUInt32(unsigned&) const;
 
-#if USE_CONSERVATIVE_GC
     bool _marked;
-#else
-    unsigned short int _flags;
-
-    enum {
-      VI_MARKED = 1,
-      VI_GCALLOWED = 2,
-      VI_CREATED = 4
-#if TEST_CONSERVATIVE_GC
-      , VI_CONSERVATIVE_MARKED = 8
-#endif // TEST_CONSERVATIVE_GC
-    }; // VI means VALUEIMPL
-#endif // USE_CONSERVATIVE_GC
 
     // Give a compile time error if we try to copy one of these.
     ValueImp(const ValueImp&);
     ValueImp& operator=(const ValueImp&);
-
-#if TEST_CONSERVATIVE_GC
-    static void useConservativeMark(bool);
-#endif
   };
+  
+  ValueImp *undefined();
+  ValueImp *null();
+
+  ValueImp *boolean(bool = false);
+
+  ValueImp *string(const char * = ""); // returns empty string if passed 0
+  ValueImp *string(const UString &); // returns empty string if passed null string
 
+  ValueImp *zero();
+  ValueImp *one();
+  ValueImp *two();
+  ValueImp *number(int);
+  ValueImp *number(unsigned);
+  ValueImp *number(long);
+  ValueImp *number(unsigned long);
+  ValueImp *number(double);
+  ValueImp *number(double, bool knownToBeInteger);
+
+  /**
+   * FIXME: Now that we have conservative GC, we will be deprecating the
+   * Value wrappers and programming in terms of the ValueImp objects.
+   * Eventually we will remove Value and rename ValueImp to Value.
+   * We'll need to move the comments from Value to ValueImp too.
+   */
   /**
    * Value objects are act as wrappers ("smart pointers") around ValueImp
    * objects and their descendents. Instead of using ValueImps
@@ -200,17 +198,8 @@ namespace KJS {
   class Value {
   public:
     Value() : rep(0) { }
-#if USE_CONSERVATIVE_GC
-    explicit Value(ValueImp *v) : rep(v) {}
-    Value(const Value &v) : rep (v.rep) {}
-    ~Value() {}
-    Value& operator=(const Value &v) { rep = v.rep; return *this; } 
-#else
-    explicit Value(ValueImp *v);
-    Value(const Value &v);
-    ~Value();
-    Value& operator=(const Value &v);
-#endif
+    Value(ValueImp *v) : rep(v) { }
+    operator ValueImp *() const { return rep; }
 
     explicit Value(bool);
 
@@ -440,17 +429,7 @@ namespace KJS {
 inline bool ValueImp::marked() const
 {
   // Simple numbers are always considered marked.
-#if USE_CONSERVATIVE_GC
   return SimpleNumber::is(this) || _marked;
-#elif TEST_CONSERVATIVE_GC
-  if (conservativeMark) {
-    return SimpleNumber::is(this) || (_flags & VI_CONSERVATIVE_MARKED);
-  } else {
-    return SimpleNumber::is(this) || (_flags & VI_MARKED);
-  }
-#else
-  return SimpleNumber::is(this) || (_flags & VI_MARKED);
-#endif
 }
 
 // Dispatchers for virtual functions, to special-case simple numbers which