mirror of
https://github.com/corda/corda.git
synced 2025-01-19 03:06:36 +00:00
add util.cpp/.h changes
This commit is contained in:
parent
51368651dc
commit
6a0502bbfe
@ -1916,6 +1916,19 @@ set(Thread* t, object target, unsigned offset, object value)
|
||||
mark(t, target, offset);
|
||||
}
|
||||
|
||||
inline void
|
||||
set(Thread* t, GcObject* target, unsigned offset, GcObject* value)
|
||||
{
|
||||
fieldAtOffset<GcObject*>(target, offset) = value;
|
||||
mark(t, reinterpret_cast<object>(target), offset);
|
||||
}
|
||||
|
||||
inline void
|
||||
setObject(Thread* t, GcObject* target, unsigned offset, GcObject* value)
|
||||
{
|
||||
set(t, target, offset, value);
|
||||
}
|
||||
|
||||
inline void
|
||||
setObjectClass(Thread*, object o, GcClass* c)
|
||||
{
|
||||
@ -3808,8 +3821,8 @@ resolveMethod(Thread* t, GcMethod* method, unsigned index, bool throw_ = true)
|
||||
(t, reinterpret_cast<object>(method->class_()->loader()), method, index, throw_);
|
||||
}
|
||||
|
||||
object
|
||||
vectorAppend(Thread*, object, object);
|
||||
GcVector*
|
||||
vectorAppend(Thread*, GcVector*, object);
|
||||
|
||||
inline object
|
||||
getClassRuntimeDataIfExists(Thread* t, object c)
|
||||
@ -3833,8 +3846,8 @@ getClassRuntimeData(Thread* t, GcClass* c)
|
||||
if (c->runtimeDataIndex() == 0) {
|
||||
object runtimeData = reinterpret_cast<object>(makeClassRuntimeData(t, 0, 0, 0, 0));
|
||||
|
||||
setRoot(t, Machine::ClassRuntimeDataTable, vectorAppend
|
||||
(t, root(t, Machine::ClassRuntimeDataTable), runtimeData));
|
||||
setRoot(t, Machine::ClassRuntimeDataTable, reinterpret_cast<object>(vectorAppend
|
||||
(t, cast<GcVector>(t, root(t, Machine::ClassRuntimeDataTable)), runtimeData)));
|
||||
|
||||
c->runtimeDataIndex() = vectorSize
|
||||
(t, root(t, Machine::ClassRuntimeDataTable));
|
||||
@ -3860,8 +3873,8 @@ getMethodRuntimeData(Thread* t, GcMethod* method)
|
||||
if (method->runtimeDataIndex() == 0) {
|
||||
object runtimeData = reinterpret_cast<object>(makeMethodRuntimeData(t, 0));
|
||||
|
||||
setRoot(t, Machine::MethodRuntimeDataTable, vectorAppend
|
||||
(t, root(t, Machine::MethodRuntimeDataTable), runtimeData));
|
||||
setRoot(t, Machine::MethodRuntimeDataTable, reinterpret_cast<object>(vectorAppend
|
||||
(t, cast<GcVector>(t, root(t, Machine::MethodRuntimeDataTable)), runtimeData)));
|
||||
|
||||
storeStoreMemoryBarrier();
|
||||
|
||||
|
@ -16,7 +16,7 @@
|
||||
|
||||
namespace vm {
|
||||
|
||||
object
|
||||
GcTriple*
|
||||
hashMapFindNode(Thread* t, GcHashMap* map, object key,
|
||||
uint32_t (*hash)(Thread*, object),
|
||||
bool (*equal)(Thread*, object, object));
|
||||
@ -26,8 +26,8 @@ hashMapFind(Thread* t, GcHashMap* map, object key,
|
||||
uint32_t (*hash)(Thread*, object),
|
||||
bool (*equal)(Thread*, object, object))
|
||||
{
|
||||
object n = hashMapFindNode(t, map, key, hash, equal);
|
||||
return (n ? tripleSecond(t, n) : 0);
|
||||
GcTriple* n = hashMapFindNode(t, map, key, hash, equal);
|
||||
return (n ? n->second() : 0);
|
||||
}
|
||||
|
||||
void
|
||||
@ -43,12 +43,12 @@ hashMapInsertOrReplace(Thread* t, GcHashMap* map, object key, object value,
|
||||
uint32_t (*hash)(Thread*, object),
|
||||
bool (*equal)(Thread*, object, object))
|
||||
{
|
||||
object n = hashMapFindNode(t, map, key, hash, equal);
|
||||
GcTriple* n = hashMapFindNode(t, map, key, hash, equal);
|
||||
if (n == 0) {
|
||||
hashMapInsert(t, map, key, value, hash);
|
||||
return true;
|
||||
} else {
|
||||
set(t, n, TripleSecond, value);
|
||||
set(t, reinterpret_cast<object>(n), TripleSecond, value);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -58,7 +58,7 @@ hashMapInsertMaybe(Thread* t, GcHashMap* map, object key, object value,
|
||||
uint32_t (*hash)(Thread*, object),
|
||||
bool (*equal)(Thread*, object, object))
|
||||
{
|
||||
object n = hashMapFindNode(t, map, key, hash, equal);
|
||||
GcTriple* n = hashMapFindNode(t, map, key, hash, equal);
|
||||
if (n == 0) {
|
||||
hashMapInsert(t, map, key, value, hash);
|
||||
return true;
|
||||
@ -79,25 +79,25 @@ object
|
||||
hashMapIteratorNext(Thread* t, object it);
|
||||
|
||||
void
|
||||
listAppend(Thread* t, object list, object value);
|
||||
listAppend(Thread* t, GcList* list, object value);
|
||||
|
||||
object
|
||||
vectorAppend(Thread* t, object vector, object value);
|
||||
GcVector*
|
||||
vectorAppend(Thread* t, GcVector* vector, object value);
|
||||
|
||||
object
|
||||
growArray(Thread* t, object array);
|
||||
|
||||
object
|
||||
treeQuery(Thread* t, object tree, intptr_t key, object sentinal,
|
||||
treeQuery(Thread* t, GcTreeNode* tree, intptr_t key, GcTreeNode* sentinal,
|
||||
intptr_t (*compare)(Thread* t, intptr_t key, object b));
|
||||
|
||||
object
|
||||
treeInsert(Thread* t, Zone* zone, object tree, intptr_t key, object value,
|
||||
object sentinal,
|
||||
GcTreeNode*
|
||||
treeInsert(Thread* t, Zone* zone, GcTreeNode* tree, intptr_t key, object value,
|
||||
GcTreeNode* sentinal,
|
||||
intptr_t (*compare)(Thread* t, intptr_t key, object b));
|
||||
|
||||
void
|
||||
treeUpdate(Thread* t, object tree, intptr_t key, object value, object sentinal,
|
||||
treeUpdate(Thread* t, GcTreeNode* tree, intptr_t key, object value, GcTreeNode* sentinal,
|
||||
intptr_t (*compare)(Thread* t, intptr_t key, object b));
|
||||
|
||||
class HashMapIterator: public Thread::Protector {
|
||||
@ -109,11 +109,11 @@ class HashMapIterator: public Thread::Protector {
|
||||
}
|
||||
|
||||
void find() {
|
||||
object array = map->array();
|
||||
GcArray* array = map->array();
|
||||
if (array) {
|
||||
for (unsigned i = index; i < arrayLength(t, array); ++i) {
|
||||
if (arrayBody(t, array, i)) {
|
||||
node = arrayBody(t, array, i);
|
||||
for (unsigned i = index; i < array->length(); ++i) {
|
||||
if (array->body()[i]) {
|
||||
node = cast<GcTriple>(t, array->body()[i]);
|
||||
index = i + 1;
|
||||
return;
|
||||
}
|
||||
@ -126,11 +126,11 @@ class HashMapIterator: public Thread::Protector {
|
||||
return node != 0;
|
||||
}
|
||||
|
||||
object next() {
|
||||
GcTriple* next() {
|
||||
if (node) {
|
||||
object n = node;
|
||||
if (tripleThird(t, node)) {
|
||||
node = tripleThird(t, node);
|
||||
GcTriple* n = node;
|
||||
if (node->third()) {
|
||||
node = cast<GcTriple>(t, node->third());
|
||||
} else {
|
||||
find();
|
||||
}
|
||||
@ -146,7 +146,7 @@ class HashMapIterator: public Thread::Protector {
|
||||
}
|
||||
|
||||
GcHashMap* map;
|
||||
object node;
|
||||
GcTriple* node;
|
||||
unsigned index;
|
||||
};
|
||||
|
||||
|
@ -412,8 +412,8 @@ methodForIp(MyThread* t, void* ip)
|
||||
// compile(MyThread*, FixedAllocator*, BootContext*, object)):
|
||||
loadMemoryBarrier();
|
||||
|
||||
return cast<GcMethod>(t, treeQuery(t, root(t, MethodTree), reinterpret_cast<intptr_t>(ip),
|
||||
root(t, MethodTreeSentinal), compareIpToMethodBounds));
|
||||
return cast<GcMethod>(t, treeQuery(t, cast<GcTreeNode>(t, root(t, MethodTree)), reinterpret_cast<intptr_t>(ip),
|
||||
cast<GcTreeNode>(t, root(t, MethodTreeSentinal)), compareIpToMethodBounds));
|
||||
}
|
||||
|
||||
unsigned
|
||||
@ -5751,7 +5751,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned initialIp,
|
||||
value);
|
||||
} else {
|
||||
c->call(
|
||||
c->constant(getThunk(t, setThunk), ir::Type::iptr()),
|
||||
c->constant(getThunk(t, setObjectThunk), ir::Type::iptr()),
|
||||
0,
|
||||
0,
|
||||
ir::Type::void_(),
|
||||
@ -9261,7 +9261,7 @@ GcHashMap*
|
||||
makeClassMap(Thread* t, unsigned* table, unsigned count,
|
||||
uintptr_t* heap)
|
||||
{
|
||||
object array = reinterpret_cast<object>(makeArray(t, nextPowerOfTwo(count)));
|
||||
GcArray* array = makeArray(t, nextPowerOfTwo(count));
|
||||
GcHashMap* map = makeHashMap(t, 0, array);
|
||||
PROTECT(t, map);
|
||||
|
||||
@ -9295,7 +9295,7 @@ makeStaticTableArray(Thread* t, unsigned* bootTable, unsigned bootCount,
|
||||
GcWeakHashMap*
|
||||
makeStringMap(Thread* t, unsigned* table, unsigned count, uintptr_t* heap)
|
||||
{
|
||||
object array = reinterpret_cast<object>(makeArray(t, nextPowerOfTwo(count)));
|
||||
GcArray* array = makeArray(t, nextPowerOfTwo(count));
|
||||
GcWeakHashMap* map = makeWeakHashMap(t, 0, array);
|
||||
PROTECT(t, map);
|
||||
|
||||
@ -9400,7 +9400,7 @@ void
|
||||
resetRuntimeState(Thread* t, GcHashMap* map, uintptr_t* heap, unsigned heapSize)
|
||||
{
|
||||
for (HashMapIterator it(t, map); it.hasMore();) {
|
||||
resetClassRuntimeState(t, tripleSecond(t, it.next()), heap, heapSize);
|
||||
resetClassRuntimeState(t, it.next()->second(), heap, heapSize);
|
||||
}
|
||||
}
|
||||
|
||||
@ -9408,7 +9408,7 @@ void
|
||||
fixupMethods(Thread* t, GcHashMap* map, BootImage* image UNUSED, uint8_t* code)
|
||||
{
|
||||
for (HashMapIterator it(t, map); it.hasMore();) {
|
||||
object c = tripleSecond(t, it.next());
|
||||
object c = it.next()->second();
|
||||
|
||||
if (classMethodTable(t, c)) {
|
||||
for (unsigned i = 0; i < arrayLength(t, classMethodTable(t, c)); ++i) {
|
||||
@ -10020,13 +10020,13 @@ compile(MyThread* t, FixedAllocator* allocator, BootContext* bootContext,
|
||||
|
||||
setRoot(t,
|
||||
MethodTree,
|
||||
treeInsert(t,
|
||||
reinterpret_cast<object>(treeInsert(t,
|
||||
&(context.zone),
|
||||
root(t, MethodTree),
|
||||
cast<GcTreeNode>(t, root(t, MethodTree)),
|
||||
methodCompiled(t, clone),
|
||||
reinterpret_cast<object>(clone),
|
||||
root(t, MethodTreeSentinal),
|
||||
compareIpToMethodBounds));
|
||||
cast<GcTreeNode>(t, root(t, MethodTreeSentinal)),
|
||||
compareIpToMethodBounds)));
|
||||
|
||||
storeStoreMemoryBarrier();
|
||||
|
||||
@ -10042,8 +10042,8 @@ compile(MyThread* t, FixedAllocator* allocator, BootContext* bootContext,
|
||||
// when we dispose of the context:
|
||||
context.executableAllocator = 0;
|
||||
|
||||
treeUpdate(t, root(t, MethodTree), methodCompiled(t, clone),
|
||||
reinterpret_cast<object>(method), root(t, MethodTreeSentinal), compareIpToMethodBounds);
|
||||
treeUpdate(t, cast<GcTreeNode>(t, root(t, MethodTree)), methodCompiled(t, clone),
|
||||
reinterpret_cast<object>(method), cast<GcTreeNode>(t, root(t, MethodTreeSentinal)), compareIpToMethodBounds);
|
||||
}
|
||||
|
||||
object&
|
||||
|
@ -544,8 +544,8 @@ methodID(Thread* t, GcMethod* method)
|
||||
ACQUIRE(t, t->m->referenceLock);
|
||||
|
||||
if (method->nativeID() == 0) {
|
||||
setRoot(t, Machine::JNIMethodTable, vectorAppend
|
||||
(t, root(t, Machine::JNIMethodTable), reinterpret_cast<object>(method)));
|
||||
setRoot(t, Machine::JNIMethodTable, reinterpret_cast<object>(vectorAppend
|
||||
(t, cast<GcVector>(t, root(t, Machine::JNIMethodTable)), reinterpret_cast<object>(method))));
|
||||
|
||||
storeStoreMemoryBarrier();
|
||||
|
||||
@ -1497,8 +1497,8 @@ fieldID(Thread* t, object field)
|
||||
ACQUIRE(t, t->m->referenceLock);
|
||||
|
||||
if (fieldNativeID(t, field) == 0) {
|
||||
setRoot(t, Machine::JNIFieldTable, vectorAppend
|
||||
(t, root(t, Machine::JNIFieldTable), field));
|
||||
setRoot(t, Machine::JNIFieldTable, reinterpret_cast<object>(vectorAppend
|
||||
(t, cast<GcVector>(t, root(t, Machine::JNIFieldTable)), field)));
|
||||
|
||||
storeStoreMemoryBarrier();
|
||||
|
||||
|
@ -893,10 +893,10 @@ internByteArray(Thread* t, object array)
|
||||
|
||||
ACQUIRE(t, t->m->referenceLock);
|
||||
|
||||
object n = hashMapFindNode
|
||||
GcTriple* n = hashMapFindNode
|
||||
(t, cast<GcHashMap>(t, root(t, Machine::ByteArrayMap)), array, byteArrayHash, byteArrayEqual);
|
||||
if (n) {
|
||||
return jreferenceTarget(t, tripleFirst(t, n));
|
||||
return jreferenceTarget(t, n->first());
|
||||
} else {
|
||||
hashMapInsert(t, cast<GcHashMap>(t, root(t, Machine::ByteArrayMap)), array, 0, byteArrayHash);
|
||||
addFinalizer(t, array, removeByteArray);
|
||||
@ -1275,7 +1275,7 @@ parseInterfaceTable(Thread* t, Stream& s, GcClass* class_, GcSingleton* pool,
|
||||
|
||||
unsigned i = 0;
|
||||
for (HashMapIterator it(t, map); it.hasMore();) {
|
||||
GcClass* interface = cast<GcClass>(t, tripleSecond(t, it.next()));
|
||||
GcClass* interface = cast<GcClass>(t, it.next()->second());
|
||||
|
||||
set(t, interfaceTable, ArrayBody + (i * BytesPerWord), reinterpret_cast<object>(interface));
|
||||
++ i;
|
||||
@ -1987,7 +1987,7 @@ addInterfaceMethods(Thread* t, GcClass* class_, GcHashMap* virtualMap,
|
||||
if (vtable) {
|
||||
for (unsigned j = 0; j < arrayLength(t, vtable); ++j) {
|
||||
method = cast<GcMethod>(t, arrayBody(t, vtable, j));
|
||||
object n = hashMapFindNode
|
||||
GcTriple* n = hashMapFindNode
|
||||
(t, virtualMap, reinterpret_cast<object>(method), methodHash, methodEqual);
|
||||
if (n == 0) {
|
||||
method = makeMethod
|
||||
@ -2016,7 +2016,7 @@ addInterfaceMethods(Thread* t, GcClass* class_, GcHashMap* virtualMap,
|
||||
if (list == 0) {
|
||||
list = reinterpret_cast<object>(vm::makeList(t, 0, 0, 0));
|
||||
}
|
||||
listAppend(t, list, reinterpret_cast<object>(method));
|
||||
listAppend(t, cast<GcList>(t, list), reinterpret_cast<object>(method));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2193,17 +2193,17 @@ parseMethodTable(Thread* t, Stream& s, GcClass* class_, GcSingleton* pool)
|
||||
if (methodVirtual(t, method)) {
|
||||
++ declaredVirtualCount;
|
||||
|
||||
object p = hashMapFindNode
|
||||
GcTriple* p = hashMapFindNode
|
||||
(t, virtualMap, reinterpret_cast<object>(method), methodHash, methodEqual);
|
||||
|
||||
if (p) {
|
||||
method->offset() = methodOffset(t, tripleFirst(t, p));
|
||||
method->offset() = methodOffset(t, p->first());
|
||||
|
||||
set(t, p, TripleSecond, reinterpret_cast<object>(method));
|
||||
set(t, reinterpret_cast<object>(p), TripleSecond, reinterpret_cast<object>(method));
|
||||
} else {
|
||||
method->offset() = virtualCount++;
|
||||
|
||||
listAppend(t, newVirtuals, reinterpret_cast<object>(method));
|
||||
listAppend(t, cast<GcList>(t, newVirtuals), reinterpret_cast<object>(method));
|
||||
|
||||
hashMapInsert(t, virtualMap, reinterpret_cast<object>(method), reinterpret_cast<object>(method), methodHash);
|
||||
}
|
||||
@ -2284,7 +2284,7 @@ parseMethodTable(Thread* t, Stream& s, GcClass* class_, GcSingleton* pool)
|
||||
PROTECT(t, vtable);
|
||||
|
||||
for (HashMapIterator it(t, virtualMap); it.hasMore();) {
|
||||
object method = tripleFirst(t, it.next());
|
||||
object method = it.next()->first();
|
||||
assertT(t, arrayBody(t, vtable, methodOffset(t, method)) == 0);
|
||||
set(t, vtable, ArrayBody + (methodOffset(t, method) * BytesPerWord),
|
||||
method);
|
||||
@ -4933,11 +4933,11 @@ intern(Thread* t, object s)
|
||||
|
||||
ACQUIRE(t, t->m->referenceLock);
|
||||
|
||||
object n = hashMapFindNode
|
||||
GcTriple* n = hashMapFindNode
|
||||
(t, cast<GcHashMap>(t, root(t, Machine::StringMap)), s, stringHash, stringEqual);
|
||||
|
||||
if (n) {
|
||||
return jreferenceTarget(t, tripleFirst(t, n));
|
||||
return jreferenceTarget(t, n->first());
|
||||
} else {
|
||||
hashMapInsert(t, cast<GcHashMap>(t, root(t, Machine::StringMap)), s, 0, stringHash);
|
||||
addFinalizer(t, s, removeString);
|
||||
|
@ -66,7 +66,7 @@ THUNK(instanceOfFromReference)
|
||||
THUNK(makeNewGeneral64)
|
||||
THUNK(makeNew64)
|
||||
THUNK(makeNewFromReference)
|
||||
THUNK(set)
|
||||
THUNK(setObject)
|
||||
THUNK(getJClass64)
|
||||
THUNK(getJClassFromReference)
|
||||
THUNK(gcIfNecessary)
|
||||
|
@ -200,13 +200,13 @@ getNonStaticFields(Thread* t, GcHashMap* typeMaps, object c, object fields,
|
||||
|
||||
if ((fieldFlags(t, field) & ACC_STATIC) == 0) {
|
||||
++ (*count);
|
||||
fields = vectorAppend(t, fields, field);
|
||||
fields = reinterpret_cast<object>(vectorAppend(t, cast<GcVector>(t, fields), field));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return vectorAppend(t, fields, 0);
|
||||
return reinterpret_cast<object>(vectorAppend(t, cast<GcVector>(t, fields), 0));
|
||||
}
|
||||
|
||||
object
|
||||
@ -239,7 +239,7 @@ allFields(Thread* t, GcHashMap* typeMaps, object c, unsigned* count, object* arr
|
||||
|
||||
if (includeMembers or (fieldFlags(t, field) & ACC_STATIC)) {
|
||||
++ (*count);
|
||||
fields = vectorAppend(t, fields, field);
|
||||
fields = reinterpret_cast<object>(vectorAppend(t, cast<GcVector>(t, fields), field));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -707,7 +707,7 @@ visitRoots(Thread* t, BootImage* image, HeapWalker* w, object constants)
|
||||
for (HashMapIterator it(t, cast<GcHashMap>(t, classLoaderMap(t, root(t, Machine::BootLoader))));
|
||||
it.hasMore();)
|
||||
{
|
||||
w->visitRoot(tripleSecond(t, it.next()));
|
||||
w->visitRoot(it.next()->second());
|
||||
}
|
||||
|
||||
image->bootLoader = w->visitRoot(root(t, Machine::BootLoader));
|
||||
@ -1572,7 +1572,7 @@ writeBootImage2(Thread* t, OutputStream* bootimageOutput, OutputStream* codeOutp
|
||||
it.hasMore();)
|
||||
{
|
||||
bootClassTable[i++] = targetVW
|
||||
(heapWalker->map()->find(tripleSecond(t, it.next())));
|
||||
(heapWalker->map()->find(it.next()->second()));
|
||||
}
|
||||
}
|
||||
|
||||
@ -1588,7 +1588,7 @@ writeBootImage2(Thread* t, OutputStream* bootimageOutput, OutputStream* codeOutp
|
||||
it.hasMore();)
|
||||
{
|
||||
appClassTable[i++] = targetVW
|
||||
(heapWalker->map()->find(tripleSecond(t, it.next())));
|
||||
(heapWalker->map()->find(it.next()->second()));
|
||||
}
|
||||
}
|
||||
|
||||
@ -1600,7 +1600,7 @@ writeBootImage2(Thread* t, OutputStream* bootimageOutput, OutputStream* codeOutp
|
||||
for (HashMapIterator it(t, cast<GcHashMap>(t, root(t, Machine::StringMap))); it.hasMore();) {
|
||||
stringTable[i++] = targetVW
|
||||
(heapWalker->map()->find
|
||||
(jreferenceTarget(t, tripleFirst(t, it.next()))));
|
||||
(jreferenceTarget(t, it.next()->first())));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -105,13 +105,6 @@
|
||||
(object queueTarget)
|
||||
(object queueNext))
|
||||
|
||||
(type hashMap
|
||||
(uint32_t size)
|
||||
(object array))
|
||||
|
||||
(type weakHashMap
|
||||
(extends hashMap))
|
||||
|
||||
(type list
|
||||
(uint32_t size)
|
||||
(object front)
|
||||
@ -127,8 +120,8 @@
|
||||
|
||||
(type treeNode
|
||||
(object value)
|
||||
(object left)
|
||||
(object right))
|
||||
(treeNode left)
|
||||
(treeNode right))
|
||||
|
||||
(type callNode
|
||||
(intptr_t address)
|
||||
@ -142,6 +135,13 @@
|
||||
(type array
|
||||
(noassert array object body))
|
||||
|
||||
(type hashMap
|
||||
(uint32_t size)
|
||||
(field array array))
|
||||
|
||||
(type weakHashMap
|
||||
(extends hashMap))
|
||||
|
||||
(type pair
|
||||
(object first)
|
||||
(object second))
|
||||
|
272
src/util.cpp
272
src/util.cpp
@ -28,7 +28,7 @@ class TreeContext {
|
||||
v->visit(&(context->root));
|
||||
v->visit(&(context->node));
|
||||
|
||||
for (List<object>* p = context->ancestors; p; p = p->next) {
|
||||
for (List<GcTreeNode*>* p = context->ancestors; p; p = p->next) {
|
||||
v->visit(&(p->item));
|
||||
}
|
||||
}
|
||||
@ -42,44 +42,44 @@ class TreeContext {
|
||||
{ }
|
||||
|
||||
Zone* zone;
|
||||
object root;
|
||||
object node;
|
||||
List<object>* ancestors;
|
||||
GcTreeNode* root;
|
||||
GcTreeNode* node;
|
||||
List<GcTreeNode*>* ancestors;
|
||||
MyProtector protector;
|
||||
bool fresh;
|
||||
};
|
||||
|
||||
List<object>*
|
||||
path(TreeContext* c, object node, List<object>* next)
|
||||
List<GcTreeNode*>*
|
||||
path(TreeContext* c, GcTreeNode* node, List<GcTreeNode*>* next)
|
||||
{
|
||||
return new(c->zone) List<object>(node, next);
|
||||
return new(c->zone) List<GcTreeNode*>(node, next);
|
||||
}
|
||||
|
||||
inline object
|
||||
getTreeNodeValue(Thread*, object n)
|
||||
getTreeNodeValue(Thread*, GcTreeNode* n)
|
||||
{
|
||||
return reinterpret_cast<object>
|
||||
(alias(n, TreeNodeValue) & PointerMask);
|
||||
}
|
||||
|
||||
inline void
|
||||
setTreeNodeValue(Thread* t, object n, object value)
|
||||
setTreeNodeValue(Thread* t, GcTreeNode* n, object value)
|
||||
{
|
||||
intptr_t red = alias(n, TreeNodeValue) & (~PointerMask);
|
||||
|
||||
set(t, n, TreeNodeValue, value);
|
||||
set(t, reinterpret_cast<object>(n), TreeNodeValue, value);
|
||||
|
||||
alias(n, TreeNodeValue) |= red;
|
||||
}
|
||||
|
||||
inline bool
|
||||
treeNodeRed(Thread*, object n)
|
||||
treeNodeRed(Thread*, GcTreeNode* n)
|
||||
{
|
||||
return (alias(n, TreeNodeValue) & (~PointerMask)) == 1;
|
||||
}
|
||||
|
||||
inline void
|
||||
setTreeNodeRed(Thread*, object n, bool red)
|
||||
setTreeNodeRed(Thread*, GcTreeNode* n, bool red)
|
||||
{
|
||||
if (red) {
|
||||
alias(n, TreeNodeValue) |= 1;
|
||||
@ -88,28 +88,28 @@ setTreeNodeRed(Thread*, object n, bool red)
|
||||
}
|
||||
}
|
||||
|
||||
inline object
|
||||
cloneTreeNode(Thread* t, object n)
|
||||
inline GcTreeNode*
|
||||
cloneTreeNode(Thread* t, GcTreeNode* n)
|
||||
{
|
||||
PROTECT(t, n);
|
||||
|
||||
object newNode = reinterpret_cast<object>(makeTreeNode
|
||||
(t, getTreeNodeValue(t, n), treeNodeLeft(t, n), treeNodeRight(t, n)));
|
||||
GcTreeNode* newNode = makeTreeNode
|
||||
(t, getTreeNodeValue(t, n), n->left(), n->right());
|
||||
setTreeNodeRed(t, newNode, treeNodeRed(t, n));
|
||||
return newNode;
|
||||
}
|
||||
|
||||
object
|
||||
treeFind(Thread* t, object tree, intptr_t key, object sentinal,
|
||||
GcTreeNode*
|
||||
treeFind(Thread* t, GcTreeNode* tree, intptr_t key, GcTreeNode* sentinal,
|
||||
intptr_t (*compare)(Thread* t, intptr_t key, object b))
|
||||
{
|
||||
object node = tree;
|
||||
GcTreeNode* node = tree;
|
||||
while (node != sentinal) {
|
||||
intptr_t difference = compare(t, key, getTreeNodeValue(t, node));
|
||||
if (difference < 0) {
|
||||
node = treeNodeLeft(t, node);
|
||||
node = node->left();
|
||||
} else if (difference > 0) {
|
||||
node = treeNodeRight(t, node);
|
||||
node = node->right();
|
||||
} else {
|
||||
return node;
|
||||
}
|
||||
@ -119,18 +119,18 @@ treeFind(Thread* t, object tree, intptr_t key, object sentinal,
|
||||
}
|
||||
|
||||
void
|
||||
treeFind(Thread* t, TreeContext* c, object old, intptr_t key, object node,
|
||||
object sentinal,
|
||||
treeFind(Thread* t, TreeContext* c, GcTreeNode* old, intptr_t key, GcTreeNode* node,
|
||||
GcTreeNode* sentinal,
|
||||
intptr_t (*compare)(Thread* t, intptr_t key, object b))
|
||||
{
|
||||
PROTECT(t, old);
|
||||
PROTECT(t, node);
|
||||
PROTECT(t, sentinal);
|
||||
|
||||
object newRoot = cloneTreeNode(t, old);
|
||||
GcTreeNode* newRoot = cloneTreeNode(t, old);
|
||||
PROTECT(t, newRoot);
|
||||
|
||||
object new_ = newRoot;
|
||||
GcTreeNode* new_ = newRoot;
|
||||
PROTECT(t, new_);
|
||||
|
||||
int count = 0;
|
||||
@ -140,13 +140,13 @@ treeFind(Thread* t, TreeContext* c, object old, intptr_t key, object node,
|
||||
intptr_t difference = compare(t, key, getTreeNodeValue(t, old));
|
||||
|
||||
if (difference < 0) {
|
||||
old = treeNodeLeft(t, old);
|
||||
object n = cloneTreeNode(t, old);
|
||||
old = old->left();
|
||||
GcTreeNode* n = cloneTreeNode(t, old);
|
||||
set(t, new_, TreeNodeLeft, n);
|
||||
new_ = n;
|
||||
} else if (difference > 0) {
|
||||
old = treeNodeRight(t, old);
|
||||
object n = cloneTreeNode(t, old);
|
||||
old = old->right();
|
||||
GcTreeNode* n = cloneTreeNode(t, old);
|
||||
set(t, new_, TreeNodeRight, n);
|
||||
new_ = n;
|
||||
} else {
|
||||
@ -173,67 +173,67 @@ treeFind(Thread* t, TreeContext* c, object old, intptr_t key, object node,
|
||||
c->ancestors = c->ancestors;
|
||||
}
|
||||
|
||||
object
|
||||
leftRotate(Thread* t, object n)
|
||||
GcTreeNode*
|
||||
leftRotate(Thread* t, GcTreeNode* n)
|
||||
{
|
||||
PROTECT(t, n);
|
||||
|
||||
object child = cloneTreeNode(t, treeNodeRight(t, n));
|
||||
set(t, n, TreeNodeRight, treeNodeLeft(t, child));
|
||||
GcTreeNode* child = cloneTreeNode(t, n->right());
|
||||
set(t, n, TreeNodeRight, child->left());
|
||||
set(t, child, TreeNodeLeft, n);
|
||||
return child;
|
||||
}
|
||||
|
||||
object
|
||||
rightRotate(Thread* t, object n)
|
||||
GcTreeNode*
|
||||
rightRotate(Thread* t, GcTreeNode* n)
|
||||
{
|
||||
PROTECT(t, n);
|
||||
|
||||
object child = cloneTreeNode(t, treeNodeLeft(t, n));
|
||||
set(t, n, TreeNodeLeft, treeNodeRight(t, child));
|
||||
GcTreeNode* child = cloneTreeNode(t, n->left());
|
||||
set(t, n, TreeNodeLeft, child->right());
|
||||
set(t, child, TreeNodeRight, n);
|
||||
return child;
|
||||
}
|
||||
|
||||
object
|
||||
GcTreeNode*
|
||||
treeAdd(Thread* t, TreeContext* c)
|
||||
{
|
||||
object new_ = c->node;
|
||||
GcTreeNode* new_ = c->node;
|
||||
PROTECT(t, new_);
|
||||
|
||||
object newRoot = c->root;
|
||||
GcTreeNode* newRoot = c->root;
|
||||
PROTECT(t, newRoot);
|
||||
|
||||
// rebalance
|
||||
setTreeNodeRed(t, new_, true);
|
||||
while (c->ancestors != 0 and treeNodeRed(t, c->ancestors->item)) {
|
||||
if (c->ancestors->item
|
||||
== treeNodeLeft(t, c->ancestors->next->item))
|
||||
== c->ancestors->next->item->left())
|
||||
{
|
||||
if (treeNodeRed
|
||||
(t, treeNodeRight(t, c->ancestors->next->item)))
|
||||
(t, c->ancestors->next->item->right()))
|
||||
{
|
||||
setTreeNodeRed(t, c->ancestors->item, false);
|
||||
|
||||
object n = cloneTreeNode
|
||||
(t, treeNodeRight(t, c->ancestors->next->item));
|
||||
GcTreeNode* n = cloneTreeNode
|
||||
(t, c->ancestors->next->item->right());
|
||||
|
||||
set(t, c->ancestors->next->item, TreeNodeRight, n);
|
||||
|
||||
setTreeNodeRed(t, treeNodeRight(t, c->ancestors->next->item), false);
|
||||
setTreeNodeRed(t, c->ancestors->next->item->right(), false);
|
||||
|
||||
setTreeNodeRed(t, c->ancestors->next->item, true);
|
||||
|
||||
new_ = c->ancestors->next->item;
|
||||
c->ancestors = c->ancestors->next->next;
|
||||
} else {
|
||||
if (new_ == treeNodeRight(t, c->ancestors->item)) {
|
||||
if (new_ == c->ancestors->item->right()) {
|
||||
new_ = c->ancestors->item;
|
||||
c->ancestors = c->ancestors->next;
|
||||
|
||||
object n = leftRotate(t, new_);
|
||||
GcTreeNode* n = leftRotate(t, new_);
|
||||
|
||||
if (new_ == treeNodeRight(t, c->ancestors->item)) {
|
||||
if (new_ == c->ancestors->item->right()) {
|
||||
set(t, c->ancestors->item, TreeNodeRight, n);
|
||||
} else {
|
||||
set(t, c->ancestors->item, TreeNodeLeft, n);
|
||||
@ -243,10 +243,10 @@ treeAdd(Thread* t, TreeContext* c)
|
||||
setTreeNodeRed(t, c->ancestors->item, false);
|
||||
setTreeNodeRed(t, c->ancestors->next->item, true);
|
||||
|
||||
object n = rightRotate(t, c->ancestors->next->item);
|
||||
GcTreeNode* n = rightRotate(t, c->ancestors->next->item);
|
||||
if (c->ancestors->next->next == 0) {
|
||||
newRoot = n;
|
||||
} else if (treeNodeRight(t, c->ancestors->next->next->item)
|
||||
} else if (c->ancestors->next->next->item->right()
|
||||
== c->ancestors->next->item)
|
||||
{
|
||||
set(t, c->ancestors->next->next->item, TreeNodeRight, n);
|
||||
@ -258,29 +258,29 @@ treeAdd(Thread* t, TreeContext* c)
|
||||
} else { // this is just the reverse of the code above (right and
|
||||
// left swapped):
|
||||
if (treeNodeRed
|
||||
(t, treeNodeLeft(t, c->ancestors->next->item)))
|
||||
(t, c->ancestors->next->item->left()))
|
||||
{
|
||||
setTreeNodeRed(t, c->ancestors->item, false);
|
||||
|
||||
object n = cloneTreeNode
|
||||
(t, treeNodeLeft(t, c->ancestors->next->item));
|
||||
GcTreeNode* n = cloneTreeNode
|
||||
(t, c->ancestors->next->item->left());
|
||||
|
||||
set(t, c->ancestors->next->item, TreeNodeLeft, n);
|
||||
|
||||
setTreeNodeRed(t, treeNodeLeft(t, c->ancestors->next->item), false);
|
||||
setTreeNodeRed(t, c->ancestors->next->item->left(), false);
|
||||
|
||||
setTreeNodeRed(t, c->ancestors->next->item, true);
|
||||
|
||||
new_ = c->ancestors->next->item;
|
||||
c->ancestors = c->ancestors->next->next;
|
||||
} else {
|
||||
if (new_ == treeNodeLeft(t, c->ancestors->item)) {
|
||||
if (new_ == c->ancestors->item->left()) {
|
||||
new_ = c->ancestors->item;
|
||||
c->ancestors = c->ancestors->next;
|
||||
|
||||
object n = rightRotate(t, new_);
|
||||
GcTreeNode* n = rightRotate(t, new_);
|
||||
|
||||
if (new_ == treeNodeLeft(t, c->ancestors->item)) {
|
||||
if (new_ == c->ancestors->item->left()) {
|
||||
set(t, c->ancestors->item, TreeNodeLeft, n);
|
||||
} else {
|
||||
set(t, c->ancestors->item, TreeNodeRight, n);
|
||||
@ -290,10 +290,10 @@ treeAdd(Thread* t, TreeContext* c)
|
||||
setTreeNodeRed(t, c->ancestors->item, false);
|
||||
setTreeNodeRed(t, c->ancestors->next->item, true);
|
||||
|
||||
object n = leftRotate(t, c->ancestors->next->item);
|
||||
GcTreeNode* n = leftRotate(t, c->ancestors->next->item);
|
||||
if (c->ancestors->next->next == 0) {
|
||||
newRoot = n;
|
||||
} else if (treeNodeLeft(t, c->ancestors->next->next->item)
|
||||
} else if (c->ancestors->next->next->item->left()
|
||||
== c->ancestors->next->item)
|
||||
{
|
||||
set(t, c->ancestors->next->next->item, TreeNodeLeft, n);
|
||||
@ -314,20 +314,20 @@ treeAdd(Thread* t, TreeContext* c)
|
||||
|
||||
namespace vm {
|
||||
|
||||
object
|
||||
GcTriple*
|
||||
hashMapFindNode(Thread* t, GcHashMap* map, object key,
|
||||
uint32_t (*hash)(Thread*, object),
|
||||
bool (*equal)(Thread*, object, object))
|
||||
{
|
||||
bool weak = objectClass(t, map) == type(t, GcWeakHashMap::Type);
|
||||
|
||||
object array = map->array();
|
||||
GcArray* array = map->array();
|
||||
if (array) {
|
||||
unsigned index = hash(t, key) & (arrayLength(t, array) - 1);
|
||||
for (object n = arrayBody(t, array, index); n; n = tripleThird(t, n)) {
|
||||
object k = tripleFirst(t, n);
|
||||
unsigned index = hash(t, key) & (array->length() - 1);
|
||||
for (GcTriple* n = cast<GcTriple>(t, array->body()[index]); n; n = cast<GcTriple>(t, n->third())) {
|
||||
object k = n->first();
|
||||
if (weak) {
|
||||
k = jreferenceTarget(t, k);
|
||||
k = reinterpret_cast<object>(cast<GcJreference>(t, k)->target());
|
||||
if (k == 0) {
|
||||
continue;
|
||||
}
|
||||
@ -347,18 +347,18 @@ hashMapResize(Thread* t, GcHashMap* map, uint32_t (*hash)(Thread*, object),
|
||||
{
|
||||
PROTECT(t, map);
|
||||
|
||||
object newArray = 0;
|
||||
GcArray* newArray = 0;
|
||||
|
||||
if (size) {
|
||||
object oldArray = map->array();
|
||||
GcArray* oldArray = map->array();
|
||||
PROTECT(t, oldArray);
|
||||
|
||||
unsigned newLength = nextPowerOfTwo(size);
|
||||
if (oldArray and arrayLength(t, oldArray) == newLength) {
|
||||
if (oldArray and oldArray->length() == newLength) {
|
||||
return;
|
||||
}
|
||||
|
||||
newArray = reinterpret_cast<object>(makeArray(t, newLength));
|
||||
newArray = makeArray(t, newLength);
|
||||
|
||||
if (oldArray != map->array()) {
|
||||
// a resize was performed during a GC via the makeArray call
|
||||
@ -368,14 +368,14 @@ hashMapResize(Thread* t, GcHashMap* map, uint32_t (*hash)(Thread*, object),
|
||||
|
||||
if (oldArray) {
|
||||
bool weak = objectClass(t, map) == type(t, GcWeakHashMap::Type);
|
||||
for (unsigned i = 0; i < arrayLength(t, oldArray); ++i) {
|
||||
object next;
|
||||
for (object p = arrayBody(t, oldArray, i); p; p = next) {
|
||||
next = tripleThird(t, p);
|
||||
for (unsigned i = 0; i < oldArray->length(); ++i) {
|
||||
GcTriple* next;
|
||||
for (GcTriple* p = cast<GcTriple>(t, oldArray->body()[i]); p; p = next) {
|
||||
next = cast<GcTriple>(t, p->third());
|
||||
|
||||
object k = tripleFirst(t, p);
|
||||
object k = p->first();
|
||||
if (weak) {
|
||||
k = jreferenceTarget(t, k);
|
||||
k = reinterpret_cast<object>(cast<GcJreference>(t, k)->target());
|
||||
if (k == 0) {
|
||||
continue;
|
||||
}
|
||||
@ -383,14 +383,14 @@ hashMapResize(Thread* t, GcHashMap* map, uint32_t (*hash)(Thread*, object),
|
||||
|
||||
unsigned index = hash(t, k) & (newLength - 1);
|
||||
|
||||
set(t, p, TripleThird, arrayBody(t, newArray, index));
|
||||
set(t, reinterpret_cast<object>(p), TripleThird, newArray->body()[index]);
|
||||
set(t, newArray, ArrayBody + (index * BytesPerWord), p);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
set(t, reinterpret_cast<object>(map), HashMapArray, newArray);
|
||||
set(t, map, HashMapArray, newArray);
|
||||
}
|
||||
|
||||
void
|
||||
@ -407,15 +407,15 @@ hashMapInsert(Thread* t, GcHashMap* map, object key, object value,
|
||||
|
||||
bool weak = objectClass(t, map) == type(t, GcWeakHashMap::Type);
|
||||
|
||||
object array = map->array();
|
||||
GcArray* array = map->array();
|
||||
|
||||
++ map->size();
|
||||
|
||||
if (array == 0 or map->size() >= arrayLength(t, array) * 2) {
|
||||
if (array == 0 or map->size() >= array->length() * 2) {
|
||||
PROTECT(t, key);
|
||||
PROTECT(t, value);
|
||||
|
||||
hashMapResize(t, map, hash, array ? arrayLength(t, array) * 2 : 16);
|
||||
hashMapResize(t, map, hash, array ? array->length() * 2 : 16);
|
||||
|
||||
array = map->array();
|
||||
}
|
||||
@ -426,39 +426,39 @@ hashMapInsert(Thread* t, GcHashMap* map, object key, object value,
|
||||
PROTECT(t, key);
|
||||
PROTECT(t, value);
|
||||
|
||||
object r = reinterpret_cast<object>(makeWeakReference(t, 0, 0, 0, 0));
|
||||
jreferenceTarget(t, r) = key;
|
||||
jreferenceVmNext(t, r) = t->m->weakReferences;
|
||||
t->m->weakReferences = r;
|
||||
k = r;
|
||||
GcWeakReference* r = makeWeakReference(t, 0, 0, 0, 0);
|
||||
r->target() = key;
|
||||
r->vmNext() = t->m->weakReferences;
|
||||
t->m->weakReferences = reinterpret_cast<object>(r);
|
||||
k = reinterpret_cast<object>(r);
|
||||
|
||||
array = map->array();
|
||||
}
|
||||
|
||||
object n = reinterpret_cast<object>(makeTriple(t, k, value, 0));
|
||||
GcTriple* n = makeTriple(t, k, value, 0);
|
||||
|
||||
array = map->array();
|
||||
|
||||
unsigned index = h & (arrayLength(t, array) - 1);
|
||||
unsigned index = h & (array->length() - 1);
|
||||
|
||||
set(t, n, TripleThird, arrayBody(t, array, index));
|
||||
set(t, reinterpret_cast<object>(n), TripleThird, array->body()[index]);
|
||||
set(t, array, ArrayBody + (index * BytesPerWord), n);
|
||||
|
||||
if (map->size() <= arrayLength(t, array) / 3) {
|
||||
if (map->size() <= array->length() / 3) {
|
||||
// this might happen if nodes were removed during GC in which case
|
||||
// we weren't able to resize at the time
|
||||
hashMapResize(t, map, hash, arrayLength(t, array) / 2);
|
||||
hashMapResize(t, map, hash, array->length() / 2);
|
||||
}
|
||||
}
|
||||
|
||||
object
|
||||
hashMapRemoveNode(Thread* t, GcHashMap* map, unsigned index, object p, object n)
|
||||
GcTriple*
|
||||
hashMapRemoveNode(Thread* t, GcHashMap* map, unsigned index, object p, GcTriple* n)
|
||||
{
|
||||
if (p) {
|
||||
set(t, p, TripleThird, tripleThird(t, n));
|
||||
set(t, p, TripleThird, n->third());
|
||||
} else {
|
||||
set(t, map->array(), ArrayBody + (index * BytesPerWord),
|
||||
tripleThird(t, n));
|
||||
set(t, reinterpret_cast<object>(map->array()), ArrayBody + (index * BytesPerWord),
|
||||
n->third());
|
||||
}
|
||||
-- map->size();
|
||||
return n;
|
||||
@ -471,35 +471,35 @@ hashMapRemove(Thread* t, GcHashMap* map, object key,
|
||||
{
|
||||
bool weak = objectClass(t, map) == type(t, GcWeakHashMap::Type);
|
||||
|
||||
object array = map->array();
|
||||
GcArray* array = map->array();
|
||||
object o = 0;
|
||||
if (array) {
|
||||
unsigned index = hash(t, key) & (arrayLength(t, array) - 1);
|
||||
unsigned index = hash(t, key) & (array->length() - 1);
|
||||
object p = 0;
|
||||
for (object n = arrayBody(t, array, index); n;) {
|
||||
object k = tripleFirst(t, n);
|
||||
for (GcTriple* n = cast<GcTriple>(t, array->body()[index]); n;) {
|
||||
object k = n->first();
|
||||
if (weak) {
|
||||
k = jreferenceTarget(t, k);
|
||||
k = reinterpret_cast<object>(cast<GcJreference>(t, k)->target());
|
||||
if (k == 0) {
|
||||
n = tripleThird(t, hashMapRemoveNode(t, map, index, p, n));
|
||||
n = cast<GcTriple>(t, hashMapRemoveNode(t, map, index, p, n)->third());
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (equal(t, key, k)) {
|
||||
o = tripleSecond(t, hashMapRemoveNode(t, map, index, p, n));
|
||||
o = hashMapRemoveNode(t, map, index, p, n)->second();
|
||||
break;
|
||||
} else {
|
||||
p = n;
|
||||
n = tripleThird(t, n);
|
||||
p = reinterpret_cast<object>(n);
|
||||
n = cast<GcTriple>(t, n->third());
|
||||
}
|
||||
}
|
||||
|
||||
if ((not t->m->collecting)
|
||||
and map->size() <= arrayLength(t, array) / 3)
|
||||
and map->size() <= array->length() / 3)
|
||||
{
|
||||
PROTECT(t, o);
|
||||
hashMapResize(t, map, hash, arrayLength(t, array) / 2);
|
||||
hashMapResize(t, map, hash, array->length() / 2);
|
||||
}
|
||||
}
|
||||
|
||||
@ -507,78 +507,78 @@ hashMapRemove(Thread* t, GcHashMap* map, object key,
|
||||
}
|
||||
|
||||
void
|
||||
listAppend(Thread* t, object list, object value)
|
||||
listAppend(Thread* t, GcList* list, object value)
|
||||
{
|
||||
PROTECT(t, list);
|
||||
|
||||
++ listSize(t, list);
|
||||
++ list->size();
|
||||
|
||||
object p = reinterpret_cast<object>(makePair(t, value, 0));
|
||||
if (listFront(t, list)) {
|
||||
set(t, listRear(t, list), PairSecond, p);
|
||||
if (list->front()) {
|
||||
set(t, list->rear(), PairSecond, p);
|
||||
} else {
|
||||
set(t, list, ListFront, p);
|
||||
set(t, reinterpret_cast<object>(list), ListFront, p);
|
||||
}
|
||||
set(t, list, ListRear, p);
|
||||
set(t, reinterpret_cast<object>(list), ListRear, p);
|
||||
}
|
||||
|
||||
object
|
||||
vectorAppend(Thread* t, object vector, object value)
|
||||
GcVector*
|
||||
vectorAppend(Thread* t, GcVector* vector, object value)
|
||||
{
|
||||
if (vectorLength(t, vector) == vectorSize(t, vector)) {
|
||||
if (vector->length() == vector->size()) {
|
||||
PROTECT(t, vector);
|
||||
PROTECT(t, value);
|
||||
|
||||
object newVector = reinterpret_cast<object>(makeVector
|
||||
(t, vectorSize(t, vector), max(16, vectorSize(t, vector) * 2)));
|
||||
GcVector* newVector = makeVector
|
||||
(t, vector->size(), max(16, vector->size() * 2));
|
||||
|
||||
if (vectorSize(t, vector)) {
|
||||
memcpy(&vectorBody(t, newVector, 0),
|
||||
&vectorBody(t, vector, 0),
|
||||
vectorSize(t, vector) * BytesPerWord);
|
||||
if (vector->size()) {
|
||||
memcpy(newVector->body().begin(),
|
||||
vector->body().begin(),
|
||||
vector->size() * BytesPerWord);
|
||||
}
|
||||
|
||||
vector = newVector;
|
||||
}
|
||||
|
||||
set(t, vector, VectorBody + (vectorSize(t, vector) * BytesPerWord), value);
|
||||
++ vectorSize(t, vector);
|
||||
set(t, reinterpret_cast<object>(vector), VectorBody + (vector->size() * BytesPerWord), value);
|
||||
++ vector->size();
|
||||
return vector;
|
||||
}
|
||||
|
||||
object
|
||||
growArray(Thread* t, object array)
|
||||
GcArray*
|
||||
growArray(Thread* t, GcArray* array)
|
||||
{
|
||||
PROTECT(t, array);
|
||||
|
||||
object newArray = reinterpret_cast<object>(makeArray
|
||||
(t, array == 0 ? 16 : (arrayLength(t, array) * 2)));
|
||||
GcArray* newArray = makeArray
|
||||
(t, array == 0 ? 16 : (array->length() * 2));
|
||||
|
||||
if (array) {
|
||||
memcpy(&arrayBody(t, newArray, 0), &arrayBody(t, array, 0),
|
||||
arrayLength(t, array));
|
||||
memcpy(newArray->body().begin(), array->body().begin(),
|
||||
array->length());
|
||||
}
|
||||
|
||||
return newArray;
|
||||
}
|
||||
|
||||
object
|
||||
treeQuery(Thread* t, object tree, intptr_t key, object sentinal,
|
||||
treeQuery(Thread* t, GcTreeNode* tree, intptr_t key, GcTreeNode* sentinal,
|
||||
intptr_t (*compare)(Thread* t, intptr_t key, object b))
|
||||
{
|
||||
object node = treeFind(t, tree, key, sentinal, compare);
|
||||
GcTreeNode* node = treeFind(t, tree, key, sentinal, compare);
|
||||
return (node ? getTreeNodeValue(t, node) : 0);
|
||||
}
|
||||
|
||||
object
|
||||
treeInsert(Thread* t, Zone* zone, object tree, intptr_t key, object value,
|
||||
object sentinal,
|
||||
GcTreeNode*
|
||||
treeInsert(Thread* t, Zone* zone, GcTreeNode* tree, intptr_t key, object value,
|
||||
GcTreeNode* sentinal,
|
||||
intptr_t (*compare)(Thread* t, intptr_t key, object b))
|
||||
{
|
||||
PROTECT(t, tree);
|
||||
PROTECT(t, sentinal);
|
||||
|
||||
object node = reinterpret_cast<object>(makeTreeNode(t, value, sentinal, sentinal));
|
||||
GcTreeNode* node = makeTreeNode(t, value, sentinal, sentinal);
|
||||
|
||||
TreeContext c(t, zone);
|
||||
treeFind(t, &c, tree, key, node, sentinal, compare);
|
||||
@ -588,7 +588,7 @@ treeInsert(Thread* t, Zone* zone, object tree, intptr_t key, object value,
|
||||
}
|
||||
|
||||
void
|
||||
treeUpdate(Thread* t, object tree, intptr_t key, object value, object sentinal,
|
||||
treeUpdate(Thread* t, GcTreeNode* tree, intptr_t key, object value, GcTreeNode* sentinal,
|
||||
intptr_t (*compare)(Thread* t, intptr_t key, object b))
|
||||
{
|
||||
setTreeNodeValue(t, treeFind(t, tree, key, sentinal, compare), value);
|
||||
|
Loading…
Reference in New Issue
Block a user