136 #define CLASSCACHE_INIT_SIZE 2048
150 #ifdef CLASSCACHE_STATS
151 static int stat_classnames_stored = 0;
152 static int stat_classes_stored = 0;
153 static int stat_trivial_constraints = 0;
154 static int stat_nontriv_constraints = 0;
155 static int stat_nontriv_constraints_both = 0;
156 static int stat_nontriv_constraints_merged = 0;
157 static int stat_nontriv_constraints_one = 0;
158 static int stat_nontriv_constraints_none = 0;
159 static int stat_new_loader_entry = 0;
160 static int stat_merge_class_entries = 0;
161 static int stat_merge_loader_entries = 0;
162 static int stat_lookup = 0;
163 static int stat_lookup_class_entry_checked = 0;
164 static int stat_lookup_loader_checked = 0;
165 static int stat_lookup_name = 0;
166 static int stat_lookup_name_entry = 0;
167 static int stat_lookup_name_notfound = 0;
168 static int stat_lookup_new_name = 0;
169 static int stat_lookup_new_name_entry = 0;
170 static int stat_lookup_new_name_collisions = 0;
171 static int stat_rehash_names = 0;
172 static int stat_rehash_names_collisions = 0;
174 #define CLASSCACHE_COUNT(cnt) (cnt)++
175 #define CLASSCACHE_COUNTIF(cond,cnt) do{if(cond) (cnt)++;} while(0)
177 void classcache_print_statistics(FILE *file) {
178 fprintf(file,
"classnames stored : %8d\n",stat_classnames_stored);
179 fprintf(file,
"classes stored : %8d\n",stat_classes_stored);
180 fprintf(file,
"trivial constraints : %8d\n",stat_trivial_constraints);
181 fprintf(file,
"non-triv constraints: %8d\n",stat_nontriv_constraints);
182 fprintf(file,
" both loaders rec.: %8d\n",stat_nontriv_constraints_both);
183 fprintf(file,
" merged : %8d\n",stat_nontriv_constraints_merged);
184 fprintf(file,
" one loader rec. : %8d\n",stat_nontriv_constraints_one);
185 fprintf(file,
" no loaders rec. : %8d\n",stat_nontriv_constraints_none);
186 fprintf(file,
"new loader entries : %8d\n",stat_new_loader_entry);
187 fprintf(file,
"merge class entries : %8d\n",stat_merge_class_entries);
188 fprintf(file,
"merge loader entries: %8d\n",stat_merge_loader_entries);
189 fprintf(file,
"lookups : %8d\n",stat_lookup);
190 fprintf(file,
" class entries ckd: %8d\n",stat_lookup_class_entry_checked);
191 fprintf(file,
" loader checked : %8d\n",stat_lookup_loader_checked);
192 fprintf(file,
"lookup name : %8d\n",stat_lookup_name);
193 fprintf(file,
" entries checked : %8d\n",stat_lookup_name_entry);
194 fprintf(file,
" not found : %8d\n",stat_lookup_name_notfound);
195 fprintf(file,
"lookup (new) name : %8d\n",stat_lookup_new_name);
196 fprintf(file,
" entries checked : %8d\n",stat_lookup_new_name_entry);
197 fprintf(file,
" new collisions : %8d\n",stat_lookup_new_name_collisions);
198 fprintf(file,
"names rehashed : %8d times\n",stat_rehash_names);
199 fprintf(file,
" collisions : %8d\n",stat_rehash_names_collisions);
202 #define CLASSCACHE_COUNT(cnt)
203 #define CLASSCACHE_COUNTIF(cond,cnt)
215 #define CLASSCACHE_LOCK() classcache_hashtable_mutex->lock();
216 #define CLASSCACHE_UNLOCK() classcache_hashtable_mutex->unlock();
257 classcache_hashtable_mutex =
new Mutex();
327 for (ldenA = lista; ldenA; ldenA = ldenA->
next) {
329 for (ldenB = listb; ldenB; ldenB = ldenB->
next) {
336 chain = &(ldenA->
next);
372 #ifdef CLASSCACHE_VERBOSE
381 #ifdef CLASSCACHE_VERBOSE
382 logbuffer.
writef(
"classcache_merge_class_entries(%p,%p->%p,%p->%p) ",
383 (
void*)en,(
void*)clsenA,(
void*)clsenA->
classobj,(
void*)clsenB,(
void*)clsenB->
classobj);
432 slot = key & (hashtable_classcache.
size - 1);
478 slot = key & (hashtable_classcache.
size - 1);
503 hashtable_classcache.
ptr[
slot] = c;
506 hashtable_classcache.
entries++;
509 if ((hashtable_classcache.
entries*2) > hashtable_classcache.
size) {
524 for (i = 0; i < hashtable_classcache.
size; i++) {
532 newhash.
ptr[newslot] = c2;
540 MFREE(hashtable_classcache.
ptr,
void *, hashtable_classcache.
size);
541 hashtable_classcache = newhash;
579 for (clsen = en->
classes; clsen; clsen = clsen->
next) {
583 for (lden = clsen->
loaders; lden; lden = lden->
next) {
585 if (lden->
loader == initloader) {
628 for (clsen = en->
classes; clsen; clsen = clsen->
next) {
677 for (clsen = en->
classes; clsen; clsen = clsen->
next) {
686 for (lden = clsen->
loaders; lden; lden = lden->
next) {
687 if (lden->
loader == loader) {
737 #ifdef CLASSCACHE_VERBOSE
746 #ifdef CLASSCACHE_VERBOSE
747 logbuffer.
writef(
"classcache_store (%p,%d,%p=", (
void*)initloader,mayfree,(
void*)cls)
758 for (clsen = en->
classes; clsen; clsen = clsen->
next) {
761 for (lden = clsen->
loaders; lden; lden = lden->
next) {
762 if (lden->
loader == initloader) {
766 #ifdef CLASSCACHE_VERBOSE
782 if (lden->
loader == initloader) {
789 goto return_exception;
802 for (clsenB = en->
classes; clsenB; clsenB = clsenB->
next) {
826 for (clsen = en->
classes; clsen; clsen = clsen->
next) {
830 for (lden = clsen->
loaders; lden; lden = lden->
next) {
831 if (lden->
loader == initloader)
852 #ifdef CLASSCACHE_VERBOSE
921 #ifdef CLASSCACHE_VERBOSE
930 #ifdef CLASSCACHE_VERBOSE
942 for (clsen = en->
classes; clsen; clsen = clsen->
next) {
949 #ifdef CLASSCACHE_VERBOSE
972 #ifdef CLASSCACHE_VERBOSE
994 #if defined(ENABLE_VERIFIER)
1005 for (clsen = entry->
classes; clsen; clsen = clsen->
next) {
1008 for (lden = clsen->
loaders; lden; lden = lden->
next) {
1009 if (lden->
loader == loader)
1015 if (lden->
loader == loader)
1041 for (lden = clsen->
loaders; lden; lden = next) {
1045 for (lden = clsen->
constraints; lden; lden = next) {
1075 if (*chain == clsen) {
1076 *chain = clsen->
next;
1080 chain = &((*chain)->next);
1100 for (clsen = entry->
classes; clsen; clsen = next) {
1126 for (slot = 0; slot < hashtable_classcache.
size; ++
slot) {
1133 MFREE(hashtable_classcache.
ptr,
void*, hashtable_classcache.
size);
1134 hashtable_classcache.
size = 0;
1135 hashtable_classcache.
entries = 0;
1136 hashtable_classcache.
ptr = NULL;
1156 #if defined(ENABLE_VERIFIER)
1167 #ifdef CLASSCACHE_VERBOSE
1169 log_print(
"classcache_add_constraint(%p,%p,", (
void *) a, (
void *) b);
1192 if (clsenA && clsenB) {
1197 if (clsenA == clsenB)
1198 goto return_success;
1206 goto return_exception;
1274 #if defined(ENABLE_VERIFIER)
1340 for (i = 0; i < hashtable_classcache.
size; i++) {
1346 if (en->
name[0] ==
'$')
1351 for (clsen = en->
classes; clsen != NULL; clsen = clsen->
next) {
1401 for (i = 0; i < hashtable_classcache.
size; i++) {
1407 if (en->
name[0] ==
'$')
1412 for (clsen = en->
classes; clsen != NULL; clsen = clsen->
next) {
1454 log_println(
"=== [loaded class cache] =====================================");
1465 for (slot = 0; slot < hashtable_classcache.
size; ++
slot) {
1471 fprintf(file,
"\n");
1474 for (clsen = c->
classes; clsen; clsen = clsen->
next) {
1484 for (lden = clsen->
loaders; lden; lden = lden->
next) {
1501 fprintf(file,
"\n==============================================================\n\n");
classcache_loader_entry * loaders
jlong jlong jlong jlong jint jmethodID jint slot
classinfo * classcache_lookup_defined_or_initiated(classloader_t *loader, Utf8String classname)
#define CLASSCACHE_COUNTIF(cond, cnt)
classinfo * classcache_lookup(classloader_t *initloader, Utf8String classname)
bool classcache_add_constraints_for_params(classloader_t *a, classloader_t *b, methodinfo *m)
void exceptions_throw_linkageerror(const char *message, classinfo *c)
static classcache_name_entry * classcache_new_name(Utf8String name)
static void classcache_free_class_entry(classcache_class_entry *clsen)
classcache_class_entry * next
classinfo * classcache_store_defined(classinfo *cls)
classloader_t * classloader
void classcache_debug_dump(FILE *file, Utf8String only)
void classcache_free(void)
static void classcache_free_name_entry(classcache_name_entry *entry)
hashtable hashtable_classcache
classinfo * classcache_store(classloader_t *initloader, classinfo *cls, bool mayfree)
Dummy implementation of a mutex.
#define CLASSCACHE_LOCK()
void utf_fprint_printable_ascii_classname(FILE *file, Utf8String u)
static classcache_class_entry * classcache_find_loader(classcache_name_entry *entry, classloader_t *loader)
JNIEnv jclass jobject const char * name
void(* classcache_foreach_functionptr_t)(classinfo *, void *)
void log_println(const char *text,...)
static void classcache_remove_class_entry(classcache_name_entry *en, classcache_class_entry *clsen)
Buffer & write_slash_to_dot(const char *)
write to buffer, replacing '/' by '.'
#define TRACESUBSYSTEMINITIALIZATION(text)
static classcache_loader_entry * classcache_new_loader_entry(classloader_t *loader, classcache_loader_entry *next)
void log_print(const char *text,...)
classcache_class_entry * classes
classcache_loader_entry * constraints
#define CLASSCACHE_INIT_SIZE
void exceptions_throw_internalerror(const char *message,...)
bool classcache_store_unique(classinfo *cls)
static classcache_loader_entry * classcache_merge_loaders(classcache_loader_entry *lista, classcache_loader_entry *listb)
JNIEnv jclass jobject loader
static void classcache_merge_class_entries(classcache_name_entry *en, classcache_class_entry *clsenA, classcache_class_entry *clsenB)
bool classcache_init(void)
static s4 classcache_number_of_loaded_classes(void)
static classcache_name_entry * classcache_lookup_name(Utf8String name)
void class_free(classinfo *c)
static Mutex * classcache_hashtable_mutex
void classcache_foreach_loaded_class(classcache_foreach_functionptr_t func, void *data)
static java_object_t * next
s4 classcache_get_loaded_class_count(void)
bool classcache_add_constraint(classloader_t *a, classloader_t *b, Utf8String classname)
classcache_name_entry * hashlink
Buffer & writef(const char *fmt,...)
void hashtable_create(hashtable *hash, u4 size)
classinfo * classcache_lookup_defined(classloader_t *defloader, Utf8String classname)
classcache_loader_entry * next
#define CLASSCACHE_UNLOCK()
#define MFREE(ptr, type, num)
constant_classref * classref
#define CLASSCACHE_COUNT(cnt)