[SCM] WebKit Debian packaging branch, debian/unstable, updated. debian/1.1.15-1-40151-g37bb677

mjs mjs at 268f45cc-cd09-0410-ab3c-d52691b4dbfc
Sat Sep 26 08:36:36 UTC 2009


The following commit has been merged in the debian/unstable branch:
commit 99f74d992875d52e0c05c38c65f8baeb87f9e7ec
Author: mjs <mjs at 268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Fri Apr 23 22:40:31 2004 +0000

            Reviewed by Darin.
    
    	Implementation of conservative GC, based partly on code from
    	Darin. It's turned off for now, so it shouldn't have any effect on
    	the normal build.
    
            * JavaScriptCore.pbproj/project.pbxproj:
            * kjs/collector.cpp:
            (KJS::Collector::markStackObjectsConservatively):
            (KJS::Collector::markProtectedObjects):
            (KJS::Collector::collect):
            * kjs/collector.h:
            * kjs/protect.h:
            (KJS::gcProtect):
            (KJS::gcUnprotect):
            * kjs/protected_values.cpp: Added.
            (KJS::ProtectedValues::getProtectCount):
            (KJS::ProtectedValues::increaseProtectCount):
            (KJS::ProtectedValues::insert):
            (KJS::ProtectedValues::decreaseProtectCount):
            (KJS::ProtectedValues::expand):
            (KJS::ProtectedValues::shrink):
            (KJS::ProtectedValues::rehash):
            (KJS::ProtectedValues::computeHash):
            * kjs/protected_values.h: Added.
            * kjs/value.cpp:
            (ValueImp::useConservativeMark):
            (ValueImp::mark):
            (ValueImp::marked):
            * kjs/value.h:
            (KJS::ValueImp::):
    
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@6472 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/JavaScriptCore/ChangeLog b/JavaScriptCore/ChangeLog
index c98a50f..106187e 100644
--- a/JavaScriptCore/ChangeLog
+++ b/JavaScriptCore/ChangeLog
@@ -1,3 +1,37 @@
+2004-04-23  Maciej Stachowiak  <mjs at apple.com>
+
+        Reviewed by Darin.
+
+	Implementation of conservative GC, based partly on code from
+	Darin. It's turned off for now, so it shouldn't have any effect on
+	the normal build.
+	
+        * JavaScriptCore.pbproj/project.pbxproj:
+        * kjs/collector.cpp:
+        (KJS::Collector::markStackObjectsConservatively):
+        (KJS::Collector::markProtectedObjects):
+        (KJS::Collector::collect):
+        * kjs/collector.h:
+        * kjs/protect.h:
+        (KJS::gcProtect):
+        (KJS::gcUnprotect):
+        * kjs/protected_values.cpp: Added.
+        (KJS::ProtectedValues::getProtectCount):
+        (KJS::ProtectedValues::increaseProtectCount):
+        (KJS::ProtectedValues::insert):
+        (KJS::ProtectedValues::decreaseProtectCount):
+        (KJS::ProtectedValues::expand):
+        (KJS::ProtectedValues::shrink):
+        (KJS::ProtectedValues::rehash):
+        (KJS::ProtectedValues::computeHash):
+        * kjs/protected_values.h: Added.
+        * kjs/value.cpp:
+        (ValueImp::useConservativeMark):
+        (ValueImp::mark):
+        (ValueImp::marked):
+        * kjs/value.h:
+        (KJS::ValueImp::):
+
 === Safari-138 ===
 
 2004-04-22  Richard Williamson   <rjw at apple.com>
diff --git a/JavaScriptCore/JavaScriptCore.pbproj/project.pbxproj b/JavaScriptCore/JavaScriptCore.pbproj/project.pbxproj
index 68dd112..fac82d5 100644
--- a/JavaScriptCore/JavaScriptCore.pbproj/project.pbxproj
+++ b/JavaScriptCore/JavaScriptCore.pbproj/project.pbxproj
@@ -260,6 +260,7 @@
 				5199B266061BB1300070C006,
 				65AB004B06261CBA0076DE63,
 				65C02FBC0637462A003E7EE6,
+				650B68DB0639033F009D42DE,
 			);
 			isa = PBXHeadersBuildPhase;
 			runOnlyForDeploymentPostprocessing = 0;
@@ -333,6 +334,7 @@
 				5182A53C06012C3000CBD2F2,
 				5199B1BF061B65BC0070C006,
 				65AB004A06261CBA0076DE63,
+				650B68DA0639033F009D42DE,
 			);
 			isa = PBXSourcesBuildPhase;
 			runOnlyForDeploymentPostprocessing = 0;
