[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