consolidate many implicit list types into one

This commit is contained in:
Joshua Warner 2013-12-10 21:36:55 -07:00 committed by Joshua Warner
parent 2cb606babd
commit 06432253ba
11 changed files with 169 additions and 178 deletions

35
include/avian/util/list.h Normal file
View File

@ -0,0 +1,35 @@
/* Copyright (c) 2008-2013, Avian Contributors
Permission to use, copy, modify, and/or distribute this software
for any purpose with or without fee is hereby granted, provided
that the above copyright notice and this permission notice appear
in all copies.
There is NO WARRANTY for this software. See license.txt for
details. */
#ifndef AVIAN_UTIL_LIST_H
#define AVIAN_UTIL_LIST_H
template <class T>
class List {
public:
List(const T& item, List<T>* next):
item(item),
next(next) {}
unsigned count() {
unsigned count = 0;
List<T>* c = this;
while (c) {
++ count;
c = c->next;
}
return count;
}
T item;
List<T>* next;
};
#endif // AVIAN_UTIL_LIST_H

View File

@ -1634,8 +1634,8 @@ captureBranchSnapshots(Context* c, Event* e)
e->snapshots = makeSnapshots(c, el.value, e->snapshots);
}
for (Cell<Value>* sv = e->successors->forkState->saved; sv; sv = sv->next) {
e->snapshots = makeSnapshots(c, sv->value, e->snapshots);
for (List<Value*>* sv = e->successors->forkState->saved; sv; sv = sv->next) {
e->snapshots = makeSnapshots(c, sv->item, e->snapshots);
}
if (DebugControl) {
@ -1925,8 +1925,8 @@ compile(Context* c, uintptr_t stackOverflowHandler, unsigned stackLimitOffset)
}
if (e->visitLinks) {
for (Cell<Link>* cell = reverseDestroy(e->visitLinks); cell; cell = cell->next) {
visit(c, cell->value);
for (List<Link*>* cell = reverseDestroy(e->visitLinks); cell; cell = cell->next) {
visit(c, cell->item);
}
e->visitLinks = 0;
}
@ -1997,7 +1997,7 @@ saveState(Context* c)
appendDummy(c);
}
unsigned elementCount = frameFootprint(c, c->stack) + count(c->saved);
unsigned elementCount = frameFootprint(c, c->stack) + c->saved->count();
ForkState* state = new
(c->zone->allocate
@ -2014,8 +2014,8 @@ saveState(Context* c)
addForkElement(c, e.value, state, count++);
}
for (Cell<Value>* sv = c->saved; sv; sv = sv->next) {
addForkElement(c, sv->value, state, count++);
for (List<Value*>* sv = c->saved; sv; sv = sv->next) {
addForkElement(c, sv->item, state, count++);
}
state->readCount = count;

View File

@ -13,6 +13,7 @@
#include <avian/vm/codegen/assembler.h>
#include <avian/vm/codegen/compiler.h>
#include <avian/util/list.h>
#include "regalloc.h"
@ -38,29 +39,10 @@ class MySubroutine;
class Block;
template<class T>
class Cell {
public:
Cell(Cell<T>* next, T* value): next(next), value(value) { }
Cell<T>* next;
T* value;
};
template<class T>
unsigned count(Cell<T>* c) {
unsigned count = 0;
while (c) {
++ count;
c = c->next;
}
return count;
}
template<class T>
Cell<T>* reverseDestroy(Cell<T>* cell) {
Cell<T>* previous = 0;
List<T>* reverseDestroy(List<T>* cell) {
List<T>* previous = 0;
while (cell) {
Cell<T>* next = cell->next;
List<T>* next = cell->next;
cell->next = previous;
previous = cell;
cell = next;
@ -80,7 +62,7 @@ class Context {
Compiler::Client* client;
Stack* stack;
Local* locals;
Cell<Value>* saved;
List<Value*>* saved;
Event* predecessor;
LogicalInstruction** logicalCode;
const RegisterFile* regFile;
@ -111,8 +93,8 @@ inline Aborter* getAborter(Context* c) {
}
template<class T>
Cell<T>* cons(Context* c, T* value, Cell<T>* next) {
return new (c->zone) Cell<T>(next, value);
List<T>* cons(Context* c, const T& value, List<T>* next) {
return new (c->zone) List<T>(value, next);
}
} // namespace compiler

View File

@ -68,7 +68,7 @@ class Event {
Snapshot* snapshots;
Link* predecessors;
Link* successors;
Cell<Link>* visitLinks;
List<Link*>* visitLinks;
Block* block;
LogicalInstruction* logicalInstruction;
unsigned readCount;

View File

@ -26,7 +26,7 @@ class ForkElement {
class ForkState: public Compiler::State {
public:
ForkState(Stack* stack, Local* locals, Cell<Value>* saved, Event* predecessor,
ForkState(Stack* stack, Local* locals, List<Value*>* saved, Event* predecessor,
unsigned logicalIp):
stack(stack),
locals(locals),
@ -38,7 +38,7 @@ class ForkState: public Compiler::State {
Stack* stack;
Local* locals;
Cell<Value>* saved;
List<Value*>* saved;
Event* predecessor;
unsigned logicalIp;
unsigned readCount;

View File

@ -66,8 +66,8 @@ bool MultiRead::intersect(SiteMask* mask, unsigned depth) {
bool result = false;
if (not visited) {
visited = true;
for (Cell<Read>** cell = &reads; *cell;) {
Read* r = (*cell)->value;
for (List<Read*>** cell = &reads; *cell;) {
Read* r = (*cell)->item;
bool valid = r->intersect(mask, depth + 1);
if (valid) {
result = true;
@ -89,8 +89,8 @@ bool MultiRead::valid() {
bool result = false;
if (not visited) {
visited = true;
for (Cell<Read>** cell = &reads; *cell;) {
Read* r = (*cell)->value;
for (List<Read*>** cell = &reads; *cell;) {
Read* r = (*cell)->item;
if (r->valid()) {
result = true;
cell = &((*cell)->next);
@ -104,7 +104,7 @@ bool MultiRead::valid() {
}
void MultiRead::append(Context* c, Read* r) {
Cell<Read>* cell = cons<Read>(c, r, 0);
List<Read*>* cell = cons<Read*>(c, r, 0);
if (lastRead == 0) {
reads = cell;
} else {
@ -114,7 +114,7 @@ void MultiRead::append(Context* c, Read* r) {
// fprintf(stderr, "append %p to %p for %p\n", r, lastTarget, this);
lastTarget->value = r;
lastTarget->item = r;
}
Read* MultiRead::next(Context* c) {
@ -122,7 +122,7 @@ Read* MultiRead::next(Context* c) {
}
void MultiRead::allocateTarget(Context* c) {
Cell<Read>* cell = cons<Read>(c, 0, 0);
List<Read*>* cell = cons<Read*>(c, 0, 0);
// fprintf(stderr, "allocate target for %p: %p\n", this, cell);
@ -137,7 +137,7 @@ void MultiRead::allocateTarget(Context* c) {
Read* MultiRead::nextTarget() {
// fprintf(stderr, "next target for %p: %p\n", this, firstTarget);
Read* r = firstTarget->value;
Read* r = firstTarget->item;
firstTarget = firstTarget->next;
return r;
}

View File

@ -88,10 +88,10 @@ class MultiRead: public Read {
Read* nextTarget();
Cell<Read>* reads;
Cell<Read>* lastRead;
Cell<Read>* firstTarget;
Cell<Read>* lastTarget;
List<Read*>* reads;
List<Read*>* lastRead;
List<Read*>* firstTarget;
List<Read*>* lastTarget;
bool visited;
};

View File

@ -21,6 +21,7 @@
#include <avian/vm/codegen/targets.h>
#include <avian/util/runtime-array.h>
#include <avian/util/list.h>
using namespace vm;
@ -211,17 +212,6 @@ class MyThread: public Thread {
bool methodIsMostRecent;
};
class ReferenceFrame {
public:
ReferenceFrame(ReferenceFrame* next, Reference* reference):
next(next),
reference(reference)
{ }
ReferenceFrame* next;
Reference* reference;
};
static void doTransition(MyThread* t, void* ip, void* stack,
object continuation, MyThread::CallTrace* trace)
{
@ -301,7 +291,7 @@ class MyThread: public Thread {
Context* transition;
TraceContext* traceContext;
uintptr_t stackLimit;
ReferenceFrame* referenceFrame;
List<Reference*>* referenceFrame;
bool methodLockIsClean;
};
@ -9061,8 +9051,8 @@ class MyProcessor: public Processor {
MyThread* t = static_cast<MyThread*>(vmt);
t->referenceFrame = new
(t->m->heap->allocate(sizeof(MyThread::ReferenceFrame)))
MyThread::ReferenceFrame(t->referenceFrame, t->reference);
(t->m->heap->allocate(sizeof(List<Reference*>)))
List<Reference*>(t->reference, t->referenceFrame);
return true;
}
@ -9072,13 +9062,13 @@ class MyProcessor: public Processor {
{
MyThread* t = static_cast<MyThread*>(vmt);
MyThread::ReferenceFrame* f = t->referenceFrame;
List<Reference*>* f = t->referenceFrame;
t->referenceFrame = f->next;
while (t->reference != f->reference) {
while (t->reference != f->item) {
vm::dispose(t, t->reference);
}
t->m->heap->free(f, sizeof(MyThread::ReferenceFrame));
t->m->heap->free(f, sizeof(List<Reference*>));
}
virtual object

View File

@ -11,6 +11,7 @@
#include <avian/vm/system/system.h>
#include <avian/util/string.h>
#include <avian/util/runtime-array.h>
#include <avian/util/list.h>
#include "avian/zlib-custom.h"
#include "avian/finder.h"
@ -241,15 +242,14 @@ class JarIndex {
Deflated = 8
};
class Node {
public:
Node(uint32_t hash, const uint8_t* entry, Node* next):
hash(hash), entry(entry), next(next)
{ }
class Entry {
public:
Entry(uint32_t hash, const uint8_t* entry):
hash(hash),
entry(entry) {}
uint32_t hash;
const uint8_t* entry;
Node* next;
};
JarIndex(System* s, Allocator* allocator, unsigned capacity):
@ -257,14 +257,14 @@ class JarIndex {
allocator(allocator),
capacity(capacity),
position(0),
nodes(static_cast<Node*>(allocator->allocate(sizeof(Node) * capacity)))
nodes(static_cast<List<Entry>*>(allocator->allocate(sizeof(List<Entry>) * capacity)))
{
memset(table, 0, sizeof(Node*) * capacity);
memset(table, 0, sizeof(List<Entry>*) * capacity);
}
static JarIndex* make(System* s, Allocator* allocator, unsigned capacity) {
return new
(allocator->allocate(sizeof(JarIndex) + (sizeof(Node*) * capacity)))
(allocator->allocate(sizeof(JarIndex) + (sizeof(List<Entry>*) * capacity)))
JarIndex(s, allocator, capacity);
}
@ -279,46 +279,46 @@ class JarIndex {
// Find end of central directory record
while (p > start) {
if (signature(p) == CentralDirectorySignature) {
p = region->start() + centralDirectoryOffset(p);
while (p < end) {
if (signature(p) == EntrySignature) {
index = index->add(hash(fileName(p), fileNameLength(p)), p);
p = region->start() + centralDirectoryOffset(p);
p = endOfEntry(p);
} else {
return index;
}
}
while (p < end) {
if (signature(p) == EntrySignature) {
index = index->add(Entry(hash(fileName(p), fileNameLength(p)), p));
p = endOfEntry(p);
} else {
return index;
}
}
} else {
p--;
p--;
}
}
return index;
}
JarIndex* add(uint32_t hash, const uint8_t* entry) {
JarIndex* add(const Entry& entry) {
if (position < capacity) {
unsigned i = hash & (capacity - 1);
table[i] = new (nodes + (position++)) Node(hash, entry, table[i]);
unsigned i = entry.hash & (capacity - 1);
table[i] = new (nodes + (position++)) List<Entry>(entry, table[i]);
return this;
} else {
JarIndex* index = make(s, allocator, capacity * 2);
for (unsigned i = 0; i < capacity; ++i) {
index->add(nodes[i].hash, nodes[i].entry);
index->add(nodes[i].item);
}
index->add(hash, entry);
index->add(entry);
dispose();
return index;
}
}
Node* findNode(const char* name) {
List<Entry>* findNode(const char* name) {
unsigned length = strlen(name);
unsigned i = hash(name) & (capacity - 1);
for (Node* n = table[i]; n; n = n->next) {
const uint8_t* p = n->entry;
for (List<Entry>* n = table[i]; n; n = n->next) {
const uint8_t* p = n->item.entry;
if (equal(name, length, fileName(p), fileNameLength(p))) {
return n;
}
@ -327,14 +327,14 @@ class JarIndex {
}
System::Region* find(const char* name, const uint8_t* start) {
Node* n = findNode(name);
List<Entry>* n = findNode(name);
if (n) {
const uint8_t* p = n->entry;
const uint8_t* p = n->item.entry;
switch (compressionMethod(p)) {
case Stored: {
return new (allocator->allocate(sizeof(PointerRegion)))
PointerRegion(s, allocator, fileData(start + localHeaderOffset(p)),
compressedSize(p));
compressedSize(p));
} break;
case Deflated: {
@ -345,7 +345,7 @@ class JarIndex {
z_stream zStream; memset(&zStream, 0, sizeof(z_stream));
zStream.next_in = const_cast<uint8_t*>(fileData(start +
localHeaderOffset(p)));
localHeaderOffset(p)));
zStream.avail_in = compressedSize(p);
zStream.next_out = region->data;
zStream.avail_out = region->length();
@ -372,9 +372,9 @@ class JarIndex {
System::FileType stat(const char* name, unsigned* length, bool tryDirectory)
{
Node* node = findNode(name);
List<Entry>* node = findNode(name);
if (node) {
*length = uncompressedSize(node->entry);
*length = uncompressedSize(node->item.entry);
return System::TypeFile;
} else if (tryDirectory) {
*length = 0;
@ -399,8 +399,8 @@ class JarIndex {
}
void dispose() {
allocator->free(nodes, sizeof(Node) * capacity);
allocator->free(this, sizeof(*this) + (sizeof(Node*) * capacity));
allocator->free(nodes, sizeof(List<Entry>) * capacity);
allocator->free(this, sizeof(*this) + (sizeof(List<Entry>*) * capacity));
}
System* s;
@ -408,8 +408,8 @@ class JarIndex {
unsigned capacity;
unsigned position;
Node* nodes;
Node* table[0];
List<Entry>* nodes;
List<Entry>* table[0];
};
class JarElement: public Element {
@ -422,9 +422,9 @@ class JarElement: public Element {
virtual const char* next(unsigned* size) {
if (position < index->position) {
JarIndex::Node* n = index->nodes + (position++);
*size = fileNameLength(n->entry);
return reinterpret_cast<const char*>(fileName(n->entry));
List<JarIndex::Entry>* n = index->nodes + (position++);
*size = fileNameLength(n->item.entry);
return reinterpret_cast<const char*>(fileName(n->item.entry));
} else {
return 0;
}

View File

@ -17,6 +17,7 @@
#include "avian/arch.h"
#include <avian/util/runtime-array.h>
#include <avian/util/list.h>
using namespace vm;
@ -30,16 +31,6 @@ const unsigned FrameFootprint = 4;
class Thread: public vm::Thread {
public:
class ReferenceFrame {
public:
ReferenceFrame(ReferenceFrame* next, unsigned sp):
next(next),
sp(sp)
{ }
ReferenceFrame* next;
unsigned sp;
};
Thread(Machine* m, object javaThread, vm::Thread* parent):
vm::Thread(m, javaThread, parent),
@ -47,14 +38,14 @@ class Thread: public vm::Thread {
sp(0),
frame(-1),
code(0),
referenceFrame(0)
stackPointers(0)
{ }
unsigned ip;
unsigned sp;
int frame;
object code;
ReferenceFrame* referenceFrame;
List<unsigned>* stackPointers;
uintptr_t stack[0];
};
@ -3079,9 +3070,8 @@ class MyProcessor: public Processor {
Thread* t = static_cast<Thread*>(vmt);
if (t->sp + capacity < stackSizeInWords(t) / 2) {
t->referenceFrame = new
(t->m->heap->allocate(sizeof(Thread::ReferenceFrame)))
Thread::ReferenceFrame(t->referenceFrame, t->sp);
t->stackPointers = new(t->m->heap)
List<unsigned>(t->sp, t->stackPointers);
return true;
} else {
@ -3094,11 +3084,11 @@ class MyProcessor: public Processor {
{
Thread* t = static_cast<Thread*>(vmt);
Thread::ReferenceFrame* f = t->referenceFrame;
t->referenceFrame = f->next;
t->sp = f->sp;
List<unsigned>* f = t->stackPointers;
t->stackPointers = f->next;
t->sp = f->item;
t->m->heap->free(f, sizeof(Thread::ReferenceFrame));
t->m->heap->free(f, sizeof(List<unsigned>));
}
virtual object

View File

@ -9,6 +9,7 @@
details. */
#include "avian/util.h"
#include <avian/util/list.h>
using namespace vm;
@ -16,13 +17,6 @@ namespace {
class TreeContext {
public:
class Path {
public:
Path(object node, Path* next): node(node), next(next) { }
object node;
Path* next;
};
class MyProtector: public Thread::Protector {
public:
@ -34,8 +28,8 @@ class TreeContext {
v->visit(&(context->root));
v->visit(&(context->node));
for (Path* p = context->ancestors; p; p = p->next) {
v->visit(&(p->node));
for (List<object>* p = context->ancestors; p; p = p->next) {
v->visit(&(p->item));
}
}
@ -50,15 +44,15 @@ class TreeContext {
Zone* zone;
object root;
object node;
Path* ancestors;
List<object>* ancestors;
MyProtector protector;
bool fresh;
};
TreeContext::Path*
path(TreeContext* c, object node, TreeContext::Path* next)
List<object>*
path(TreeContext* c, object node, List<object>* next)
{
return new(c->zone) TreeContext::Path(node, next);
return new(c->zone) List<object>(node, next);
}
inline object
@ -212,99 +206,99 @@ treeAdd(Thread* t, TreeContext* c)
// rebalance
setTreeNodeRed(t, new_, true);
while (c->ancestors != 0 and treeNodeRed(t, c->ancestors->node)) {
if (c->ancestors->node
== treeNodeLeft(t, c->ancestors->next->node))
while (c->ancestors != 0 and treeNodeRed(t, c->ancestors->item)) {
if (c->ancestors->item
== treeNodeLeft(t, c->ancestors->next->item))
{
if (treeNodeRed
(t, treeNodeRight(t, c->ancestors->next->node)))
(t, treeNodeRight(t, c->ancestors->next->item)))
{
setTreeNodeRed(t, c->ancestors->node, false);
setTreeNodeRed(t, c->ancestors->item, false);
object n = cloneTreeNode
(t, treeNodeRight(t, c->ancestors->next->node));
(t, treeNodeRight(t, c->ancestors->next->item));
set(t, c->ancestors->next->node, TreeNodeRight, n);
set(t, c->ancestors->next->item, TreeNodeRight, n);
setTreeNodeRed(t, treeNodeRight(t, c->ancestors->next->node), false);
setTreeNodeRed(t, treeNodeRight(t, c->ancestors->next->item), false);
setTreeNodeRed(t, c->ancestors->next->node, true);
setTreeNodeRed(t, c->ancestors->next->item, true);
new_ = c->ancestors->next->node;
new_ = c->ancestors->next->item;
c->ancestors = c->ancestors->next->next;
} else {
if (new_ == treeNodeRight(t, c->ancestors->node)) {
new_ = c->ancestors->node;
if (new_ == treeNodeRight(t, c->ancestors->item)) {
new_ = c->ancestors->item;
c->ancestors = c->ancestors->next;
object n = leftRotate(t, new_);
if (new_ == treeNodeRight(t, c->ancestors->node)) {
set(t, c->ancestors->node, TreeNodeRight, n);
if (new_ == treeNodeRight(t, c->ancestors->item)) {
set(t, c->ancestors->item, TreeNodeRight, n);
} else {
set(t, c->ancestors->node, TreeNodeLeft, n);
set(t, c->ancestors->item, TreeNodeLeft, n);
}
c->ancestors = path(c, n, c->ancestors);
}
setTreeNodeRed(t, c->ancestors->node, false);
setTreeNodeRed(t, c->ancestors->next->node, true);
setTreeNodeRed(t, c->ancestors->item, false);
setTreeNodeRed(t, c->ancestors->next->item, true);
object n = rightRotate(t, c->ancestors->next->node);
object n = rightRotate(t, c->ancestors->next->item);
if (c->ancestors->next->next == 0) {
newRoot = n;
} else if (treeNodeRight(t, c->ancestors->next->next->node)
== c->ancestors->next->node)
} else if (treeNodeRight(t, c->ancestors->next->next->item)
== c->ancestors->next->item)
{
set(t, c->ancestors->next->next->node, TreeNodeRight, n);
set(t, c->ancestors->next->next->item, TreeNodeRight, n);
} else {
set(t, c->ancestors->next->next->node, TreeNodeLeft, n);
set(t, c->ancestors->next->next->item, TreeNodeLeft, n);
}
// done
}
} else { // this is just the reverse of the code above (right and
// left swapped):
if (treeNodeRed
(t, treeNodeLeft(t, c->ancestors->next->node)))
(t, treeNodeLeft(t, c->ancestors->next->item)))
{
setTreeNodeRed(t, c->ancestors->node, false);
setTreeNodeRed(t, c->ancestors->item, false);
object n = cloneTreeNode
(t, treeNodeLeft(t, c->ancestors->next->node));
(t, treeNodeLeft(t, c->ancestors->next->item));
set(t, c->ancestors->next->node, TreeNodeLeft, n);
set(t, c->ancestors->next->item, TreeNodeLeft, n);
setTreeNodeRed(t, treeNodeLeft(t, c->ancestors->next->node), false);
setTreeNodeRed(t, treeNodeLeft(t, c->ancestors->next->item), false);
setTreeNodeRed(t, c->ancestors->next->node, true);
setTreeNodeRed(t, c->ancestors->next->item, true);
new_ = c->ancestors->next->node;
new_ = c->ancestors->next->item;
c->ancestors = c->ancestors->next->next;
} else {
if (new_ == treeNodeLeft(t, c->ancestors->node)) {
new_ = c->ancestors->node;
if (new_ == treeNodeLeft(t, c->ancestors->item)) {
new_ = c->ancestors->item;
c->ancestors = c->ancestors->next;
object n = rightRotate(t, new_);
if (new_ == treeNodeLeft(t, c->ancestors->node)) {
set(t, c->ancestors->node, TreeNodeLeft, n);
if (new_ == treeNodeLeft(t, c->ancestors->item)) {
set(t, c->ancestors->item, TreeNodeLeft, n);
} else {
set(t, c->ancestors->node, TreeNodeRight, n);
set(t, c->ancestors->item, TreeNodeRight, n);
}
c->ancestors = path(c, n, c->ancestors);
}
setTreeNodeRed(t, c->ancestors->node, false);
setTreeNodeRed(t, c->ancestors->next->node, true);
setTreeNodeRed(t, c->ancestors->item, false);
setTreeNodeRed(t, c->ancestors->next->item, true);
object n = leftRotate(t, c->ancestors->next->node);
object n = leftRotate(t, c->ancestors->next->item);
if (c->ancestors->next->next == 0) {
newRoot = n;
} else if (treeNodeLeft(t, c->ancestors->next->next->node)
== c->ancestors->next->node)
} else if (treeNodeLeft(t, c->ancestors->next->next->item)
== c->ancestors->next->item)
{
set(t, c->ancestors->next->next->node, TreeNodeLeft, n);
set(t, c->ancestors->next->next->item, TreeNodeLeft, n);
} else {
set(t, c->ancestors->next->next->node, TreeNodeRight, n);
set(t, c->ancestors->next->next->item, TreeNodeRight, n);
}
// done
}