@@ -352,6 +354,8 @@
 		08FB77AEFE84172EC02AAC07 = {
 			children = (
 				938772E5038BFE19008635CE,
+				650B68D80639033F009D42DE,
+				650B68D90639033F009D42DE,
 				65AB004806261CBA0076DE63,
 				65AB004906261CBA0076DE63,
 				F692A84E0255597D01FF60F7,
@@ -1109,6 +1113,37 @@
 //652
 //653
 //654
+		650B68D80639033F009D42DE = {
+			fileEncoding = 30;
+			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.cpp.cpp;
+			path = protected_values.cpp;
+			refType = 4;
+			sourceTree = "<group>";
+		};
+		650B68D90639033F009D42DE = {
+			fileEncoding = 30;
+			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.h;
+			path = protected_values.h;
+			refType = 4;
+			sourceTree = "<group>";
+		};
+		650B68DA0639033F009D42DE = {
+			fileRef = 650B68D80639033F009D42DE;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		650B68DB0639033F009D42DE = {
+			fileRef = 650B68D90639033F009D42DE;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
 		651F6412039D5B5F0078395C = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
diff --git a/JavaScriptCore/kjs/collector.cpp b/JavaScriptCore/kjs/collector.cpp
index ec6cfb6..09ef8ee 100644
--- a/JavaScriptCore/kjs/collector.cpp
+++ b/JavaScriptCore/kjs/collector.cpp
@@ -162,12 +162,101 @@ void* Collector::allocate(size_t s)
   return (void *)(newCell);
 }
 
+#if TEST_CONSERVATIVE_GC
+ 
+#define IS_POINTER_ALIGNED(p) (((int)(p) & (sizeof(char *) - 1)) == 0)
+
+void Collector::markStackObjectsConservatively(void *start, void *end)
+{
+  assert(((char *)end - (char *)start) < 0x1000000);
+  assert(IS_POINTER_ALIGNED(start));
+  assert(IS_POINTER_ALIGNED(end));
+  
+  char **p = (char **)start;
+  char **e = (char **)end;
+  
+  while (p != e) {
+    char *x = *p++;
+    if (IS_POINTER_ALIGNED(x)) {
+      bool good = false;
+      for (int block = 0; block < heap.usedBlocks; block++) {
+	size_t offset = x - (char *)heap.blocks[block];
+	const size_t lastCellOffset = sizeof(CollectorCell) * (CELLS_PER_BLOCK - 1);
+	if (offset <= lastCellOffset && offset % sizeof(CollectorCell) == 0) {
+	  good = true;
+	  break;
+	}
+      }
+      
+      if (!good) {
+	int n = heap.usedOversizeCells;
+	for (int i = 0; i != n; i++) {
+	  if (x == (char *)heap.oversizeCells[i]) {
+	    good = true;
+	    break;
+	  }
+	}
+      }
+      
+      if (good && ((CollectorCell *)x)->u.freeCell.zeroIfFree != 0) {
+	ValueImp *imp = (ValueImp *)x;
+	if (!imp->marked())
+	  imp->mark();
+      }
+    }
+  }
+}
+
+void Collector::markStackObjectsConservatively()
+{
+  jmp_buf registers;
+  setjmp(registers);
+
+  pthread_t thread = pthread_self();
+  void *stackBase = pthread_get_stackaddr_np(thread);
+  void *stackPointer;
+  asm("mr %0,r1" : "=r" (stackPointer));
+  markStackObjectsConservatively(stackPointer, stackBase);
+}
+
+void Collector::markProtectedObjects()
+{
+  for (int i = 0; i < ProtectedValues::_tableSize; i++) {
+    ValueImp *val = ProtectedValues::_table[i].key;
+    if (val && !val->marked()) {
+      val->mark();
+    }
+  }
+}
+
+#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);
+
+  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);
+  }
+
+  markStackObjectsConservatively();
+  markProtectedObjects();
+
+
+  ValueImp::useConservativeMark(false);
+#endif
+
   // MARK: first mark all referenced objects recursively
   // starting out from the set of root objects
   if (InterpreterImp::s_hook) {
@@ -244,7 +333,11 @@ bool Collector::collect()
 	  curBlock->freeList = (CollectorCell *)imp;
 
 	} else {
+#if TEST_CONSERVATIVE_GC
+	  imp->_flags &= ~(ValueImp::VI_MARKED | ValueImp::VI_CONSERVATIVE_MARKED);
+#else
 	  imp->_flags &= ~ValueImp::VI_MARKED;
+#endif
 	}
       } else {
 	minimumCellsToProcess++;
diff --git a/JavaScriptCore/kjs/collector.h b/JavaScriptCore/kjs/collector.h
index f68a0e1..be5bba3 100644
--- a/JavaScriptCore/kjs/collector.h
+++ b/JavaScriptCore/kjs/collector.h
@@ -24,6 +24,8 @@
 #ifndef _KJSCOLLECTOR_H_
 #define _KJSCOLLECTOR_H_
 
+#include "value.h"
+
 #define KJS_MEM_LIMIT 500000
 
 namespace KJS {
@@ -68,6 +70,13 @@ namespace KJS {
     static const void *rootObjectClasses(); // actually returns CFSetRef
 #endif
   private:
+
+#if TEST_CONSERVATIVE_GC
+    static void markProtectedObjects();
+    static void markStackObjectsConservatively();
+    static void markStackObjectsConservatively(void *start, void *end);
+#endif
+
     static bool memoryFull;
   };
 
diff --git a/JavaScriptCore/kjs/protect.h b/JavaScriptCore/kjs/protect.h
index 691d292..1bf2a61 100644
--- a/JavaScriptCore/kjs/protect.h
+++ b/JavaScriptCore/kjs/protect.h
@@ -27,11 +27,22 @@
 #include "object.h"
 #include "reference.h"
 #include "value.h"
+#include "protected_values.h"
 
 namespace KJS {
 
-    inline void gcProtect(ValueImp *) {}
-    inline void gcUnprotect(ValueImp *) {}
+    inline void gcProtect(ValueImp *val) 
+      { 
+#if TEST_CONSERVATIVE_GC
+	ProtectedValues::increaseProtectCount(val);
+#endif
+      }
+    inline void gcUnprotect(ValueImp *val)
+      { 
+#if TEST_CONSERVATIVE_GC
+	ProtectedValues::decreaseProtectCount(val);
+#endif
+      }
     
     class ProtectedValue : public Value {
     public:
diff --git a/JavaScriptCore/kjs/interpreter_map.cpp b/JavaScriptCore/kjs/protected_values.cpp
similarity index 65%
copy from JavaScriptCore/kjs/interpreter_map.cpp
copy to JavaScriptCore/kjs/protected_values.cpp
index dafed25..fe6df1e 100644
--- a/JavaScriptCore/kjs/interpreter_map.cpp
+++ b/JavaScriptCore/kjs/protected_values.cpp
@@ -1,3 +1,4 @@
+// -*- c-basic-offset: 2 -*-
 /*
  *  This file is part of the KDE libraries
  *  Copyright (C) 2004 Apple Computer, Inc.
@@ -19,72 +20,77 @@
  *
  */
 
-#include "interpreter_map.h"
+#include "protected_values.h"
 
 namespace KJS {
 
 const int _minTableSize = 64;
 
-InterpreterMap::KeyValue *InterpreterMap::_table;
-int InterpreterMap::_tableSize;
-int InterpreterMap::_tableSizeMask;
-int InterpreterMap::_keyCount;
+ProtectedValues::KeyValue *ProtectedValues::_table;
+int ProtectedValues::_tableSize;
+int ProtectedValues::_tableSizeMask;
+int ProtectedValues::_keyCount;
 
-
-InterpreterImp * InterpreterMap::getInterpreterForGlobalObject(ObjectImp *global)
+int ProtectedValues::getProtectCount(ValueImp *k)
 {
+    if (!k)
+	return 0;
+
     if (!_table)
-        expand();
-    
-    unsigned hash = computeHash(global);
+	return 0;
+
+    unsigned hash = computeHash(k);
     
     int i = hash & _tableSizeMask;
 #if DUMP_STATISTICS
     ++numProbes;
-    numCollisions += _table[i].key && _table[i].key != global;
+    numCollisions += _table[i].key && _table[i].key != k;
 #endif
-    while (ObjectImp *key = _table[i].key) {
-        if (key == global) {
+    while (ValueImp *key = _table[i].key) {
+        if (key == k) {
 	    return _table[i].value;
 	}
         i = (i + 1) & _tableSizeMask;
     }
-    
+
     return 0;
 }
 
 
-void InterpreterMap::setInterpreterForGlobalObject(InterpreterImp *interpreter, ObjectImp *global)
+void ProtectedValues::increaseProtectCount(ValueImp *k)
 {
+    if (!k)
+	return;
+
     if (!_table)
         expand();
     
-    unsigned hash = computeHash(global);
+    unsigned hash = computeHash(k);
     
     int i = hash & _tableSizeMask;
 #if DUMP_STATISTICS
     ++numProbes;
-    numCollisions += _table[i].key && _table[i].key != global;
+    numCollisions += _table[i].key && _table[i].key != k;
 #endif
-    while (ObjectImp *key = _table[i].key) {
-        if (key == global) {
-	    _table[i].value = interpreter;
+    while (ValueImp *key = _table[i].key) {
+        if (key == k) {
+	    _table[i].value++;
 	    return;
 	}
         i = (i + 1) & _tableSizeMask;
     }
     
-    _table[i].key = global;
-    _table[i].value = interpreter;
+    _table[i].key = k;
+    _table[i].value = 1;
     ++_keyCount;
     
     if (_keyCount * 2 >= _tableSize)
         expand();
 }
 
-inline void InterpreterMap::insert(InterpreterImp *interpreter, ObjectImp *global)
+inline void ProtectedValues::insert(ValueImp *k, int v)
 {
-    unsigned hash = computeHash(global);
+    unsigned hash = computeHash(k);
     
     int i = hash & _tableSizeMask;
 #if DUMP_STATISTICS
@@ -94,31 +100,38 @@ inline void InterpreterMap::insert(InterpreterImp *interpreter, ObjectImp *globa
     while (_table[i].key)
         i = (i + 1) & _tableSizeMask;
     
-    _table[i].key = global;
-    _table[i].value = interpreter;
+    _table[i].key = k;
+    _table[i].value = v;
 }
 
-void InterpreterMap::removeInterpreterForGlobalObject(ObjectImp *global)
+void ProtectedValues::decreaseProtectCount(ValueImp *k)
 {
-    unsigned hash = computeHash(global);
+    if (!k)
+	return;
+
+    unsigned hash = computeHash(k);
     
-    ObjectImp *key;
+    ValueImp *key;
     
     int i = hash & _tableSizeMask;
 #if DUMP_STATISTICS
     ++numProbes;
-    numCollisions += _table[i].key && _table[i].key == global;
+    numCollisions += _table[i].key && _table[i].key == k;
 #endif
     while ((key = _table[i].key)) {
-        if (key == global)
+        if (key == k)
             break;
         i = (i + 1) & _tableSizeMask;
     }
     if (!key)
         return;
     
+    _table[i].value--;
+
+    if (_table[i].value != 0)
+	return;
+
     _table[i].key = 0;
-    _table[i].value = 0;
     --_keyCount;
     
     if (_keyCount * 6 < _tableSize && _tableSize > _minTableSize) {
@@ -130,26 +143,26 @@ void InterpreterMap::removeInterpreterForGlobalObject(ObjectImp *global)
     while (1) {
         i = (i + 1) & _tableSizeMask;
         key = _table[i].key;
-	InterpreterImp *value = _table[i].value;
+	int value = _table[i].value;
         if (!key)
             break;
         _table[i].key = 0;
         _table[i].value = 0;
-        insert(value,key);
+        insert(key, value);
     }
 }
 
-void InterpreterMap::expand()
+void ProtectedValues::expand()
 {
     rehash(_tableSize == 0 ? _minTableSize : _tableSize * 2);
 }
 
-void InterpreterMap::shrink()
+void ProtectedValues::shrink()
 {
     rehash(_tableSize / 2);
 }
 
-void InterpreterMap::rehash(int newTableSize)
+void ProtectedValues::rehash(int newTableSize)
 {
     int oldTableSize = _tableSize;
     KeyValue *oldTable = _table;
@@ -160,7 +173,7 @@ void InterpreterMap::rehash(int newTableSize)
 
     for (int i = 0; i != oldTableSize; ++i)
         if (oldTable[i].key)
-            insert(oldTable[i].value, oldTable[i].key);
+            insert(oldTable[i].key, oldTable[i].value);
 
     free(oldTable);
 }
@@ -172,12 +185,12 @@ const unsigned PHI = 0x9e3779b9U;
 // This hash algorithm comes from:
 // http://burtleburtle.net/bob/hash/hashfaq.html
 // http://burtleburtle.net/bob/hash/doobs.html
-unsigned InterpreterMap::computeHash(ObjectImp *pointer)
+unsigned ProtectedValues::computeHash(ValueImp *pointer)
 {
-    int length = sizeof(ObjectImp *);
-    char s[sizeof(ObjectImp *)];
+    int length = sizeof(ValueImp *);
+    char s[sizeof(ValueImp *)];
 		
-    memcpy((void *)s, (void *)&pointer, sizeof(ObjectImp *));
+    memcpy((void *)s, (void *)&pointer, sizeof(ValueImp *));
 
     unsigned h = PHI;
     h += length;
@@ -201,4 +214,4 @@ unsigned InterpreterMap::computeHash(ObjectImp *pointer)
 }
 
 
-}; // namespace
+} // namespace
diff --git a/JavaScriptCore/kjs/interpreter_map.h b/JavaScriptCore/kjs/protected_values.h
similarity index 58%
copy from JavaScriptCore/kjs/interpreter_map.h
copy to JavaScriptCore/kjs/protected_values.h
index 016fc0a..40bb152 100644
--- a/JavaScriptCore/kjs/interpreter_map.h
+++ b/JavaScriptCore/kjs/protected_values.h
@@ -20,39 +20,41 @@
  *
  */
 
-#ifndef _KJS_INTERPRETER_MAP_H_
-#define _KJS_INTERPRETER_MAP_H_
+
+#ifndef _KJS_PROTECTED_VALUES_H_
+#define _KJS_PROTECTED_VALUES_H_
 
 namespace KJS {
-    class ObjectImp;
-    class InterpreterImp;
+    class ValueImp;
 
-    class InterpreterMap {
+    class ProtectedValues {
 	struct KeyValue {
-	    ObjectImp *key;
-	    InterpreterImp *value;
+	    ValueImp *key;
+	    int value;
 	};
 
     public:
-	static InterpreterImp * getInterpreterForGlobalObject(ObjectImp *global);
-	static void setInterpreterForGlobalObject(InterpreterImp *interpreter, ObjectImp *global);
-	static void removeInterpreterForGlobalObject(ObjectImp *global);
+	static void increaseProtectCount(ValueImp *key);
+	static void decreaseProtectCount(ValueImp *key);
+
+	static int getProtectCount(ValueImp *key);
 
     private:
-	static void insert(InterpreterImp *interpreter, ObjectImp *global);
+	static void insert(ValueImp *key, int value);
 	static void expand();
 	static void shrink();
 	static void rehash(int newTableSize);
-	static unsigned computeHash(ObjectImp *pointer);
+	static unsigned computeHash(ValueImp *pointer);
 
+	// let the collector scan the table directly for protected
+	// values
+	friend class Collector;
 
-	static KeyValue * InterpreterMap::_table;
-	static int InterpreterMap::_tableSize;
-	static int InterpreterMap::_tableSizeMask;
-	static int InterpreterMap::_keyCount;
+	static KeyValue * ProtectedValues::_table;
+	static int ProtectedValues::_tableSize;
+	static int ProtectedValues::_tableSizeMask;
+	static int ProtectedValues::_keyCount;
     };
+}
 
-}; // namespace
-
-
-#endif // _KJS_INTERPRETER_MAP_H_
+#endif
diff --git a/JavaScriptCore/kjs/value.cpp b/JavaScriptCore/kjs/value.cpp
index a2fb5cf..88913da 100644
--- a/JavaScriptCore/kjs/value.cpp
+++ b/JavaScriptCore/kjs/value.cpp
@@ -56,16 +56,44 @@ ValueImp::~ValueImp()
   //fprintf(stderr,"ValueImp::~ValueImp %p\n",(void*)this);
 }
 
+#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 TEST_CONSERVATIVE_GC
+  if (conservativeMark) {
+    _flags |= VI_CONSERVATIVE_MARKED;
+  } else {
+    if (!(_flags | VI_CONSERVATIVE_MARKED)) {
+      printf("Conservative collector missed ValueImp 0x%x.\n", (int)this);
+    }
+    _flags |= VI_MARKED;
+  }
+#else
   _flags |= VI_MARKED;
+#endif
 }
 
 bool ValueImp::marked() const
 {
   // Simple numbers are always considered marked.
+#if 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
 }
 
 void ValueImp::setGcAllowed()
diff --git a/JavaScriptCore/kjs/value.h b/JavaScriptCore/kjs/value.h
index 9fde98f..c225352 100644
--- a/JavaScriptCore/kjs/value.h
+++ b/JavaScriptCore/kjs/value.h
@@ -25,6 +25,8 @@
 #ifndef _KJS_VALUE_H_
 #define _KJS_VALUE_H_
 
+#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
@@ -148,11 +150,18 @@ namespace KJS {
       VI_MARKED = 1,
       VI_GCALLOWED = 2,
       VI_CREATED = 4
+#if TEST_CONSERVATIVE_GC
+      , VI_CONSERVATIVE_MARKED = 8
+#endif
     }; // VI means VALUEIMPL
 
     // 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
   };
 
   /**

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list