00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 # include "incls/_precompiled.incl"
00027
00028 #ifdef DELTA_COMPILER
00029
00030 # include "incls/_codeTable.cpp.incl"
00031
00032 codeTable::codeTable(int size) {
00033 tableSize = size;
00034 buckets = NEW_C_HEAP_ARRAY(codeTableEntry, size);
00035 clear();
00036 }
00037
00038 codeTableLink* codeTable::new_link(nmethod* nm, codeTableLink* n) {
00039 codeTableLink* res = NEW_C_HEAP_OBJ(codeTableLink);
00040 res->nm = nm;
00041 res->next = n;
00042 return res;
00043 }
00044
00045 void codeTable::clear() {
00046 for (int index = 0; index < tableSize; index++) at(index)->clear();
00047 }
00048
00049 nmethod* codeTable::lookup(LookupKey* L) {
00050 codeTableEntry* bucket = bucketFor(L->hash());
00051
00052
00053 if (bucket->is_empty()) return NULL;
00054
00055
00056 if (bucket->is_nmethod()) {
00057 if (bucket->get_nmethod()->key.equal(L))
00058 return bucket->get_nmethod();
00059 return NULL;
00060 }
00061
00062
00063 for (codeTableLink* l = bucket->get_link(); l; l = l->next) {
00064 if (l->nm->key.equal(L)) return l->nm;
00065 }
00066
00067 return NULL;
00068 }
00069
00070 void codeTable::add(nmethod* nm) {
00071 # ifdef ASSERT
00072 if (lookup(&nm->key)) {
00073 fatal2("adding duplicate key to code table: %#lx and new %#lx",
00074 lookup(&nm->key), nm);
00075 }
00076 # endif
00077 codeTableEntry* bucket = bucketFor(nm->key.hash());
00078
00079 if (bucket->is_empty()) {
00080 bucket->set_nmethod(nm);
00081 } else {
00082 codeTableLink* old_link;
00083 if (bucket->is_nmethod()) {
00084 old_link = new_link(bucket->get_nmethod());
00085 } else {
00086 old_link = bucket->get_link();
00087 }
00088 bucket->set_link(new_link(nm, old_link));
00089 }
00090 }
00091
00092 void codeTable::addIfAbsent(nmethod* nm) {
00093 if (!lookup(&nm->key)) add(nm);
00094 }
00095
00096 bool codeTable::is_present(nmethod* nm) {
00097 return lookup(&nm->key) == nm;
00098 }
00099
00100 void codeTable::remove(nmethod* nm) {
00101 codeTableEntry* bucket = bucketFor(nm->key.hash());
00102 if (bucket->is_empty()) {
00103 fatal("trying to remove nmethod that is not present");
00104 } else {
00105 if (bucket->is_nmethod()) {
00106 bucket->clear();
00107 } else {
00108 if (bucket->get_link()->nm == nm) {
00109
00110 codeTableLink* disposable_link = bucket->get_link();
00111 bucket->set_link(disposable_link->next);
00112 delete disposable_link;
00113 } else {
00114
00115 codeTableLink* current = bucket->get_link();
00116 while (current->next) {
00117 if (current->next->nm == nm) {
00118 codeTableLink* disposable_link = current->next;
00119 current->next = disposable_link->next;
00120 delete disposable_link;
00121 return;
00122 }
00123 current = current->next;
00124 }
00125 fatal("trying to remove nmethod that is not present");
00126 }
00127 }
00128 }
00129 }
00130
00131 bool codeTable::verify() {
00132 bool flag = true;
00133 return flag;
00134 }
00135
00136 void codeTable::print() {
00137 lprintf("CodeTable\n");
00138 }
00139
00140 void codeTable::print_stats() {
00141 # ifdef NOT_IMPLEMENTED
00142 int nmin = 9999999, nmax = 0, total = 0, nonzero = 0;
00143 const int N = 10;
00144 int histo[N];
00145 for (int i = 0; i < N; i++) histo[i] = 0;
00146 for (nmln* p = buckets; p < &buckets[tableSize]; ++p) {
00147 int len = 0;
00148 for (nmln* q = p->next; q != p; q = q->next) len++;
00149 if (len < nmin) nmin = len;
00150 if (len > nmax) nmax = len;
00151 if (len) nonzero++;
00152 total += len;
00153 histo[min(len, N-1)]++;
00154 }
00155 lprintf("\ncodeTable statistics: %d nmethods; min chain = %d, max = %d, avg = %4.1f\n",
00156 total, nmin, nmax, (float)total / nonzero);
00157 lprintf("histogram:\n");
00158 for (i = 0; i < N - 1; i++) lprintf("%4d:\t%d", i, histo[i]);
00159 lprintf(">=%d:\t%d\n", N-1, histo[N-1]);
00160 # endif
00161 }
00162
00163 #endif