mirror of
https://github.com/corda/corda.git
synced 2025-01-07 13:38:47 +00:00
consolidate many implicit list types into one
This commit is contained in:
parent
2cb606babd
commit
06432253ba
35
include/avian/util/list.h
Normal file
35
include/avian/util/list.h
Normal 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
|
@ -1634,8 +1634,8 @@ captureBranchSnapshots(Context* c, Event* e)
|
|||||||
e->snapshots = makeSnapshots(c, el.value, e->snapshots);
|
e->snapshots = makeSnapshots(c, el.value, e->snapshots);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (Cell<Value>* sv = e->successors->forkState->saved; sv; sv = sv->next) {
|
for (List<Value*>* sv = e->successors->forkState->saved; sv; sv = sv->next) {
|
||||||
e->snapshots = makeSnapshots(c, sv->value, e->snapshots);
|
e->snapshots = makeSnapshots(c, sv->item, e->snapshots);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (DebugControl) {
|
if (DebugControl) {
|
||||||
@ -1925,8 +1925,8 @@ compile(Context* c, uintptr_t stackOverflowHandler, unsigned stackLimitOffset)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (e->visitLinks) {
|
if (e->visitLinks) {
|
||||||
for (Cell<Link>* cell = reverseDestroy(e->visitLinks); cell; cell = cell->next) {
|
for (List<Link*>* cell = reverseDestroy(e->visitLinks); cell; cell = cell->next) {
|
||||||
visit(c, cell->value);
|
visit(c, cell->item);
|
||||||
}
|
}
|
||||||
e->visitLinks = 0;
|
e->visitLinks = 0;
|
||||||
}
|
}
|
||||||
@ -1997,7 +1997,7 @@ saveState(Context* c)
|
|||||||
appendDummy(c);
|
appendDummy(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned elementCount = frameFootprint(c, c->stack) + count(c->saved);
|
unsigned elementCount = frameFootprint(c, c->stack) + c->saved->count();
|
||||||
|
|
||||||
ForkState* state = new
|
ForkState* state = new
|
||||||
(c->zone->allocate
|
(c->zone->allocate
|
||||||
@ -2014,8 +2014,8 @@ saveState(Context* c)
|
|||||||
addForkElement(c, e.value, state, count++);
|
addForkElement(c, e.value, state, count++);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (Cell<Value>* sv = c->saved; sv; sv = sv->next) {
|
for (List<Value*>* sv = c->saved; sv; sv = sv->next) {
|
||||||
addForkElement(c, sv->value, state, count++);
|
addForkElement(c, sv->item, state, count++);
|
||||||
}
|
}
|
||||||
|
|
||||||
state->readCount = count;
|
state->readCount = count;
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
|
|
||||||
#include <avian/vm/codegen/assembler.h>
|
#include <avian/vm/codegen/assembler.h>
|
||||||
#include <avian/vm/codegen/compiler.h>
|
#include <avian/vm/codegen/compiler.h>
|
||||||
|
#include <avian/util/list.h>
|
||||||
|
|
||||||
#include "regalloc.h"
|
#include "regalloc.h"
|
||||||
|
|
||||||
@ -38,29 +39,10 @@ class MySubroutine;
|
|||||||
class Block;
|
class Block;
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
class Cell {
|
List<T>* reverseDestroy(List<T>* cell) {
|
||||||
public:
|
List<T>* previous = 0;
|
||||||
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;
|
|
||||||
while (cell) {
|
while (cell) {
|
||||||
Cell<T>* next = cell->next;
|
List<T>* next = cell->next;
|
||||||
cell->next = previous;
|
cell->next = previous;
|
||||||
previous = cell;
|
previous = cell;
|
||||||
cell = next;
|
cell = next;
|
||||||
@ -80,7 +62,7 @@ class Context {
|
|||||||
Compiler::Client* client;
|
Compiler::Client* client;
|
||||||
Stack* stack;
|
Stack* stack;
|
||||||
Local* locals;
|
Local* locals;
|
||||||
Cell<Value>* saved;
|
List<Value*>* saved;
|
||||||
Event* predecessor;
|
Event* predecessor;
|
||||||
LogicalInstruction** logicalCode;
|
LogicalInstruction** logicalCode;
|
||||||
const RegisterFile* regFile;
|
const RegisterFile* regFile;
|
||||||
@ -111,8 +93,8 @@ inline Aborter* getAborter(Context* c) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
Cell<T>* cons(Context* c, T* value, Cell<T>* next) {
|
List<T>* cons(Context* c, const T& value, List<T>* next) {
|
||||||
return new (c->zone) Cell<T>(next, value);
|
return new (c->zone) List<T>(value, next);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace compiler
|
} // namespace compiler
|
||||||
|
@ -68,7 +68,7 @@ class Event {
|
|||||||
Snapshot* snapshots;
|
Snapshot* snapshots;
|
||||||
Link* predecessors;
|
Link* predecessors;
|
||||||
Link* successors;
|
Link* successors;
|
||||||
Cell<Link>* visitLinks;
|
List<Link*>* visitLinks;
|
||||||
Block* block;
|
Block* block;
|
||||||
LogicalInstruction* logicalInstruction;
|
LogicalInstruction* logicalInstruction;
|
||||||
unsigned readCount;
|
unsigned readCount;
|
||||||
|
@ -26,7 +26,7 @@ class ForkElement {
|
|||||||
|
|
||||||
class ForkState: public Compiler::State {
|
class ForkState: public Compiler::State {
|
||||||
public:
|
public:
|
||||||
ForkState(Stack* stack, Local* locals, Cell<Value>* saved, Event* predecessor,
|
ForkState(Stack* stack, Local* locals, List<Value*>* saved, Event* predecessor,
|
||||||
unsigned logicalIp):
|
unsigned logicalIp):
|
||||||
stack(stack),
|
stack(stack),
|
||||||
locals(locals),
|
locals(locals),
|
||||||
@ -38,7 +38,7 @@ class ForkState: public Compiler::State {
|
|||||||
|
|
||||||
Stack* stack;
|
Stack* stack;
|
||||||
Local* locals;
|
Local* locals;
|
||||||
Cell<Value>* saved;
|
List<Value*>* saved;
|
||||||
Event* predecessor;
|
Event* predecessor;
|
||||||
unsigned logicalIp;
|
unsigned logicalIp;
|
||||||
unsigned readCount;
|
unsigned readCount;
|
||||||
|
@ -66,8 +66,8 @@ bool MultiRead::intersect(SiteMask* mask, unsigned depth) {
|
|||||||
bool result = false;
|
bool result = false;
|
||||||
if (not visited) {
|
if (not visited) {
|
||||||
visited = true;
|
visited = true;
|
||||||
for (Cell<Read>** cell = &reads; *cell;) {
|
for (List<Read*>** cell = &reads; *cell;) {
|
||||||
Read* r = (*cell)->value;
|
Read* r = (*cell)->item;
|
||||||
bool valid = r->intersect(mask, depth + 1);
|
bool valid = r->intersect(mask, depth + 1);
|
||||||
if (valid) {
|
if (valid) {
|
||||||
result = true;
|
result = true;
|
||||||
@ -89,8 +89,8 @@ bool MultiRead::valid() {
|
|||||||
bool result = false;
|
bool result = false;
|
||||||
if (not visited) {
|
if (not visited) {
|
||||||
visited = true;
|
visited = true;
|
||||||
for (Cell<Read>** cell = &reads; *cell;) {
|
for (List<Read*>** cell = &reads; *cell;) {
|
||||||
Read* r = (*cell)->value;
|
Read* r = (*cell)->item;
|
||||||
if (r->valid()) {
|
if (r->valid()) {
|
||||||
result = true;
|
result = true;
|
||||||
cell = &((*cell)->next);
|
cell = &((*cell)->next);
|
||||||
@ -104,7 +104,7 @@ bool MultiRead::valid() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void MultiRead::append(Context* c, Read* r) {
|
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) {
|
if (lastRead == 0) {
|
||||||
reads = cell;
|
reads = cell;
|
||||||
} else {
|
} else {
|
||||||
@ -114,7 +114,7 @@ void MultiRead::append(Context* c, Read* r) {
|
|||||||
|
|
||||||
// fprintf(stderr, "append %p to %p for %p\n", r, lastTarget, this);
|
// fprintf(stderr, "append %p to %p for %p\n", r, lastTarget, this);
|
||||||
|
|
||||||
lastTarget->value = r;
|
lastTarget->item = r;
|
||||||
}
|
}
|
||||||
|
|
||||||
Read* MultiRead::next(Context* c) {
|
Read* MultiRead::next(Context* c) {
|
||||||
@ -122,7 +122,7 @@ Read* MultiRead::next(Context* c) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void MultiRead::allocateTarget(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);
|
// fprintf(stderr, "allocate target for %p: %p\n", this, cell);
|
||||||
|
|
||||||
@ -137,7 +137,7 @@ void MultiRead::allocateTarget(Context* c) {
|
|||||||
Read* MultiRead::nextTarget() {
|
Read* MultiRead::nextTarget() {
|
||||||
// fprintf(stderr, "next target for %p: %p\n", this, firstTarget);
|
// fprintf(stderr, "next target for %p: %p\n", this, firstTarget);
|
||||||
|
|
||||||
Read* r = firstTarget->value;
|
Read* r = firstTarget->item;
|
||||||
firstTarget = firstTarget->next;
|
firstTarget = firstTarget->next;
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
@ -88,10 +88,10 @@ class MultiRead: public Read {
|
|||||||
|
|
||||||
Read* nextTarget();
|
Read* nextTarget();
|
||||||
|
|
||||||
Cell<Read>* reads;
|
List<Read*>* reads;
|
||||||
Cell<Read>* lastRead;
|
List<Read*>* lastRead;
|
||||||
Cell<Read>* firstTarget;
|
List<Read*>* firstTarget;
|
||||||
Cell<Read>* lastTarget;
|
List<Read*>* lastTarget;
|
||||||
bool visited;
|
bool visited;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
#include <avian/vm/codegen/targets.h>
|
#include <avian/vm/codegen/targets.h>
|
||||||
|
|
||||||
#include <avian/util/runtime-array.h>
|
#include <avian/util/runtime-array.h>
|
||||||
|
#include <avian/util/list.h>
|
||||||
|
|
||||||
using namespace vm;
|
using namespace vm;
|
||||||
|
|
||||||
@ -211,17 +212,6 @@ class MyThread: public Thread {
|
|||||||
bool methodIsMostRecent;
|
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,
|
static void doTransition(MyThread* t, void* ip, void* stack,
|
||||||
object continuation, MyThread::CallTrace* trace)
|
object continuation, MyThread::CallTrace* trace)
|
||||||
{
|
{
|
||||||
@ -301,7 +291,7 @@ class MyThread: public Thread {
|
|||||||
Context* transition;
|
Context* transition;
|
||||||
TraceContext* traceContext;
|
TraceContext* traceContext;
|
||||||
uintptr_t stackLimit;
|
uintptr_t stackLimit;
|
||||||
ReferenceFrame* referenceFrame;
|
List<Reference*>* referenceFrame;
|
||||||
bool methodLockIsClean;
|
bool methodLockIsClean;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -9061,8 +9051,8 @@ class MyProcessor: public Processor {
|
|||||||
MyThread* t = static_cast<MyThread*>(vmt);
|
MyThread* t = static_cast<MyThread*>(vmt);
|
||||||
|
|
||||||
t->referenceFrame = new
|
t->referenceFrame = new
|
||||||
(t->m->heap->allocate(sizeof(MyThread::ReferenceFrame)))
|
(t->m->heap->allocate(sizeof(List<Reference*>)))
|
||||||
MyThread::ReferenceFrame(t->referenceFrame, t->reference);
|
List<Reference*>(t->reference, t->referenceFrame);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -9072,13 +9062,13 @@ class MyProcessor: public Processor {
|
|||||||
{
|
{
|
||||||
MyThread* t = static_cast<MyThread*>(vmt);
|
MyThread* t = static_cast<MyThread*>(vmt);
|
||||||
|
|
||||||
MyThread::ReferenceFrame* f = t->referenceFrame;
|
List<Reference*>* f = t->referenceFrame;
|
||||||
t->referenceFrame = f->next;
|
t->referenceFrame = f->next;
|
||||||
while (t->reference != f->reference) {
|
while (t->reference != f->item) {
|
||||||
vm::dispose(t, t->reference);
|
vm::dispose(t, t->reference);
|
||||||
}
|
}
|
||||||
|
|
||||||
t->m->heap->free(f, sizeof(MyThread::ReferenceFrame));
|
t->m->heap->free(f, sizeof(List<Reference*>));
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual object
|
virtual object
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
#include <avian/vm/system/system.h>
|
#include <avian/vm/system/system.h>
|
||||||
#include <avian/util/string.h>
|
#include <avian/util/string.h>
|
||||||
#include <avian/util/runtime-array.h>
|
#include <avian/util/runtime-array.h>
|
||||||
|
#include <avian/util/list.h>
|
||||||
|
|
||||||
#include "avian/zlib-custom.h"
|
#include "avian/zlib-custom.h"
|
||||||
#include "avian/finder.h"
|
#include "avian/finder.h"
|
||||||
@ -241,15 +242,14 @@ class JarIndex {
|
|||||||
Deflated = 8
|
Deflated = 8
|
||||||
};
|
};
|
||||||
|
|
||||||
class Node {
|
class Entry {
|
||||||
public:
|
public:
|
||||||
Node(uint32_t hash, const uint8_t* entry, Node* next):
|
Entry(uint32_t hash, const uint8_t* entry):
|
||||||
hash(hash), entry(entry), next(next)
|
hash(hash),
|
||||||
{ }
|
entry(entry) {}
|
||||||
|
|
||||||
uint32_t hash;
|
uint32_t hash;
|
||||||
const uint8_t* entry;
|
const uint8_t* entry;
|
||||||
Node* next;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
JarIndex(System* s, Allocator* allocator, unsigned capacity):
|
JarIndex(System* s, Allocator* allocator, unsigned capacity):
|
||||||
@ -257,14 +257,14 @@ class JarIndex {
|
|||||||
allocator(allocator),
|
allocator(allocator),
|
||||||
capacity(capacity),
|
capacity(capacity),
|
||||||
position(0),
|
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) {
|
static JarIndex* make(System* s, Allocator* allocator, unsigned capacity) {
|
||||||
return new
|
return new
|
||||||
(allocator->allocate(sizeof(JarIndex) + (sizeof(Node*) * capacity)))
|
(allocator->allocate(sizeof(JarIndex) + (sizeof(List<Entry>*) * capacity)))
|
||||||
JarIndex(s, allocator, capacity);
|
JarIndex(s, allocator, capacity);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -283,7 +283,7 @@ class JarIndex {
|
|||||||
|
|
||||||
while (p < end) {
|
while (p < end) {
|
||||||
if (signature(p) == EntrySignature) {
|
if (signature(p) == EntrySignature) {
|
||||||
index = index->add(hash(fileName(p), fileNameLength(p)), p);
|
index = index->add(Entry(hash(fileName(p), fileNameLength(p)), p));
|
||||||
|
|
||||||
p = endOfEntry(p);
|
p = endOfEntry(p);
|
||||||
} else {
|
} else {
|
||||||
@ -298,27 +298,27 @@ class JarIndex {
|
|||||||
return index;
|
return index;
|
||||||
}
|
}
|
||||||
|
|
||||||
JarIndex* add(uint32_t hash, const uint8_t* entry) {
|
JarIndex* add(const Entry& entry) {
|
||||||
if (position < capacity) {
|
if (position < capacity) {
|
||||||
unsigned i = hash & (capacity - 1);
|
unsigned i = entry.hash & (capacity - 1);
|
||||||
table[i] = new (nodes + (position++)) Node(hash, entry, table[i]);
|
table[i] = new (nodes + (position++)) List<Entry>(entry, table[i]);
|
||||||
return this;
|
return this;
|
||||||
} else {
|
} else {
|
||||||
JarIndex* index = make(s, allocator, capacity * 2);
|
JarIndex* index = make(s, allocator, capacity * 2);
|
||||||
for (unsigned i = 0; i < capacity; ++i) {
|
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();
|
dispose();
|
||||||
return index;
|
return index;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Node* findNode(const char* name) {
|
List<Entry>* findNode(const char* name) {
|
||||||
unsigned length = strlen(name);
|
unsigned length = strlen(name);
|
||||||
unsigned i = hash(name) & (capacity - 1);
|
unsigned i = hash(name) & (capacity - 1);
|
||||||
for (Node* n = table[i]; n; n = n->next) {
|
for (List<Entry>* n = table[i]; n; n = n->next) {
|
||||||
const uint8_t* p = n->entry;
|
const uint8_t* p = n->item.entry;
|
||||||
if (equal(name, length, fileName(p), fileNameLength(p))) {
|
if (equal(name, length, fileName(p), fileNameLength(p))) {
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
@ -327,9 +327,9 @@ class JarIndex {
|
|||||||
}
|
}
|
||||||
|
|
||||||
System::Region* find(const char* name, const uint8_t* start) {
|
System::Region* find(const char* name, const uint8_t* start) {
|
||||||
Node* n = findNode(name);
|
List<Entry>* n = findNode(name);
|
||||||
if (n) {
|
if (n) {
|
||||||
const uint8_t* p = n->entry;
|
const uint8_t* p = n->item.entry;
|
||||||
switch (compressionMethod(p)) {
|
switch (compressionMethod(p)) {
|
||||||
case Stored: {
|
case Stored: {
|
||||||
return new (allocator->allocate(sizeof(PointerRegion)))
|
return new (allocator->allocate(sizeof(PointerRegion)))
|
||||||
@ -372,9 +372,9 @@ class JarIndex {
|
|||||||
|
|
||||||
System::FileType stat(const char* name, unsigned* length, bool tryDirectory)
|
System::FileType stat(const char* name, unsigned* length, bool tryDirectory)
|
||||||
{
|
{
|
||||||
Node* node = findNode(name);
|
List<Entry>* node = findNode(name);
|
||||||
if (node) {
|
if (node) {
|
||||||
*length = uncompressedSize(node->entry);
|
*length = uncompressedSize(node->item.entry);
|
||||||
return System::TypeFile;
|
return System::TypeFile;
|
||||||
} else if (tryDirectory) {
|
} else if (tryDirectory) {
|
||||||
*length = 0;
|
*length = 0;
|
||||||
@ -399,8 +399,8 @@ class JarIndex {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void dispose() {
|
void dispose() {
|
||||||
allocator->free(nodes, sizeof(Node) * capacity);
|
allocator->free(nodes, sizeof(List<Entry>) * capacity);
|
||||||
allocator->free(this, sizeof(*this) + (sizeof(Node*) * capacity));
|
allocator->free(this, sizeof(*this) + (sizeof(List<Entry>*) * capacity));
|
||||||
}
|
}
|
||||||
|
|
||||||
System* s;
|
System* s;
|
||||||
@ -408,8 +408,8 @@ class JarIndex {
|
|||||||
unsigned capacity;
|
unsigned capacity;
|
||||||
unsigned position;
|
unsigned position;
|
||||||
|
|
||||||
Node* nodes;
|
List<Entry>* nodes;
|
||||||
Node* table[0];
|
List<Entry>* table[0];
|
||||||
};
|
};
|
||||||
|
|
||||||
class JarElement: public Element {
|
class JarElement: public Element {
|
||||||
@ -422,9 +422,9 @@ class JarElement: public Element {
|
|||||||
|
|
||||||
virtual const char* next(unsigned* size) {
|
virtual const char* next(unsigned* size) {
|
||||||
if (position < index->position) {
|
if (position < index->position) {
|
||||||
JarIndex::Node* n = index->nodes + (position++);
|
List<JarIndex::Entry>* n = index->nodes + (position++);
|
||||||
*size = fileNameLength(n->entry);
|
*size = fileNameLength(n->item.entry);
|
||||||
return reinterpret_cast<const char*>(fileName(n->entry));
|
return reinterpret_cast<const char*>(fileName(n->item.entry));
|
||||||
} else {
|
} else {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
#include "avian/arch.h"
|
#include "avian/arch.h"
|
||||||
|
|
||||||
#include <avian/util/runtime-array.h>
|
#include <avian/util/runtime-array.h>
|
||||||
|
#include <avian/util/list.h>
|
||||||
|
|
||||||
using namespace vm;
|
using namespace vm;
|
||||||
|
|
||||||
@ -30,16 +31,6 @@ const unsigned FrameFootprint = 4;
|
|||||||
|
|
||||||
class Thread: public vm::Thread {
|
class Thread: public vm::Thread {
|
||||||
public:
|
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):
|
Thread(Machine* m, object javaThread, vm::Thread* parent):
|
||||||
vm::Thread(m, javaThread, parent),
|
vm::Thread(m, javaThread, parent),
|
||||||
@ -47,14 +38,14 @@ class Thread: public vm::Thread {
|
|||||||
sp(0),
|
sp(0),
|
||||||
frame(-1),
|
frame(-1),
|
||||||
code(0),
|
code(0),
|
||||||
referenceFrame(0)
|
stackPointers(0)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
unsigned ip;
|
unsigned ip;
|
||||||
unsigned sp;
|
unsigned sp;
|
||||||
int frame;
|
int frame;
|
||||||
object code;
|
object code;
|
||||||
ReferenceFrame* referenceFrame;
|
List<unsigned>* stackPointers;
|
||||||
uintptr_t stack[0];
|
uintptr_t stack[0];
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -3079,9 +3070,8 @@ class MyProcessor: public Processor {
|
|||||||
Thread* t = static_cast<Thread*>(vmt);
|
Thread* t = static_cast<Thread*>(vmt);
|
||||||
|
|
||||||
if (t->sp + capacity < stackSizeInWords(t) / 2) {
|
if (t->sp + capacity < stackSizeInWords(t) / 2) {
|
||||||
t->referenceFrame = new
|
t->stackPointers = new(t->m->heap)
|
||||||
(t->m->heap->allocate(sizeof(Thread::ReferenceFrame)))
|
List<unsigned>(t->sp, t->stackPointers);
|
||||||
Thread::ReferenceFrame(t->referenceFrame, t->sp);
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
@ -3094,11 +3084,11 @@ class MyProcessor: public Processor {
|
|||||||
{
|
{
|
||||||
Thread* t = static_cast<Thread*>(vmt);
|
Thread* t = static_cast<Thread*>(vmt);
|
||||||
|
|
||||||
Thread::ReferenceFrame* f = t->referenceFrame;
|
List<unsigned>* f = t->stackPointers;
|
||||||
t->referenceFrame = f->next;
|
t->stackPointers = f->next;
|
||||||
t->sp = f->sp;
|
t->sp = f->item;
|
||||||
|
|
||||||
t->m->heap->free(f, sizeof(Thread::ReferenceFrame));
|
t->m->heap->free(f, sizeof(List<unsigned>));
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual object
|
virtual object
|
||||||
|
102
src/util.cpp
102
src/util.cpp
@ -9,6 +9,7 @@
|
|||||||
details. */
|
details. */
|
||||||
|
|
||||||
#include "avian/util.h"
|
#include "avian/util.h"
|
||||||
|
#include <avian/util/list.h>
|
||||||
|
|
||||||
using namespace vm;
|
using namespace vm;
|
||||||
|
|
||||||
@ -16,13 +17,6 @@ namespace {
|
|||||||
|
|
||||||
class TreeContext {
|
class TreeContext {
|
||||||
public:
|
public:
|
||||||
class Path {
|
|
||||||
public:
|
|
||||||
Path(object node, Path* next): node(node), next(next) { }
|
|
||||||
|
|
||||||
object node;
|
|
||||||
Path* next;
|
|
||||||
};
|
|
||||||
|
|
||||||
class MyProtector: public Thread::Protector {
|
class MyProtector: public Thread::Protector {
|
||||||
public:
|
public:
|
||||||
@ -34,8 +28,8 @@ class TreeContext {
|
|||||||
v->visit(&(context->root));
|
v->visit(&(context->root));
|
||||||
v->visit(&(context->node));
|
v->visit(&(context->node));
|
||||||
|
|
||||||
for (Path* p = context->ancestors; p; p = p->next) {
|
for (List<object>* p = context->ancestors; p; p = p->next) {
|
||||||
v->visit(&(p->node));
|
v->visit(&(p->item));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -50,15 +44,15 @@ class TreeContext {
|
|||||||
Zone* zone;
|
Zone* zone;
|
||||||
object root;
|
object root;
|
||||||
object node;
|
object node;
|
||||||
Path* ancestors;
|
List<object>* ancestors;
|
||||||
MyProtector protector;
|
MyProtector protector;
|
||||||
bool fresh;
|
bool fresh;
|
||||||
};
|
};
|
||||||
|
|
||||||
TreeContext::Path*
|
List<object>*
|
||||||
path(TreeContext* c, object node, TreeContext::Path* next)
|
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
|
inline object
|
||||||
@ -212,99 +206,99 @@ treeAdd(Thread* t, TreeContext* c)
|
|||||||
|
|
||||||
// rebalance
|
// rebalance
|
||||||
setTreeNodeRed(t, new_, true);
|
setTreeNodeRed(t, new_, true);
|
||||||
while (c->ancestors != 0 and treeNodeRed(t, c->ancestors->node)) {
|
while (c->ancestors != 0 and treeNodeRed(t, c->ancestors->item)) {
|
||||||
if (c->ancestors->node
|
if (c->ancestors->item
|
||||||
== treeNodeLeft(t, c->ancestors->next->node))
|
== treeNodeLeft(t, c->ancestors->next->item))
|
||||||
{
|
{
|
||||||
if (treeNodeRed
|
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
|
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;
|
c->ancestors = c->ancestors->next->next;
|
||||||
} else {
|
} else {
|
||||||
if (new_ == treeNodeRight(t, c->ancestors->node)) {
|
if (new_ == treeNodeRight(t, c->ancestors->item)) {
|
||||||
new_ = c->ancestors->node;
|
new_ = c->ancestors->item;
|
||||||
c->ancestors = c->ancestors->next;
|
c->ancestors = c->ancestors->next;
|
||||||
|
|
||||||
object n = leftRotate(t, new_);
|
object n = leftRotate(t, new_);
|
||||||
|
|
||||||
if (new_ == treeNodeRight(t, c->ancestors->node)) {
|
if (new_ == treeNodeRight(t, c->ancestors->item)) {
|
||||||
set(t, c->ancestors->node, TreeNodeRight, n);
|
set(t, c->ancestors->item, TreeNodeRight, n);
|
||||||
} else {
|
} else {
|
||||||
set(t, c->ancestors->node, TreeNodeLeft, n);
|
set(t, c->ancestors->item, TreeNodeLeft, n);
|
||||||
}
|
}
|
||||||
c->ancestors = path(c, n, c->ancestors);
|
c->ancestors = path(c, n, c->ancestors);
|
||||||
}
|
}
|
||||||
setTreeNodeRed(t, c->ancestors->node, false);
|
setTreeNodeRed(t, c->ancestors->item, false);
|
||||||
setTreeNodeRed(t, c->ancestors->next->node, true);
|
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) {
|
if (c->ancestors->next->next == 0) {
|
||||||
newRoot = n;
|
newRoot = n;
|
||||||
} else if (treeNodeRight(t, c->ancestors->next->next->node)
|
} else if (treeNodeRight(t, c->ancestors->next->next->item)
|
||||||
== c->ancestors->next->node)
|
== c->ancestors->next->item)
|
||||||
{
|
{
|
||||||
set(t, c->ancestors->next->next->node, TreeNodeRight, n);
|
set(t, c->ancestors->next->next->item, TreeNodeRight, n);
|
||||||
} else {
|
} else {
|
||||||
set(t, c->ancestors->next->next->node, TreeNodeLeft, n);
|
set(t, c->ancestors->next->next->item, TreeNodeLeft, n);
|
||||||
}
|
}
|
||||||
// done
|
// done
|
||||||
}
|
}
|
||||||
} else { // this is just the reverse of the code above (right and
|
} else { // this is just the reverse of the code above (right and
|
||||||
// left swapped):
|
// left swapped):
|
||||||
if (treeNodeRed
|
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
|
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;
|
c->ancestors = c->ancestors->next->next;
|
||||||
} else {
|
} else {
|
||||||
if (new_ == treeNodeLeft(t, c->ancestors->node)) {
|
if (new_ == treeNodeLeft(t, c->ancestors->item)) {
|
||||||
new_ = c->ancestors->node;
|
new_ = c->ancestors->item;
|
||||||
c->ancestors = c->ancestors->next;
|
c->ancestors = c->ancestors->next;
|
||||||
|
|
||||||
object n = rightRotate(t, new_);
|
object n = rightRotate(t, new_);
|
||||||
|
|
||||||
if (new_ == treeNodeLeft(t, c->ancestors->node)) {
|
if (new_ == treeNodeLeft(t, c->ancestors->item)) {
|
||||||
set(t, c->ancestors->node, TreeNodeLeft, n);
|
set(t, c->ancestors->item, TreeNodeLeft, n);
|
||||||
} else {
|
} else {
|
||||||
set(t, c->ancestors->node, TreeNodeRight, n);
|
set(t, c->ancestors->item, TreeNodeRight, n);
|
||||||
}
|
}
|
||||||
c->ancestors = path(c, n, c->ancestors);
|
c->ancestors = path(c, n, c->ancestors);
|
||||||
}
|
}
|
||||||
setTreeNodeRed(t, c->ancestors->node, false);
|
setTreeNodeRed(t, c->ancestors->item, false);
|
||||||
setTreeNodeRed(t, c->ancestors->next->node, true);
|
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) {
|
if (c->ancestors->next->next == 0) {
|
||||||
newRoot = n;
|
newRoot = n;
|
||||||
} else if (treeNodeLeft(t, c->ancestors->next->next->node)
|
} else if (treeNodeLeft(t, c->ancestors->next->next->item)
|
||||||
== c->ancestors->next->node)
|
== c->ancestors->next->item)
|
||||||
{
|
{
|
||||||
set(t, c->ancestors->next->next->node, TreeNodeLeft, n);
|
set(t, c->ancestors->next->next->item, TreeNodeLeft, n);
|
||||||
} else {
|
} else {
|
||||||
set(t, c->ancestors->next->next->node, TreeNodeRight, n);
|
set(t, c->ancestors->next->next->item, TreeNodeRight, n);
|
||||||
}
|
}
|
||||||
// done
|
// done
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user