CACAO
loader.cpp
Go to the documentation of this file.
1 /* src/vm/loader.cpp - class loader functions
2 
3  Copyright (C) 1996-2013
4  CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
5  Copyright (C) 2009 Theobroma Systems Ltd.
6 
7  This file is part of CACAO.
8 
9  This program is free software; you can redistribute it and/or
10  modify it under the terms of the GNU General Public License as
11  published by the Free Software Foundation; either version 2, or (at
12  your option) any later version.
13 
14  This program is distributed in the hope that it will be useful, but
15  WITHOUT ANY WARRANTY; without even the implied warranty of
16  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17  General Public License for more details.
18 
19  You should have received a copy of the GNU General Public License
20  along with this program; if not, write to the Free Software
21  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
22  02110-1301, USA.
23 
24 */
25 
26 
27 #include "vm/loader.hpp"
28 #include "config.h"
29 
30 #include <cassert>
31 #include <cstddef> // for size_t
32 #include <cstdio> // for printf, fprintf
33 #include <cstdlib>
34 #include <cstring> // for memset, strstr, strlen, etc
35 #include <list> // for _List_iterator, etc
36 
37 #include "mm/dumpmemory.hpp" // for DumpMemory, DumpMemoryArea
38 #include "mm/gc.hpp" // for heap_hashcode
39 
40 #include "native/llni.hpp"
41 
42 #include "threads/mutex.hpp" // for Mutex
43 
44 #include "toolbox/hashtable.hpp" // for hashtable, hashtable_create
45 #include "toolbox/list.hpp" // for DumpList
46 #include "toolbox/logging.hpp" // for log_message_class, etc
47 
48 #include "vm/class.hpp" // for classinfo, etc
49 #include "vm/classcache.hpp" // for classcache_store, etc
50 #include "vm/descriptor.hpp" // for DescriptorPool, methoddesc, etc
51 #include "vm/exceptions.hpp"
52 #include "vm/descriptor.hpp"
53 #include "vm/field.hpp" // for fieldinfo, field_load
54 #include "vm/global.hpp"
55 #include "vm/globals.hpp" // for class_java_io_Serializable, etc
56 #include "vm/hook.hpp" // for class_loaded
57 #include "vm/javaobjects.hpp" // for java_lang_ClassLoader
58 #include "vm/linker.hpp"
59 #include "vm/method.hpp" // for methodinfo, etc
60 #include "vm/options.hpp" // for opt_verify, loadverbose, etc
61 #include "vm/package.hpp" // for Package
62 #include "vm/primitive.hpp" // for Primitive
63 #include "vm/references.hpp" // for constant_FMIref, etc
64 #include "vm/resolve.hpp"
65 #include "vm/rt-timing.hpp"
66 #include "vm/statistics.hpp"
67 #include "vm/string.hpp" // for JavaString
68 #include "vm/suck.hpp" // for suck_check_classbuffer_size, etc
69 #include "vm/types.hpp" // for u2, u1, u4, s4
70 #include "vm/vm.hpp" // for VM, vm_call_method
71 #include "vm/zip.hpp" // for hashtable_zipfile_entry
72 
73 #include "vm/jit/builtin.hpp"
74 #include "vm/jit/stubs.hpp" // for NativeStub
75 
76 #if defined(ENABLE_JAVASE)
77 # include "vm/annotation.hpp"
78 # include "vm/stackmap.hpp"
79 #endif
80 
81 using namespace cacao;
82 
83 struct classinfo;
84 
85 
86 STAT_REGISTER_VAR(int,count_class_loads,0,"class loads","Number of class loads")
87 
88 STAT_DECLARE_GROUP(memory_stat)
89 STAT_REGISTER_SUM_SUBGROUP(info_struct_stat,"info structs","info struct usage",memory_stat)
90 STAT_REGISTER_GROUP_VAR_EXTERN(int,size_classinfo,0,"size classinfo","classinfo",info_struct_stat) // sizeof(classinfo)?
91 STAT_REGISTER_GROUP_VAR(int,size_fieldinfo,0,"size fieldinfo","fieldinfo",info_struct_stat) // sizeof(fieldinfo)?
92 STAT_REGISTER_GROUP_VAR(int,size_methodinfo,0,"size methodinfo","methodinfo",info_struct_stat) // sizeof(methodinfo)?
93 
94 
95 STAT_REGISTER_SUM_SUBGROUP(misc_code_stat,"misc structs","misc struct usage",memory_stat)
96 STAT_REGISTER_GROUP_VAR(int,count_const_pool_len,0,"const pool len","constant pool",misc_code_stat)
97 STAT_REGISTER_GROUP_VAR(int,count_classref_len,0,"classref len","classref",misc_code_stat)
98 STAT_REGISTER_GROUP_VAR(int,count_parsed_desc_len,0,"parsed desc len","parsed descriptors",misc_code_stat)
99 STAT_REGISTER_GROUP_VAR_EXTERN(int,count_vftbl_len,0,"vftbl len","vftbl",misc_code_stat)
100 STAT_REGISTER_GROUP_VAR_EXTERN(int,count_cstub_len,0,"cstub len","compiler stubs",misc_code_stat)
101 STAT_REGISTER_GROUP_VAR_EXTERN(int,size_stub_native,0,"stub native","native stubs",misc_code_stat)
102 STAT_REGISTER_GROUP_VAR_EXTERN(int,count_utf_len,0,"utf len","utf",misc_code_stat)
103 STAT_REGISTER_GROUP_VAR_EXTERN(int,count_vmcode_len,0,"vmcode len","vmcode",misc_code_stat)
104 STAT_REGISTER_GROUP_VAR_EXTERN(int,size_stack_map,0,"stack map","stack map",misc_code_stat)
105 STAT_REGISTER_GROUP_VAR_EXTERN(int,size_string,0,"string","string",misc_code_stat)
106 STAT_REGISTER_GROUP_VAR_EXTERN(int,size_threadobject,0,"threadobject","threadobject",misc_code_stat)
107 STAT_REGISTER_GROUP_VAR_EXTERN(int,size_thread_index_t,0,"size_thread_index_t","thread index",misc_code_stat)
108 STAT_REGISTER_GROUP_VAR_EXTERN(int,size_stacksize,0,"size_stacksize","stack size",misc_code_stat)
109 STAT_REGISTER_GROUP_VAR_EXTERN(int,size_lock_record,0,"size_lock_record","lock record",misc_code_stat)
110 STAT_REGISTER_GROUP_VAR_EXTERN(int,size_lock_hashtable,0,"size_lock_hashtable","lock hashtable",misc_code_stat)
111 STAT_REGISTER_GROUP_VAR_EXTERN(int,size_lock_waiter,0,"size_lock_waiter","lock waiter",misc_code_stat)
112 
113 
114 /* global variables ***********************************************************/
115 
116 static hashtable *hashtable_classloader;
117 
118 
120 
121 inline void *operator new(std::size_t size, ConstantPoolPlacement) {
122  STATISTICS(count_const_pool_len += size);
123 
124  return mem_alloc(size);
125 }
126 
129 
130 
131 /* loader_preinit **************************************************************
132 
133  Initializes the classpath list and loads classes required for the
134  primitive table.
135 
136  NOTE: Exceptions thrown during VM initialization are caught in the
137  exception functions themselves.
138 
139 *******************************************************************************/
140 
141 void loader_preinit(void)
142 {
143  TRACESUBSYSTEMINITIALIZATION("loader_preinit");
144 
145  // Get current list of classpath entries.
146  SuckClasspath& suckclasspath = VM::get_current()->get_suckclasspath();
147 
148  /* Initialize the monitor pointer for zip/jar file locking. */
149 
150  for (SuckClasspath::iterator it = suckclasspath.begin(); it != suckclasspath.end(); it++) {
151  list_classpath_entry* lce = *it;
152 
153  if (lce->type == CLASSPATH_ARCHIVE)
154  lce->mutex = new Mutex();
155  }
156 
157  /* initialize classloader hashtable, 10 entries should be enough */
158 
159  hashtable_classloader = NEW(hashtable);
160  hashtable_create(hashtable_classloader, 10);
161 
162  /* Load the most basic classes. */
163 
164  assert(VM::get_current()->is_initializing() == true);
165 
166  class_java_lang_Object = load_class_bootstrap(utf8::java_lang_Object);
167 
168 #if defined(ENABLE_JAVASE)
169  class_java_lang_Cloneable = load_class_bootstrap(utf8::java_lang_Cloneable);
170  class_java_io_Serializable = load_class_bootstrap(utf8::java_io_Serializable);
171 #endif
172 }
173 
174 
175 /* loader_init *****************************************************************
176 
177  Loads all classes required in the VM.
178 
179  NOTE: Exceptions thrown during VM initialization are caught in the
180  exception functions themselves.
181 
182 *******************************************************************************/
183 
184 void loader_init(void)
185 {
186  TRACESUBSYSTEMINITIALIZATION("loader_init");
187 
188  /* Load primitive-type wrapping classes. */
189 
190  assert(VM::get_current()->is_initializing() == true);
191 
192 #if defined(ENABLE_JAVASE)
193  class_java_lang_Void = load_class_bootstrap(utf8::java_lang_Void);
194 #endif
195 
196  class_java_lang_Boolean = load_class_bootstrap(utf8::java_lang_Boolean);
197  class_java_lang_Byte = load_class_bootstrap(utf8::java_lang_Byte);
198  class_java_lang_Character = load_class_bootstrap(utf8::java_lang_Character);
199  class_java_lang_Short = load_class_bootstrap(utf8::java_lang_Short);
200  class_java_lang_Integer = load_class_bootstrap(utf8::java_lang_Integer);
201  class_java_lang_Long = load_class_bootstrap(utf8::java_lang_Long);
202  class_java_lang_Float = load_class_bootstrap(utf8::java_lang_Float);
203  class_java_lang_Double = load_class_bootstrap(utf8::java_lang_Double);
204 
205  /* Load important system classes. */
206 
207  class_java_lang_Class = load_class_bootstrap(utf8::java_lang_Class);
208  class_java_lang_String = load_class_bootstrap(utf8::java_lang_String);
209 
210 #if defined(ENABLE_JAVASE)
212  load_class_bootstrap(utf8::java_lang_ClassLoader);
213 
215  load_class_bootstrap(utf8::java_lang_SecurityManager);
216 #endif
217 
219  load_class_bootstrap(Utf8String::from_utf8("java/lang/System"));
220 
222  load_class_bootstrap(Utf8String::from_utf8("java/lang/Thread"));
223 
224 #if defined(ENABLE_JAVASE)
226  load_class_bootstrap(utf8::java_lang_ThreadGroup);
227 #endif
228 
229  class_java_lang_Throwable = load_class_bootstrap(utf8::java_lang_Throwable);
230 
231 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
233  load_class_bootstrap(Utf8String::from_utf8("java/lang/VMSystem"));
234 
236  load_class_bootstrap(Utf8String::from_utf8("java/lang/VMThread"));
237 
239  load_class_bootstrap(Utf8String::from_utf8("java/lang/VMThrowable"));
240 #endif
241 
242  /* Important system exceptions. */
243 
244  class_java_lang_Exception = load_class_bootstrap(utf8::java_lang_Exception);
245 
247  load_class_bootstrap(utf8::java_lang_ClassNotFoundException);
248 
250  load_class_bootstrap(utf8::java_lang_RuntimeException);
251 
252  /* Some classes which may be used often. */
253 
254 #if defined(ENABLE_JAVASE)
255  class_java_lang_StackTraceElement = load_class_bootstrap(utf8::java_lang_StackTraceElement);
256 
257  class_java_lang_reflect_Constructor = load_class_bootstrap(utf8::java_lang_reflect_Constructor);
258  class_java_lang_reflect_Field = load_class_bootstrap(utf8::java_lang_reflect_Field);
259  class_java_lang_reflect_Method = load_class_bootstrap(utf8::java_lang_reflect_Method);
260 
261 # if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
262  class_java_lang_reflect_VMConstructor = load_class_bootstrap(utf8::java_lang_reflect_VMConstructor);
263  class_java_lang_reflect_VMField = load_class_bootstrap(utf8::java_lang_reflect_VMField);
264  class_java_lang_reflect_VMMethod = load_class_bootstrap(utf8::java_lang_reflect_VMMethod);
265 # endif
266 
268 
270  class_java_util_Vector = load_class_bootstrap(utf8::java_util_Vector);
271 
272 # if defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
273  class_sun_misc_Signal = load_class_bootstrap(Utf8String::from_utf8("sun/misc/Signal"));
274  class_sun_reflect_MagicAccessorImpl = load_class_bootstrap(Utf8String::from_utf8("sun/reflect/MagicAccessorImpl"));
275  class_sun_reflect_MethodAccessorImpl = load_class_bootstrap(Utf8String::from_utf8("sun/reflect/MethodAccessorImpl"));
276  class_sun_reflect_ConstructorAccessorImpl = load_class_bootstrap(Utf8String::from_utf8("sun/reflect/ConstructorAccessorImpl"));
277 # endif
278 
280  load_class_bootstrap(Utf8String::from_utf8("[Ljava/lang/Object;"));
281 
282 # if defined(ENABLE_ANNOTATIONS)
283  /* needed by annotation support */
285  load_class_bootstrap(Utf8String::from_utf8("sun/reflect/ConstantPool"));
286 
287 # if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
288  /* needed by GNU Classpaths annotation support */
290  load_class_bootstrap(Utf8String::from_utf8("sun/reflect/annotation/AnnotationParser"));
291 # endif
292 # endif
293 #endif
294 }
295 
296 
297 /* loader_hashtable_classloader_add ********************************************
298 
299  Adds an entry to the classloader hashtable.
300 
301  REMEMBER: Also use this to register native loaders!
302 
303 *******************************************************************************/
304 
306 {
308  u4 key;
309  u4 slot;
310 
311  if (cl == NULL)
312  return NULL;
313 
314  hashtable_classloader->mutex->lock();
315 
317 
318  /* key for entry is the hashcode of the classloader;
319  aligned to 16-byte boundaries */
320 
321  key = heap_hashcode(LLNI_DIRECT(cl)) >> 4;
322  slot = key & (hashtable_classloader->size - 1);
323  cle = (hashtable_classloader_entry*) hashtable_classloader->ptr[slot];
324 
325  /* search hashchain for existing entry */
326 
327  while (cle) {
328  if (cle->object == LLNI_DIRECT(cl))
329  break;
330 
331  cle = cle->hashlink;
332  }
333 
335 
336  /* if no classloader was found, we create a new entry here */
337 
338  if (cle == NULL) {
340 
341 #if defined(ENABLE_GC_CACAO)
342  /* register the classloader object with the GC */
343 
345 #endif
346 
348 
349  cle->object = LLNI_DIRECT(cl);
350 
352 
353 /*#define LOADER_DEBUG_CLASSLOADER*/
354 #ifdef LOADER_DEBUG_CLASSLOADER
355  printf("CLASSLOADER: adding new classloader entry %p for %p: ", cle, cl);
356  class_print(LLNI_vftbl_direct(cl)->class);
357  printf("\n");
358  fflush(stdout);
359 #endif
360 
361  /* insert entry into hashtable */
362 
363  cle->hashlink = (hashtable_classloader_entry*) hashtable_classloader->ptr[slot];
364  hashtable_classloader->ptr[slot] = cle;
365 
366  /* update number of entries */
367 
368  hashtable_classloader->entries++;
369  }
370 
371  hashtable_classloader->mutex->unlock();
372 
373 #if defined(ENABLE_HANDLES)
374  return cle;
375 #else
376  return cl;
377 #endif
378 }
379 
380 
381 /* loader_hashtable_classloader_find *******************************************
382 
383  Find an entry in the classloader hashtable.
384 
385 *******************************************************************************/
386 
388 {
390  u4 key;
391  u4 slot;
392 
393  if (cl == NULL)
394  return NULL;
395 
397 
398  /* key for entry is the hashcode of the classloader;
399  aligned to 16-byte boundaries */
400 
401  key = heap_hashcode(LLNI_DIRECT(cl)) >> 4;
402  slot = key & (hashtable_classloader->size - 1);
403  cle = (hashtable_classloader_entry*) hashtable_classloader->ptr[slot];
404 
405  /* search hashchain for existing entry */
406 
407  while (cle) {
408  if (cle->object == LLNI_DIRECT(cl))
409  break;
410 
411  cle = cle->hashlink;
412  }
413 
414 #ifdef LOADER_DEBUG_CLASSLOADER
415  if (cle == NULL) {
416  printf("CLASSLOADER: unable to find classloader entry for %p: ", cl);
417  class_print(LLNI_vftbl_direct(cl)->class);
418  printf("\n");
419  fflush(stdout);
420  }
421 #endif
422 
424 
425 #if defined(ENABLE_HANDLES)
426  return cle;
427 #else
428  return cl;
429 #endif
430 }
431 
432 
433 /* loader_load_all_classes *****************************************************
434 
435  Loads all classes specified in the BOOTCLASSPATH.
436 
437 *******************************************************************************/
438 
440 {
441  // Get current list of classpath entries.
442  SuckClasspath& suckclasspath = VM::get_current()->get_suckclasspath();
443 
444  for (SuckClasspath::iterator it = suckclasspath.begin(); it != suckclasspath.end(); it++) {
445  list_classpath_entry* lce = *it;
446 
447 #if defined(ENABLE_ZLIB)
448  if (lce->type == CLASSPATH_ARCHIVE) {
449  /* get the classes hashtable */
450 
451  ZipFile *zip = lce->zip;
452 
453  for (ZipFile::Iterator it = zip->begin(), end = zip->end(); it != end; ++it) {
454  const ZipFileEntry& entry = *it;
455 
456  Utf8String filename = entry.filename;
457 
458  // skip all entries in META-INF, .properties and .png files
459 
460  if (!strncmp(filename.begin(), "META-INF", strlen("META-INF")) ||
461  strstr(filename.begin(), ".properties") ||
462  strstr(filename.begin(), ".png"))
463  continue;
464 
465  // load class from bootstrap classloader
466 
467  if (!load_class_bootstrap(filename)) {
468  err() << "Error loading class: '" << filename << "'" << nl;
469 
470 #ifndef NDEBUG
471  // print out exception and cause
472 
474 #endif
475  }
476  }
477 
478  } else {
479 #endif
480 #if defined(ENABLE_ZLIB)
481  }
482 #endif
483  }
484 }
485 
486 
487 /* loader_skip_attribute_body **************************************************
488 
489  Skips an attribute the attribute_name_index has already been read.
490 
491  attribute_info {
492  u2 attribute_name_index;
493  u4 attribute_length;
494  u1 info[attribute_length];
495  }
496 
497 *******************************************************************************/
498 
500 {
501  if (!cb.check_size(4))
502  return false;
503 
504  u4 attribute_length = cb.read_u4();
505 
506  if (!cb.check_size(attribute_length))
507  return false;
508 
509  cb.skip_nbytes(attribute_length);
510 
511  return true;
512 }
513 
514 
515 /* load_constantpool ***********************************************************
516 
517  Loads the constantpool of a class, the entries are transformed into
518  a simpler format by resolving references (a detailed overview of
519  the compact structures can be found in global.h).
520 
521 *******************************************************************************/
522 
523 // The following structures are used to save information which cannot be
524 // processed during the first pass. After the complete constantpool has
525 // been traversed the references can be resolved (only in specific order).
526 
527 /// CONSTANT_Class entries
528 struct ForwardClass {
529  uint16_t this_index;
530  uint16_t name_index;
531 };
532 
533 /// CONSTANT_String
535  uint16_t this_index;
536  uint16_t utf8_index;
537 };
538 
539 /// CONSTANT_NameAndType
541  uint16_t this_index;
542  uint16_t name_index;
543  uint16_t type_index;
544 };
545 
546 /// CONSTANT_Fieldref, CONSTANT_Methodref or CONSTANT_InterfaceMethodref
548  uint16_t this_index;
549  uint8_t tag;
550  uint16_t class_index;
552 };
553 
554 /// CONSTANT_MethodHandle
556  uint16_t this_index;
557  uint8_t reference_kind;
558  uint16_t reference_index;
559 };
560 
561 /// CONSTANT_MethodType
563  uint16_t this_index;
565 };
566 
567 /// CONSTANT_InvokeDynamic
569  uint16_t this_index;
572 };
573 
582 };
583 
584 
586  classinfo *c = cb.get_class();
587 
588  // number of entries in the constant_pool table plus one
589  if (!cb.check_size(2))
590  return false;
591 
592  u2 cpcount = c->cpcount = cb.read_u2();
593 
594  // allocate memory
595  u1 *cptags = c->cptags = MNEW(u1, cpcount);
596  void **cpinfos = c->cpinfos = MNEW(void*, cpcount);
597 
598  // NOTE: MNEW zero initializes allcated memory,
599  // cptags and cpinfos require this
600 
601  if (cpcount < 1) {
602  exceptions_throw_classformaterror(c, "Illegal constant pool size");
603  return false;
604  }
605 
606  STATISTICS(count_const_pool_len += (sizeof(u1) + sizeof(void*)) * cpcount);
607 
608  /******* first pass *******/
609  // entries which cannot be resolved now are written into
610  // temporary structures and traversed again later
611 
612  u2 idx = 1;
613 
614  while (idx < cpcount) {
615  // get constant type
616  if (!cb.check_size(1))
617  return false;
618 
620 
621  switch (tag) {
622  case CONSTANT_Class: {
623  // reference to CONSTANT_Utf8 with class name
624  if (!cb.check_size(2))
625  return false;
626 
627  uint16_t name_index = cb.read_u2();
628 
629  ForwardClass f = { idx, name_index };
630 
631  fwd.classes.push_back(f);
632 
633  idx++;
634  break;
635  }
636 
637  case CONSTANT_String: {
638  // reference to CONSTANT_Utf8_info with string characters
639  if (!cb.check_size(2))
640  return false;
641 
642  uint16_t utf8_index = cb.read_u2();
643 
644  ForwardString f = { idx, utf8_index };
645 
646  fwd.strings.push_back(f);
647 
648  idx++;
649  break;
650  }
651 
652  case CONSTANT_NameAndType: {
653  if (!cb.check_size(2 + 2))
654  return false;
655 
656  // reference to CONSTANT_Utf8_info containing simple name
657  uint16_t name_index = cb.read_u2();
658 
659  // reference to CONSTANT_Utf8_info containing field or method descriptor
660  uint16_t type_index = cb.read_u2();
661 
662  ForwardNameAndType f = { idx, name_index, type_index };
663 
664  fwd.nameandtypes.push_back(f);
665 
666  idx++;
667  break;
668  }
669 
670  case CONSTANT_Fieldref:
671  case CONSTANT_Methodref:
673  if (!cb.check_size(2 + 2))
674  return false;
675 
676  // class or interface type that contains the declaration of the field or method
677  uint16_t class_index = cb.read_u2();
678 
679  // name and descriptor of the field or method
680  uint16_t nameandtype_index = cb.read_u2();
681 
682  ForwardFieldMethInt f = { idx, tag, class_index, nameandtype_index };
683 
684  fwd.fieldmethints.push_back(f);
685 
686  cptags[idx] = tag;
687 
688  idx++;
689  break;
690  }
691 
692  case CONSTANT_Integer: {
693  if (!cb.check_size(4))
694  return false;
695 
696  cptags[idx] = CONSTANT_Integer;
697  cpinfos[idx] = new (ConstantPool) int32_t(cb.read_s4());
698 
699  idx++;
700  break;
701  }
702 
703  case CONSTANT_Float: {
704  if (!cb.check_size(4))
705  return false;
706 
707  cptags[idx] = CONSTANT_Float;
708  cpinfos[idx] = new (ConstantPool) float(cb.read_float());
709 
710  idx++;
711  break;
712  }
713 
714  case CONSTANT_Long: {
715  if (!cb.check_size(8))
716  return false;
717 
718  cptags[idx] = CONSTANT_Long;
719  cpinfos[idx] = new (ConstantPool) int64_t(cb.read_s8());
720 
721  idx += 2;
722  if (idx > cpcount) {
723  exceptions_throw_classformaterror(c, "Invalid constant pool entry");
724  return false;
725  }
726  break;
727  }
728 
729  case CONSTANT_Double: {
730  if (!cb.check_size(8))
731  return false;
732 
733  cptags[idx] = CONSTANT_Double;
734  cpinfos[idx] = new (ConstantPool) double(cb.read_double());
735 
736  idx += 2;
737  if (idx > cpcount) {
738  exceptions_throw_classformaterror(c, "Invalid constant pool entry");
739  return false;
740  }
741  break;
742  }
743 
744  case CONSTANT_Utf8: {
745  if (!cb.check_size(2))
746  return false;
747 
748  // number of bytes in the bytes array (not string-length)
749  uint16_t length = cb.read_u2();
750 
751  // validate the string
752  if (!cb.check_size(length))
753  return false;
754 
755  Utf8String u = Utf8String::from_utf8((char *) cb.get_data(), length);
756 #ifdef ENABLE_VERIFIER
757  if (opt_verify && u == NULL) {
758  exceptions_throw_classformaterror(c, "Invalid UTF-8 string");
759  return false;
760  }
761 #endif
762  cptags[idx] = CONSTANT_Utf8;
763  cpinfos[idx] = u.c_ptr();
764 
765  // skip bytes of the string (buffer size check above)
766  cb.skip_nbytes(length);
767  idx++;
768  break;
769  }
770 
771  case CONSTANT_MethodHandle: {
772  if (cb.version() < ClassFileVersion::JDK_7)
773  goto unsupported_tag;
774 
775  if (!cb.check_size(1 + 2))
776  return false;
777 
778  uint8_t reference_kind = cb.read_u1();
779  uint16_t reference_index = cb.read_u2();
780 
781  ForwardMethodHandle f = { idx, reference_kind, reference_index };
782 
783  fwd.methodhandles.push_back(f);
784 
785  idx++;
786  break;
787  }
788 
789  case CONSTANT_MethodType: {
790  if (cb.version() < ClassFileVersion::JDK_7)
791  goto unsupported_tag;
792 
793  if (!cb.check_size(2))
794  return false;
795 
796  uint16_t descriptor_index = cb.read_u2();
797 
798  ForwardMethodType f = { idx, descriptor_index };
799 
800  fwd.methodtypes.push_front(f);
801 
802  idx++;
803  break;
804  }
805 
806  case CONSTANT_InvokeDynamic: {
807  if (cb.version() < ClassFileVersion::JDK_7)
808  goto unsupported_tag;
809 
810  if (!cb.check_size(2 + 2))
811  return false;
812 
813  uint16_t bootstrap_method_attr_index = cb.read_u2();
814  uint16_t name_and_type_index = cb.read_u2();
815 
816  ForwardInvokeDynamic f = { idx, bootstrap_method_attr_index, name_and_type_index };
817 
818  fwd.invokedynamics.push_front(f);
819 
820  idx++;
821  break;
822  }
823 
824  unsupported_tag:
825  exceptions_throw_classformaterror(c, "Class file version does not support constant tag %u in class file %s", tag, c->name.begin());
826  return false;
827 
828  default:
829  exceptions_throw_classformaterror(c, "Illegal constant pool type '%u'", tag);
830  return false;
831  } /* end switch */
832  } /* end while */
833 
834  /* resolve entries in temporary structures */
835 
836  for (DumpList<ForwardClass>::iterator it = fwd.classes.begin(),
837  end = fwd.classes.end(); it != end; ++it) {
838  Utf8String name = (utf*) class_getconstant(c, it->name_index, CONSTANT_Utf8);
839 
840  if (!name)
841  return false;
842 
843 #ifdef ENABLE_VERIFIER
844  if (opt_verify && !name.is_valid_name()) {
845  exceptions_throw_classformaterror(c, "Class reference with invalid name");
846  return false;
847  }
848 #endif
849 
850  // add all class references to the descriptor_pool
851 
852  if (!descpool.add_class(name))
853  return false;
854 
855  // the classref is created later
856  cptags[it->this_index] = CONSTANT_ClassName;
857  cpinfos[it->this_index] = name;
858  }
859 
860  for (DumpList<ForwardString>::iterator it = fwd.strings.begin(),
861  end = fwd.strings.end(); it != end; ++it) {
862  Utf8String text = (utf*) class_getconstant(c, it->utf8_index, CONSTANT_Utf8);
863 
864  if (!text)
865  return false;
866 
867  // resolve utf-string
868  cptags[it->this_index] = CONSTANT_String;
869  cpinfos[it->this_index] = text;
870  }
871 
873  end = fwd.nameandtypes.end(); it != end; ++it) {
874  // resolve simple name and descriptor
875  Utf8String name = (utf*) class_getconstant(c, it->name_index, CONSTANT_Utf8);
876  if (!name)
877  return false;
878 
879  Utf8String descriptor = (utf*) class_getconstant(c, it->type_index, CONSTANT_Utf8);
880  if (!descriptor)
881  return false;
882 
883 #ifdef ENABLE_VERIFIER
884  if (opt_verify) {
885  // check name
886  if (!name.is_valid_name()) {
887  exceptions_throw_classformaterror(c, "Illegal field or method name \"%s\"", name.begin());
888  return false;
889  }
890 
891  // disallow referencing <clinit> among others
892  if (name[0] == '<' && name != utf8::init) {
893  exceptions_throw_classformaterror(c, "Illegal reference to special method");
894  return false;
895  }
896  }
897 #endif // ENABLE_VERIFIER
898 
899  cptags[it->this_index] = CONSTANT_NameAndType;
900  cpinfos[it->this_index] = new (ConstantPool) constant_nameandtype(name, descriptor);
901  }
902 
904  end = fwd.fieldmethints.end(); it != end; ++it) {
905  // resolve simple name and descriptor
906 
908  it->nameandtype_index,
910  if (!nat)
911  return false;
912 
913  // add all descriptors in {Field,Method}ref to the descriptor_pool
914 
915  switch (it->tag) {
916  case CONSTANT_Fieldref:
917  if (!descpool.add_field(nat->descriptor))
918  return false;
919  break;
920  case CONSTANT_Methodref:
922  if (descpool.add_method(nat->descriptor) == -1)
923  return false;
924  break;
925  default:
926  assert(false);
927  break;
928  }
929 
930  // the FMIref is created later
931  }
932 
934  end = fwd.methodtypes.end(); it != end; ++it) {
935  Utf8String descriptor = (utf*) class_getconstant(c, it->descriptor_index, CONSTANT_Utf8);
936 
937  if (descpool.add_method(descriptor) == -1)
938  return false;
939  }
940 
941  // MethodHandles & InvokeDynamic are processed later
942 
943  /* everything was ok */
944 
945  return true;
946 }
947 
948 
949 /* loader_load_attribute_signature *********************************************
950 
951  Signature_attribute {
952  u2 attribute_name_index;
953  u4 atrribute_length;
954  u2 signature_index;
955  }
956 
957 *******************************************************************************/
958 
959 #if defined(ENABLE_JAVASE)
961 {
962  /* get classinfo */
963 
964  classinfo *c = cb.get_class();
965 
966  /* destination must be NULL */
967 
968  if (signature != NULL) {
969  exceptions_throw_classformaterror(c, "Multiple Signature attributes");
970  return false;
971  }
972 
973  /* check remaining bytecode */
974 
975  if (!cb.check_size(4 + 2))
976  return false;
977 
978  /* check attribute length */
979 
980  u4 attribute_length = cb.read_u4();
981 
982  if (attribute_length != 2) {
983  exceptions_throw_classformaterror(c, "Wrong size for VALUE attribute");
984  return false;
985  }
986 
987  /* get signature */
988 
989  u2 signature_index = cb.read_u2();
990 
991  signature = (utf*) class_getconstant(c, signature_index, CONSTANT_Utf8);
992 
993  return signature != NULL;
994 }
995 #endif /* defined(ENABLE_JAVASE) */
996 
997 
998 /* load_class_from_sysloader ***************************************************
999 
1000  Load the class with the given name using the system class loader
1001 
1002  IN:
1003  name.............the classname
1004 
1005  RETURN VALUE:
1006  the loaded class, or
1007  NULL if an exception has been thrown
1008 
1009 *******************************************************************************/
1010 
1011 #if defined(ENABLE_JAVASE)
1013 {
1014  classloader_t *cl;
1015  classinfo *c;
1016 
1018 
1019  if (cl == NULL)
1020  return NULL;
1021 
1022  c = load_class_from_classloader(name, cl);
1023 
1024  return c;
1025 }
1026 #endif /* defined(ENABLE_JAVASE) */
1027 
1028 
1029 // register loader real-time group
1030 RT_REGISTER_GROUP(linker_group,"linker","linker group")
1031 
1032 // register real-time timers
1033 RT_REGISTER_GROUP_TIMER(checks_timer,"load","initial checks",linker_group)
1034 RT_REGISTER_GROUP_TIMER(ndpool_timer,"load","new descriptor pool",linker_group)
1035 RT_REGISTER_GROUP_TIMER(cpool_timer,"load","load constant pool",linker_group)
1036 RT_REGISTER_GROUP_TIMER(setup_timer,"load","class setup",linker_group)
1037 RT_REGISTER_GROUP_TIMER(fields_timer,"load","load fields",linker_group)
1038 RT_REGISTER_GROUP_TIMER(methods_timer,"load","load methods",linker_group)
1039 RT_REGISTER_GROUP_TIMER(classrefs_timer,"load","create classrefs",linker_group)
1040 RT_REGISTER_GROUP_TIMER(descs_timer,"load","allocate descriptors",linker_group)
1041 RT_REGISTER_GROUP_TIMER(setrefs_timer,"load","set classrefs",linker_group)
1042 RT_REGISTER_GROUP_TIMER(parsefds_timer,"load","parse field descriptors",linker_group)
1043 RT_REGISTER_GROUP_TIMER(parsemds_timer,"load","parse method descriptors",linker_group)
1044 RT_REGISTER_GROUP_TIMER(parsecpool_timer,"load","parse descriptors in constant pool",linker_group)
1045 RT_REGISTER_GROUP_TIMER(verify_timer,"load","verifier checks",linker_group)
1046 RT_REGISTER_GROUP_TIMER(attrs_timer,"load","load attributes",linker_group)
1047 
1048 // register classloader real-time group
1049 RT_REGISTER_GROUP(cl_group,"classloader","classloader")
1050 
1051 // register real-time timers
1052 RT_REGISTER_GROUP_TIMER(cllookup_timer,"classloader","lookup in classcache",cl_group)
1053 RT_REGISTER_GROUP_TIMER(prepare_timer,"classloader","prepare loader call",cl_group)
1054 RT_REGISTER_GROUP_TIMER(java_timer,"classloader","loader Java code",cl_group)
1055 RT_REGISTER_GROUP_TIMER(clcache_timer,"classloader","store in classcache",cl_group)
1056 
1057 /* load_class_from_classloader *************************************************
1058 
1059  Load the class with the given name using the given user-defined class loader.
1060 
1061  IN:
1062  name.............the classname
1063  cl...............user-defined class loader
1064 
1065  RETURN VALUE:
1066  the loaded class, or
1067  NULL if an exception has been thrown
1068 
1069 *******************************************************************************/
1070 
1072 {
1073  java_handle_t *o;
1074  classinfo *c;
1075  classinfo *tmpc;
1076  java_handle_t *string;
1077 
1078  RT_TIMER_START(cllookup_timer);
1079 
1080  assert(name);
1081 
1082  /* lookup if this class has already been loaded */
1083 
1084  c = classcache_lookup(cl, name);
1085 
1086  RT_TIMER_STOPSTART(cllookup_timer,prepare_timer);
1087 
1088  if (c != NULL)
1089  return c;
1090 
1091  /* if other class loader than bootstrap, call it */
1092 
1093  if (cl != NULL) {
1094  methodinfo *lc;
1095  const char *text;
1096  s4 namelen;
1097 
1098  text = name.begin();
1099  namelen = name.size();
1100 
1101  /* handle array classes */
1102  if (text[0] == '[') {
1103  classinfo *comp;
1104  Utf8String u;
1105 
1106  switch (text[1]) {
1107  case 'L':
1108  /* check for cases like `[L;' or `[L[I;' or `[Ljava.lang.Object' */
1109  if (namelen < 4 || text[2] == '[' || text[namelen - 1] != ';') {
1111  return NULL;
1112  }
1113 
1114  u = Utf8String::from_utf8(text + 2, namelen - 3);
1115 
1116  if (!(comp = load_class_from_classloader(u, cl)))
1117  return NULL;
1118 
1119  /* create the array class */
1120 
1121  c = class_array_of(comp, false);
1122 
1123  tmpc = classcache_store(cl, c, true);
1124 
1125  if (tmpc == NULL) {
1126  /* exception, free the loaded class */
1127  c->state &= ~CLASS_LOADING;
1128  class_free(c);
1129  }
1130 
1131  return tmpc;
1132 
1133  case '[':
1134  /* load the component class */
1135 
1136  u = Utf8String::from_utf8(text + 1, namelen - 1);
1137 
1138  if (!(comp = load_class_from_classloader(u, cl)))
1139  return NULL;
1140 
1141  /* create the array class */
1142 
1143  c = class_array_of(comp, false);
1144 
1145  tmpc = classcache_store(cl, c, true);
1146 
1147  if (tmpc == NULL) {
1148  /* exception, free the loaded class */
1149  c->state &= ~CLASS_LOADING;
1150  class_free(c);
1151  }
1152 
1153  return tmpc;
1154 
1155  default:
1156  /* primitive array classes are loaded by the bootstrap loader */
1157 
1158  c = load_class_bootstrap(name);
1159 
1160  return c;
1161  }
1162  }
1163 
1164  LLNI_class_get(cl, c);
1165 
1166 #if defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
1167  /* OpenJDK uses this internal function because it's
1168  synchronized. */
1169 
1170  lc = class_resolveclassmethod(c,
1171  utf8::loadClassInternal,
1172  utf8::java_lang_String__java_lang_Class,
1173  NULL,
1174  true);
1175 #else
1176  lc = class_resolveclassmethod(c,
1177  utf8::loadClass,
1178  utf8::java_lang_String__java_lang_Class,
1179  NULL,
1180  true);
1181 #endif
1182 
1183  if (lc == NULL)
1184  return NULL; /* exception */
1185 
1186  /* move return value into `o' and cast it afterwards to a classinfo* */
1187 
1188  string = JavaString::from_utf8_slash_to_dot(name);
1189 
1190  RT_TIMER_STOPSTART(prepare_timer,java_timer);
1191 
1192  o = vm_call_method(lc, (java_handle_t *) cl, string);
1193 
1194  RT_TIMER_STOPSTART(java_timer,clcache_timer);
1195 
1196  c = LLNI_classinfo_unwrap(o);
1197 
1198  if (c != NULL) {
1199  /* Store this class in the loaded class cache. If another
1200  class with the same (initloader,name) pair has been
1201  stored earlier it will be returned by classcache_store
1202  In this case classcache_store may not free the class
1203  because it has already been exposed to Java code which
1204  may have kept references to that class. */
1205 
1206  tmpc = classcache_store(cl, c, false);
1207 
1208  if (tmpc == NULL) {
1209  /* exception, free the loaded class */
1210  c->state &= ~CLASS_LOADING;
1211  class_free(c);
1212  }
1213 
1214  c = tmpc;
1215  }
1216  else {
1217  // Expected behavior for the classloader is to throw an exception
1218  // and never return NULL. If the classloader shows a different
1219  // behavior, we are correcting it here (see PR126).
1220  if (exceptions_get_exception() == NULL) {
1221 #if !defined(NDEBUG)
1222  if (opt_PrintWarnings)
1223  log_message_utf("load_class_from_classloader: Correcting faulty classloader behavior (PR126) for ", name);
1224 #endif
1226  }
1227  }
1228 
1229  RT_TIMER_STOP(clcache_timer);
1230 
1231 
1232  /* SUN compatible -verbose:class output */
1233 
1234  if (opt_verboseclass && (c != NULL) && (c->classloader == cl)) {
1235  printf("[Loaded ");
1237  printf("]\n");
1238  }
1239 
1240  return c;
1241  }
1242 
1243  c = load_class_bootstrap(name);
1244 
1245  return c;
1246 }
1247 
1248 
1249 // register boot real-time group
1250 RT_REGISTER_GROUP(boot_group,"boot","boot group")
1251 
1252 // register real-time timers
1253 RT_REGISTER_GROUP_TIMER(lookup_timer,"boot","lookup in classcache",boot_group)
1254 RT_REGISTER_GROUP_TIMER(array_timer,"boot","load array classes",boot_group)
1255 RT_REGISTER_GROUP_TIMER(suck_timer,"boot","suck class files",boot_group)
1256 RT_REGISTER_GROUP_TIMER(load_timer,"boot","load from class buffer",boot_group)
1257 RT_REGISTER_GROUP_TIMER(cache_timer,"boot","store in classcache",boot_group)
1258 
1259 /* load_class_bootstrap ********************************************************
1260 
1261  Load the class with the given name using the bootstrap class loader.
1262 
1263  IN:
1264  name.............the classname
1265 
1266  RETURN VALUE:
1267  loaded classinfo, or
1268  NULL if an exception has been thrown
1269 
1270  SYNCHRONIZATION:
1271  load_class_bootstrap is synchronized. It can be treated as an
1272  atomic operation.
1273 
1274 *******************************************************************************/
1275 
1277 {
1278  classinfo *c;
1279  classinfo *r;
1280 
1281  RT_TIMER_START(lookup_timer);
1282 
1283  /* for debugging */
1284 
1285  assert(name);
1286 
1287  /* lookup if this class has already been loaded */
1288 
1289  r = classcache_lookup(NULL, name);
1290 
1291  if (r != NULL) {
1292  RT_TIMER_STOP(lookup_timer);
1293 
1294  return r;
1295  }
1296 
1297  RT_TIMER_STOP(lookup_timer);
1298 
1299  /* create the classinfo */
1300 
1301  c = class_create_classinfo(name);
1302 
1303  /* handle array classes */
1304 
1305  if (name[0] == '[') {
1306  c = load_newly_created_array(c, NULL);
1307  RT_TIMER_START(array_timer);
1308 
1309  if (c == NULL)
1310  return NULL;
1311 
1312  assert(c->state & CLASS_LOADED);
1313 
1314  RT_TIMER_STOP(array_timer);
1315 
1316  return c;
1317  }
1318  RT_TIMER_START(suck_timer);
1319 
1320 #if defined(ENABLE_STATISTICS)
1321  /* measure time */
1322 
1323  if (opt_getcompilingtime)
1325 
1326  if (opt_getloadingtime)
1328 #endif
1329 
1330  /* load classdata, throw exception on error */
1331 
1332  ClassBuffer cb(c);
1333 
1334  if (!cb) {
1336  return NULL;
1337  }
1338 
1339  RT_TIMER_STOPSTART(suck_timer,load_timer);
1340 
1341  /* load the class from the buffer */
1342 
1344 
1345  RT_TIMER_STOPSTART(load_timer,cache_timer);
1346 
1347  if (r == NULL) {
1348  /* the class could not be loaded, free the classinfo struct */
1349 
1350  class_free(c);
1351  }
1352  else {
1353  /* Store this class in the loaded class cache this step also
1354  checks the loading constraints. If the class has been
1355  loaded before, the earlier loaded class is returned. */
1356 
1357  classinfo *res = classcache_store(NULL, c, true);
1358 
1359  if (res == NULL) {
1360  /* exception */
1361  class_free(c);
1362  }
1363  else {
1364  // Add the package name to the boot packages.
1366  }
1367 
1368  r = res;
1369  }
1370 
1371  RT_TIMER_STOP(cache_timer);
1372 
1373  /* SUN compatible -verbose:class output */
1374 
1375  if (opt_verboseclass && r) {
1376  printf("[Loaded ");
1378  printf(" from %s]\n", cb.get_path());
1379  }
1380 
1381  /* free memory */
1382 
1383  cb.free();
1384 
1385 #if defined(ENABLE_STATISTICS)
1386  /* measure time */
1387 
1388  if (opt_getloadingtime)
1389  loadingtime_stop();
1390 
1391  if (opt_getcompilingtime)
1393 #endif
1394 
1395  return r;
1396 }
1397 
1398 
1399 /* load_class_from_classbuffer_intern ******************************************
1400 
1401  Loads a class from a classbuffer into a given classinfo structure.
1402  Super-classes are also loaded at this point and some verfication
1403  checks are done.
1404 
1405  SYNCHRONIZATION:
1406  This function is NOT synchronized!
1407 
1408 *******************************************************************************/
1409 
1411 {
1412  // Create new dump memory area.
1413  DumpMemoryArea dma;
1414 
1415  RT_TIMER_START(checks_timer);
1416 
1417  /* Get the classbuffer's class. */
1418 
1419  classinfo *c = cb.get_class();
1420 
1421  if (!cb.check_size(4 + 2 + 2))
1422  return false;
1423 
1424  /* check signature */
1425 
1426  if (cb.read_u4() != MAGIC) {
1427  exceptions_throw_classformaterror(c, "Bad magic number");
1428  return false;
1429  }
1430 
1431  /* check version */
1432 
1433  u4 mi = cb.read_u2();
1434  u4 ma = cb.read_u2();
1435  c->version = ClassFileVersion(ma, mi);
1436 
1437  if (ClassFileVersion::CACAO_VERSION < c->version) {
1439  return false;
1440  }
1441 
1442 
1443  RT_TIMER_STOPSTART(checks_timer,ndpool_timer);
1444 
1445  /* create a new descriptor pool */
1446 
1447  DescriptorPool descpool(c);
1448 
1449  RT_TIMER_STOPSTART(ndpool_timer,cpool_timer);
1450 
1451  /* load the constant pool */
1452 
1453  ForwardReferences fwd;
1454 
1455  if (!load_constantpool(cb, fwd, descpool))
1456  return false;
1457 
1458  RT_TIMER_STOPSTART(cpool_timer,setup_timer);
1459 
1460  /* ACC flags */
1461 
1462  if (!cb.check_size(2))
1463  return false;
1464 
1465  /* We OR the flags here, as we set already some flags in
1466  class_create_classinfo. */
1467 
1468  c->flags |= cb.read_u2();
1469 
1470  /* check ACC flags consistency */
1471 
1472  if (c->flags & ACC_INTERFACE) {
1473  if (!(c->flags & ACC_ABSTRACT)) {
1474  /* We work around this because interfaces in JDK 1.1 are
1475  * not declared abstract. */
1476 
1477  c->flags |= ACC_ABSTRACT;
1478  }
1479 
1480  if (c->flags & ACC_FINAL) {
1482  "Illegal class modifiers: 0x%X",
1483  c->flags);
1484  return false;
1485  }
1486 
1487  if (c->flags & ACC_SUPER) {
1488  c->flags &= ~ACC_SUPER; /* kjc seems to set this on interfaces */
1489  }
1490  }
1491 
1492  if ((c->flags & (ACC_ABSTRACT | ACC_FINAL)) == (ACC_ABSTRACT | ACC_FINAL)) {
1494  "Illegal class modifiers: 0x%X",
1495  c->flags);
1496  return false;
1497  }
1498 
1499  if (!cb.check_size(2 + 2))
1500  return false;
1501 
1502  /* This class. */
1503 
1504  uint16_t index = cb.read_u2();
1505 
1506  Utf8String name = (utf *) class_getconstant(c, index, CONSTANT_ClassName);
1507 
1508  if (name == NULL)
1509  return false;
1510 
1511  if (c->name == utf8::not_named_yet) {
1512  /* we finally have a name for this class */
1513  c->name = name;
1515  }
1516  else if (name != c->name) {
1518  return false;
1519  }
1520 
1521  /* Retrieve superclass. */
1522 
1523  c->super = NULL;
1524 
1525  index = cb.read_u2();
1526 
1527  Utf8String supername;
1528 
1529  if (index == 0) {
1530  supername = NULL;
1531 
1532  /* This is only allowed for java.lang.Object. */
1533 
1534  if (c->name != utf8::java_lang_Object) {
1535  exceptions_throw_classformaterror(c, "Bad superclass index");
1536  return false;
1537  }
1538  }
1539  else {
1540  supername = (utf *) class_getconstant(c, index, CONSTANT_ClassName);
1541 
1542  if (supername == NULL)
1543  return false;
1544 
1545  /* java.lang.Object may not have a super class. */
1546 
1547  if (c->name == utf8::java_lang_Object) {
1548  exceptions_throw_classformaterror(NULL, "java.lang.Object with superclass");
1549  return false;
1550  }
1551 
1552  /* Detect circularity. */
1553 
1554  if (supername == c->name) {
1556  return false;
1557  }
1558 
1559  /* Interfaces must have java.lang.Object as super class. */
1560 
1561  if ((c->flags & ACC_INTERFACE) && (supername != utf8::java_lang_Object)) {
1562  exceptions_throw_classformaterror(c, "Interfaces must have java.lang.Object as superclass");
1563  return false;
1564  }
1565  }
1566 
1567  /* Parse the super interfaces. */
1568 
1569  if (!cb.check_size(2))
1570  return false;
1571 
1572  c->interfacescount = cb.read_u2();
1573 
1574  if (!cb.check_size(2 * c->interfacescount))
1575  return false;
1576 
1578 
1579  /* Get the names of the super interfaces. */
1580 
1581  Utf8String *interfacesnames = (Utf8String*) DumpMemory::allocate(sizeof(Utf8String) * c->interfacescount);
1582 
1583  for (int32_t i = 0; i < c->interfacescount; i++) {
1584  uint16_t index = cb.read_u2();
1585 
1586  Utf8String u = (utf *) class_getconstant(c, index, CONSTANT_ClassName);
1587 
1588  if (u == NULL)
1589  return false;
1590 
1591  interfacesnames[i] = u;
1592  }
1593 
1594  RT_TIMER_STOPSTART(setup_timer,fields_timer);
1595 
1596  /* Parse fields. */
1597 
1598  if (!cb.check_size(2))
1599  return false;
1600 
1601  c->fieldscount = cb.read_u2();
1602  c->fields = MNEW(fieldinfo, c->fieldscount);
1603 
1604  MZERO(c->fields, fieldinfo, c->fieldscount);
1605 
1606  for (int32_t i = 0; i < c->fieldscount; i++) {
1607  if (!field_load(cb, &(c->fields[i]), descpool))
1608  return false;
1609  }
1610 
1611  RT_TIMER_STOPSTART(fields_timer,methods_timer);
1612 
1613  /* Parse methods. */
1614 
1615  if (!cb.check_size(2))
1616  return false;
1617 
1618  c->methodscount = cb.read_u2();
1619  c->methods = MNEW(methodinfo, c->methodscount);
1620 
1622 
1623  for (int32_t i = 0; i < c->methodscount; i++) {
1624  if (!method_load(cb, &(c->methods[i]), descpool))
1625  return false;
1626  }
1627 
1628  RT_TIMER_STOPSTART(methods_timer,classrefs_timer);
1629 
1630  /* create the class reference table */
1631 
1632  c->classrefs = descpool.create_classrefs(&(c->classrefcount));
1633 
1634  RT_TIMER_STOPSTART(classrefs_timer,descs_timer);
1635 
1636  /* allocate space for the parsed descriptors */
1637 
1638  descpool.alloc_parsed_descriptors();
1639 
1640 #if defined(ENABLE_STATISTICS)
1641  size_t classrefsize, descsize;
1642 
1643  descpool.get_sizes(&classrefsize, &descsize);
1644  count_classref_len += classrefsize;
1645  count_parsed_desc_len += descsize;
1646 #endif
1647 
1648  RT_TIMER_STOPSTART(descs_timer,setrefs_timer);
1649 
1650  // put the classrefs in the constant pool
1651 
1652  for (DumpList<ForwardClass>::iterator it = fwd.classes.begin(),
1653  end = fwd.classes.end(); it != end; ++it) {
1654  Utf8String name = (utf*) class_getconstant(c, it->this_index, CONSTANT_ClassName);
1655 
1656  c->cptags[it->this_index] = CONSTANT_Class;
1657  c->cpinfos[it->this_index] = descpool.lookup_classref(name);
1658  }
1659 
1660  // get parsed descriptors for MethodTypes & InvokeDynamic call sites
1661 
1662  for (DumpList<ForwardMethodType>::iterator it = fwd.methodtypes.begin(),
1663  end = fwd.methodtypes.end(); it != end; ++it) {
1664  Utf8String descriptor = (utf*) class_getconstant(c, it->descriptor_index, CONSTANT_Utf8);
1665  methoddesc *parseddesc = descpool.parse_method_descriptor(descriptor, ACC_STATIC, NULL);
1666 
1667  c->cptags[it->this_index] = CONSTANT_MethodType;
1668  c->cpinfos[it->this_index] = new (ConstantPool) constant_MethodType(descriptor, parseddesc);
1669  }
1670 
1672  end = fwd.invokedynamics.end(); it != end; ++it) {
1674 
1675  Utf8String name = nat->name;
1676  Utf8String desc = nat->descriptor;
1677 
1678  methoddesc *md = descpool.parse_method_descriptor(desc, ACC_STATIC, NULL);
1680 
1681  c->cptags[it->this_index] = CONSTANT_InvokeDynamic;
1682  c->cpinfos[it->this_index] = new (ConstantPool) constant_InvokeDynamic(it->bootstrap_method_attr_index, name, desc, md);
1683  }
1684 
1685  /* Resolve the super class. */
1686 
1687  if (supername != NULL) {
1688  constant_classref *cr = descpool.lookup_classref(supername);
1689 
1690  if (cr == NULL)
1691  return false;
1692 
1693  /* XXX This should be done better. */
1695 
1696  if (tc == NULL) {
1698  return false;
1699  }
1700 
1701  /* Interfaces are not allowed as super classes. */
1702 
1703  if (tc->flags & ACC_INTERFACE) {
1704  exceptions_throw_incompatibleclasschangeerror(c, "class %s has interface %s as super class");
1705  return false;
1706  }
1707 
1708  /* Don't allow extending final classes */
1709 
1710  if (tc->flags & ACC_FINAL) {
1711  exceptions_throw_verifyerror(NULL, "Cannot inherit from final class");
1712  return false;
1713  }
1714 
1715  /* Store the super class. */
1716 
1717  c->super = tc;
1718  }
1719 
1720  /* Resolve the super interfaces. */
1721 
1722  for (int32_t i = 0; i < c->interfacescount; i++) {
1723  Utf8String u = interfacesnames[i];
1724  constant_classref *cr = descpool.lookup_classref(u);
1725 
1726  if (cr == NULL)
1727  return false;
1728 
1729  /* XXX This should be done better. */
1731 
1732  if (tc == NULL) {
1734  return false;
1735  }
1736 
1737  /* Detect circularity. */
1738 
1739  if (tc == c) {
1741  return false;
1742  }
1743 
1744  if (!(tc->flags & ACC_INTERFACE)) {
1745  exceptions_throw_incompatibleclasschangeerror(tc, "Implementing class");
1746  return false;
1747  }
1748 
1749  /* Store the super interface. */
1750 
1751  c->interfaces[i] = tc;
1752  }
1753 
1754  RT_TIMER_STOPSTART(setrefs_timer,parsefds_timer);
1755 
1756  /* Parse the field descriptors. */
1757 
1758  for (int32_t i = 0; i < c->fieldscount; i++) {
1760  if (!c->fields[i].parseddesc)
1761  return false;
1762  }
1763 
1764  RT_TIMER_STOPSTART(parsefds_timer,parsemds_timer);
1765 
1766  /* parse method descriptors */
1767 
1768  for (int32_t i = 0; i < c->methodscount; i++) {
1769  methodinfo *m = &c->methods[i];
1771  if (!m->parseddesc)
1772  return false;
1773 
1774  for (int32_t j = 0; j < m->rawexceptiontablelength; j++) {
1775  if (!m->rawexceptiontable[j].catchtype.any)
1776  continue;
1777 
1778  if ((m->rawexceptiontable[j].catchtype.ref =
1779  descpool.lookup_classref((utf *) m->rawexceptiontable[j].catchtype.any)) == NULL)
1780  return false;
1781  }
1782 
1783  for (int32_t j = 0; j < m->thrownexceptionscount; j++) {
1784  if (!m->thrownexceptions[j].any)
1785  continue;
1786 
1787  if ((m->thrownexceptions[j].ref =
1788  descpool.lookup_classref((utf *) m->thrownexceptions[j].any)) == NULL)
1789  return false;
1790  }
1791  }
1792 
1793  RT_TIMER_STOPSTART(parsemds_timer,parsecpool_timer);
1794 
1795  /* parse the loaded descriptors */
1796 
1798  end = fwd.fieldmethints.end(); it != end; ++it) {
1800 
1801  Utf8String name = nat->name;
1802  Utf8String descriptor = nat->descriptor;
1803 
1804  constant_classref *classref = (constant_classref *) class_getconstant(c, it->class_index, CONSTANT_Class);
1805  if (!classref)
1806  return false;
1807 
1808  parseddesc_t parseddesc;
1809 
1810  switch (it->tag) {
1811  case CONSTANT_Fieldref: {
1812  parseddesc.fd = descpool.parse_field_descriptor(descriptor);
1813  if (!parseddesc)
1814  return false;
1815  break;
1816  }
1817 
1818  case CONSTANT_Methodref:
1820  parseddesc.md = descpool.parse_method_descriptor(descriptor, ACC_UNDEF, classref);
1821  if (!parseddesc)
1822  return false;
1823  break;
1824  }
1825  default:
1826  assert(false);
1827  }
1828 
1829  c->cptags[it->this_index] = it->tag;
1830  c->cpinfos[it->this_index] = new (ConstantPool) constant_FMIref(classref, name, descriptor, parseddesc);
1831  }
1832 
1834  end = fwd.methodhandles.end(); it != end; ++it) {
1835  MethodHandleKind kind = (MethodHandleKind) it->reference_kind;
1836 
1837  constant_FMIref *fmi;
1838 
1839  switch (kind) {
1840  case REF_getField:
1841  case REF_getStatic:
1842  case REF_putField:
1843  case REF_putStatic:
1844  fmi = (constant_FMIref*) class_getconstant(c, it->reference_index, CONSTANT_Fieldref);
1845 
1846  if (!fmi)
1847  return false;
1848  break;
1849 
1850  case REF_invokeVirtual:
1851  case REF_invokeStatic:
1852  case REF_invokeSpecial:
1853  fmi = (constant_FMIref*) class_getconstant(c, it->reference_index, CONSTANT_Methodref);
1854 
1855  if (!fmi)
1856  return false;
1857 
1858  if (fmi->name == utf8::init || fmi->name == utf8::clinit) {
1859  exceptions_throw_classformaterror(c, "Illegal method handle");
1860  return false;
1861  }
1862  break;
1863 
1864  case REF_newInvokeSpecial:
1865  fmi = (constant_FMIref*) class_getconstant(c, it->reference_index, CONSTANT_Methodref);
1866 
1867  if (!fmi)
1868  return false;
1869 
1870  if (fmi->name != utf8::init) {
1871  exceptions_throw_classformaterror(c, "Illegal method handle");
1872  return false;
1873  }
1874  break;
1875 
1876  case REF_invokeInterface:
1877  fmi = (constant_FMIref*) class_getconstant(c, it->reference_index, CONSTANT_InterfaceMethodref);
1878 
1879  if (!fmi)
1880  return false;
1881 
1882  if (fmi->name == utf8::init || fmi->name == utf8::clinit) {
1883  exceptions_throw_classformaterror(c, "Illegal method handle");
1884  return false;
1885  }
1886  break;
1887 
1888  default:
1889  exceptions_throw_classformaterror(c, "Illegal reference kind in method handle");
1890  return false;
1891  }
1892 
1893  c->cptags[it->this_index] = CONSTANT_MethodHandle;
1894  c->cpinfos[it->this_index] = new (ConstantPool) constant_MethodHandle(kind, fmi);
1895  }
1896 
1897  RT_TIMER_STOPSTART(parsecpool_timer,verify_timer);
1898 
1899 #ifdef ENABLE_VERIFIER
1900  /* Check if all fields and methods can be uniquely
1901  * identified by (name,descriptor). */
1902 
1903  if (opt_verify) {
1904  /* We use a hash table here to avoid making the
1905  * average case quadratic in # of methods, fields.
1906  */
1907  static int shift = 0;
1908  u2 *hashtab;
1909  u2 *next; /* for chaining colliding hash entries */
1910  int32_t len;
1911  int32_t hashlen;
1912  u2 index;
1913  u2 old;
1914 
1915  /* Allocate hashtable */
1916  len = c->methodscount;
1917  if (len < c->fieldscount) len = c->fieldscount;
1918  hashlen = 5 * len;
1919  hashtab = MNEW(u2,(hashlen + len));
1920  next = hashtab + hashlen;
1921 
1922  /* Determine bitshift (to get good hash values) */
1923  if (!shift) {
1924  len = Utf8String::sizeof_utf;
1925  while (len) {
1926  len >>= 1;
1927  shift++;
1928  }
1929  }
1930 
1931  /* Check fields */
1932  memset(hashtab, 0, sizeof(u2) * (hashlen + len));
1933 
1934  for (int32_t i = 0; i < c->fieldscount; ++i) {
1935  fieldinfo *fi = c->fields + i;
1936 
1937  /* It's ok if we lose bits here */
1938  index = ((((size_t) fi->name.c_ptr()) +
1939  ((size_t) fi->descriptor.c_ptr())) >> shift) % hashlen;
1940 
1941  if ((old = hashtab[index])) {
1942  old--;
1943  next[i] = old;
1944  do {
1945  if (c->fields[old].name == fi->name &&
1946  c->fields[old].descriptor == fi->descriptor) {
1947  exceptions_throw_classformaterror(c, "Repetitive field name/signature");
1948  return false;
1949  }
1950  } while ((old = next[old]));
1951  }
1952  hashtab[index] = i + 1;
1953  }
1954 
1955  /* Check methods */
1956  memset(hashtab, 0, sizeof(u2) * (hashlen + hashlen/5));
1957 
1958  for (int32_t i = 0; i < c->methodscount; ++i) {
1959  methodinfo *mi = c->methods + i;
1960 
1961  /* It's ok if we lose bits here */
1962  index = ((((size_t) mi->name.c_ptr()) +
1963  ((size_t) mi->descriptor.c_ptr())) >> shift) % hashlen;
1964 
1965  if ((old = hashtab[index])) {
1966  old--;
1967  next[i] = old;
1968  do {
1969  if (c->methods[old].name == mi->name &&
1970  c->methods[old].descriptor == mi->descriptor) {
1971  exceptions_throw_classformaterror(c, "Repetitive method name/signature");
1972  return false;
1973  }
1974  } while ((old = next[old]));
1975  }
1976  hashtab[index] = i + 1;
1977  }
1978 
1979  MFREE(hashtab, u2, (hashlen + len));
1980  }
1981 #endif /* ENABLE_VERIFIER */
1982 
1983  RT_TIMER_STOPSTART(verify_timer,attrs_timer);
1984 
1985  STATISTICS(size_classinfo += sizeof(classinfo*) * c->interfacescount);
1987  STATISTICS(size_methodinfo += sizeof(methodinfo) * c->methodscount);
1988 
1989  /* load attribute structures */
1990 
1991  if (!class_load_attributes(cb))
1992  return false;
1993 
1994  // Pre Java 1.5 version don't check this. This implementation is
1995  // like Java 1.5 do it: for class file version 45.3 we don't check
1996  // it, older versions are checked.
1997 
1998  if (((ma == 45) && (mi > 3)) || (ma > 45)) {
1999  // check if all data has been read
2000  if (cb.remaining() != 0) {
2001  exceptions_throw_classformaterror(c, "Extra bytes at the end of class file");
2002  return false;
2003  }
2004  }
2005 
2006  RT_TIMER_STOP(attrs_timer);
2007 
2008  return true;
2009 }
2010 
2011 
2012 /* load_class_from_classbuffer *************************************************
2013 
2014  Convenience wrapper for load_class_from_classbuffer.
2015 
2016  SYNCHRONIZATION:
2017  This function is NOT synchronized!
2018 
2019 *******************************************************************************/
2020 
2022 {
2023  classinfo *c;
2024  bool result;
2025 
2026  /* Get the classbuffer's class. */
2027 
2028  c = cb.get_class();
2029 
2030  /* Check if the class is already loaded. */
2031 
2032  if (c->state & CLASS_LOADED)
2033  return c;
2034 
2035  STATISTICS(count_class_loads++);
2036 
2037 #if !defined(NDEBUG)
2038  if (loadverbose)
2039  log_message_class("Loading class: ", c);
2040 #endif
2041 
2042  /* Class is currently loading. */
2043 
2044  c->state |= CLASS_LOADING;
2045 
2046  /* Parse the classbuffer. */
2047 
2049 
2050  /* An error occurred. */
2051 
2052  if (result == false) {
2053  /* Revert loading state. */
2054 
2055  c->state = (c->state & ~CLASS_LOADING);
2056 
2057  return NULL;
2058  }
2059 
2060  /* Revert loading state and set loaded. */
2061 
2062  c->state = (c->state & ~CLASS_LOADING) | CLASS_LOADED;
2063 
2064 #if !defined(NDEBUG)
2065  if (loadverbose)
2066  log_message_class("Loading done class: ", c);
2067 #endif
2068 
2069  // Hook point just after a class was loaded.
2070  Hook::class_loaded(c);
2071 
2072  return c;
2073 }
2074 
2075 
2076 /* load_newly_created_array ****************************************************
2077 
2078  Load a newly created array class.
2079 
2080  RETURN VALUE:
2081  c....................the array class C has been loaded
2082  other classinfo......the array class was found in the class cache,
2083  C has been freed
2084  NULL.................an exception has been thrown
2085 
2086  Note:
2087  This is an internal function. Do not use it unless you know exactly
2088  what you are doing!
2089 
2090  Use one of the load_class_... functions for general array class loading.
2091 
2092 *******************************************************************************/
2093 
2095 {
2096  classinfo *comp = NULL;
2097  methodinfo *clone;
2098  methoddesc *clonedesc;
2099  constant_classref *classrefs;
2100  const char *text;
2101  s4 namelen;
2102  Utf8String u;
2103 
2104  Utf8String name = c->name;
2105 
2106  text = name.begin();
2107  namelen = name.size();
2108 
2109  /* Check array class name */
2110 
2111  if ((namelen < 2) || (text[0] != '[')) {
2113  return NULL;
2114  }
2115 
2116  /* Check the element type */
2117 
2118  switch (text[1]) {
2119  case '[':
2120  /* c is an array of arrays. We have to create the component class. */
2121 
2122  comp = load_class_from_classloader(name.substring(1), loader);
2123 
2124  if (comp == NULL)
2125  return NULL;
2126 
2127  assert(comp->state & CLASS_LOADED);
2128 
2129  /* the array's flags are that of the component class */
2130  c->flags = (comp->flags & ~ACC_INTERFACE) | ACC_FINAL | ACC_ABSTRACT;
2131  c->classloader = comp->classloader;
2132  break;
2133 
2134  case 'L':
2135  /* c is an array of objects. */
2136 
2137  /* check for cases like `[L;' or `[L[I;' or `[Ljava.lang.Object' */
2138  if ((namelen < 4) || (text[2] == '[') || (text[namelen - 1] != ';')) {
2140  return NULL;
2141  }
2142 
2143  u = Utf8String::from_utf8(text + 2, namelen - 3);
2144 
2145  if (!(comp = load_class_from_classloader(u, loader)))
2146  return NULL;
2147 
2148  assert(comp->state & CLASS_LOADED);
2149 
2150  /* the array's flags are that of the component class */
2151  c->flags = (comp->flags & ~ACC_INTERFACE) | ACC_FINAL | ACC_ABSTRACT;
2152  c->classloader = comp->classloader;
2153  break;
2154 
2155  default:
2156  /* c is an array of a primitive type */
2157 
2158  /* check for cases like `[II' and whether the character is a
2159  valid primitive type */
2160 
2161  if ((namelen > 2) || (Primitive::get_class_by_char(text[1]) == NULL)) {
2163  return NULL;
2164  }
2165 
2166  /* the accessibility of the array class is public (VM Spec 5.3.3) */
2168  c->classloader = NULL;
2169  }
2170 
2171  assert(class_java_lang_Object);
2172 #if defined(ENABLE_JAVASE)
2173  assert(class_java_lang_Cloneable);
2175 #endif
2176 
2177  /* Setup the array class. */
2178 
2180 
2181 #if defined(ENABLE_JAVASE)
2182 
2183  c->interfacescount = 2;
2184  c->interfaces = MNEW(classinfo*, 2);
2187 
2188 #elif defined(ENABLE_JAVAME_CLDC1_1)
2189 
2190  c->interfacescount = 0;
2191  c->interfaces = NULL;
2192 
2193 #else
2194 # error unknow Java configuration
2195 #endif
2196 
2197  c->methodscount = 1;
2198  c->methods = MNEW(methodinfo, c->methodscount);
2199 
2201 
2202  classrefs = MNEW(constant_classref, 2);
2203 
2204  new (classrefs + 0) constant_classref(c, c->name);
2205  new (classrefs + 1) constant_classref(c, utf8::java_lang_Object);
2206 
2207  /* create descriptor for clone method */
2208  /* we need one paramslot which is reserved for the 'this' parameter */
2209  clonedesc = NEW(methoddesc);
2210  clonedesc->returntype.type = TYPE_ADR;
2211  clonedesc->returntype.classref = classrefs + 1;
2212  clonedesc->returntype.arraydim = 0;
2213  // initialize params to "empty", add real params below in
2214  // params_from_paramtypes
2215  clonedesc->paramcount = 0;
2216  clonedesc->paramslots = 0;
2217  clonedesc->paramtypes[0].classref = classrefs + 0;
2218  clonedesc->params = NULL;
2219  clonedesc->pool_lock = NULL;
2220 
2221  /* create methodinfo */
2222 
2223  clone = c->methods;
2224  MSET(clone, 0, methodinfo, 1);
2225 
2226  /* ATTENTION: if you delete the ACC_NATIVE below, set
2227  clone->maxlocals=1 (interpreter related) */
2228 
2229  clone->mutex = new Mutex();
2230  clone->flags = ACC_PUBLIC | ACC_NATIVE;
2231  clone->name = utf8::clone;
2232  clone->descriptor = utf8::void__java_lang_Object;
2233  clone->parseddesc = clonedesc;
2234  clone->clazz = c;
2235 
2236  /* parse the descriptor to get the register allocation */
2237 
2238  clonedesc->params_from_paramtypes(clone->flags);
2239 
2240  clone->code = NativeStub::generate(clone, BUILTIN_clone);
2241 
2242  /* XXX: field: length? */
2243 
2244  /* array classes are not loaded from class files */
2245 
2246  c->state |= CLASS_LOADED;
2247  c->classrefs = classrefs;
2248  c->classrefcount = 1;
2249 
2250  /* insert class into the loaded class cache */
2251  /* XXX free classinfo if NULL returned? */
2252 
2253  return classcache_store(loader, c, true);
2254 }
2255 
2256 
2257 /* loader_close ****************************************************************
2258 
2259  Frees all resources.
2260 
2261 *******************************************************************************/
2262 
2263 void loader_close(void)
2264 {
2265  /* empty */
2266 }
2267 
2268 
2269 /*
2270  * These are local overrides for various environment variables in Emacs.
2271  * Please do not remove this and leave it at the end of the file, where
2272  * Emacs will automagically detect them.
2273  * ---------------------------------------------------------------------
2274  * Local variables:
2275  * mode: c++
2276  * indent-tabs-mode: t
2277  * c-basic-offset: 4
2278  * tab-width: 4
2279  * End:
2280  * vim:noexpandtab:sw=4:ts=4:
2281  */
void exceptions_throw_verifyerror(methodinfo *m, const char *message,...)
Definition: exceptions.cpp:973
A MethodType constant stored in the constant pool.
Definition: references.hpp:140
void exceptions_throw_noclassdeffounderror_wrong_name(classinfo *c, Utf8String name)
Definition: exceptions.cpp:729
Utf8String name
Definition: method.hpp:71
jlong jlong jlong jlong jint jmethodID jint slot
Definition: jvmti.h:497
std::size_t index
#define MINOR_VERSION
Definition: global.hpp:152
classinfo * class_java_lang_ThreadGroup
Definition: globals.cpp:42
ConstantPoolTag
Types for entries of a classes constant pool.
Definition: global.hpp:162
#define BUILTIN_clone
Definition: builtin.hpp:323
classinfo * class_java_lang_reflect_Field
Definition: globals.cpp:82
JNIEnv jthread jmethodID jlocation jclass jobject jfieldID field
Definition: jvmti.h:221
Utf8String substring(size_t from) const
Definition: utf8.cpp:378
Utf8String name
Definition: field.hpp:61
#define STATISTICS(x)
Wrapper for statistics only code.
Definition: statistics.hpp:975
void get_sizes(size_t *classrefsize, size_t *descsize)
Definition: descriptor.cpp:961
const char * get_path() const
Definition: suck.hpp:119
uint16_t name_and_type_index
Definition: loader.cpp:571
classinfo * load_class_from_classbuffer(ClassBuffer &cb)
Definition: loader.cpp:2021
static const size_t sizeof_utf
Definition: utf8.hpp:181
bool method_load(ClassBuffer &cb, methodinfo *m, DescriptorPool &descpool)
Definition: method.cpp:162
size_fieldinfo
Definition: loader.cpp:91
methodinfo * class_resolveclassmethod(classinfo *c, Utf8String name, Utf8String desc, classinfo *referer, bool throwexception)
Definition: class.cpp:1211
official tags from JVM spec
Definition: global.hpp:164
ConstantPoolPlacement
Definition: loader.cpp:119
void * class_getconstant(classinfo *c, u4 pos, ConstantPoolTag ctype)
Definition: class.cpp:679
paramdesc * params
Definition: descriptor.hpp:164
#define STAT_REGISTER_SUM_SUBGROUP(var, name, description, group)
Register a statistics summary group.
Definition: statistics.hpp:973
ZipFile * zip
Definition: suck.hpp:55
classinfo * classcache_lookup(classloader_t *initloader, Utf8String classname)
Definition: classcache.cpp:564
CONSTANT_InvokeDynamic.
Definition: loader.cpp:568
uint16_t nameandtype_index
Definition: loader.cpp:551
#define RT_TIMER_STOP(var)
Stop the timer var.
Definition: rt-timing.hpp:695
classinfo * class_java_lang_RuntimeException
Definition: globals.cpp:56
classinfo * class_java_lang_Long
Definition: globals.cpp:73
#define MSET(ptr, byte, type, num)
Definition: memory.hpp:104
classinfo * load_newly_created_array(classinfo *c, classloader_t *loader)
Definition: loader.cpp:2094
methodinfo * methods
Definition: class.hpp:113
#define NEW(type)
Definition: memory.hpp:93
argument_type from
void exceptions_throw_classnotfoundexception(Utf8String name)
Definition: exceptions.cpp:681
classinfo * load_class_from_sysloader(Utf8String name)
Definition: loader.cpp:1012
classinfo * class_java_lang_Float
Definition: globals.cpp:74
uint16_t this_index
Definition: loader.cpp:548
s4 rawexceptiontablelength
Definition: method.hpp:88
static const ClassFileVersion JDK_7
The class file format version used by JDK 7.
Definition: loader.hpp:117
static bool load_class_from_classbuffer_intern(ClassBuffer &cb)
Definition: loader.cpp:1410
hashtable_classloader_entry * hashlink
Definition: loader.hpp:98
classinfo * class_java_lang_Short
Definition: globals.cpp:71
classinfo * super
Definition: class.hpp:102
Utf8String packagename
Definition: class.hpp:132
classinfo * class_java_lang_VMSystem
Definition: globals.cpp:47
void class_print(classinfo *c)
Definition: class.cpp:2231
CONSTANT_Fieldref, CONSTANT_Methodref or CONSTANT_InterfaceMethodref.
Definition: loader.cpp:547
classinfo * class_sun_reflect_annotation_AnnotationParser
Definition: globals.cpp:99
uint16_t this_index
Definition: loader.cpp:529
void utf_display_printable_ascii_classname(Utf8String u)
Definition: utf8.cpp:552
size_t size() const
Definition: utf8.hpp:161
An invokedynamic call site.
Definition: references.hpp:154
classinfo * class_java_lang_Character
Definition: globals.cpp:70
CONSTANT_NameAndType.
Definition: loader.cpp:540
void loader_close(void)
Definition: loader.cpp:2263
classinfo * class_array_of(classinfo *component, bool link)
Definition: class.cpp:832
s4 state
Definition: class.hpp:115
u1 * cptags
Definition: class.hpp:95
classinfo * class_java_lang_Void
Definition: globals.cpp:66
classinfo * class_java_lang_VMThrowable
Definition: globals.cpp:49
classloader_t * classloader
Definition: class.hpp:151
uint16_t this_index
Definition: loader.cpp:563
void exceptions_throw_classcircularityerror(classinfo *c)
Definition: exceptions.cpp:618
void resolve_handle_pending_exception(bool throwError)
Definition: resolve.cpp:78
classinfo * class_java_lang_reflect_VMMethod
Definition: globals.cpp:91
uint16_t class_index
Definition: loader.cpp:550
void skip_nbytes(size_t num_bytes)
Skip block of classfile data.
Definition: suck.hpp:190
s4 classrefcount
Definition: class.hpp:98
void loader_init(void)
Definition: loader.cpp:184
int32_t interfacescount
Definition: class.hpp:106
#define RT_TIMER_START(var)
Start the timer var.
Definition: rt-timing.hpp:694
methoddesc * md
Definition: references.hpp:75
static void usage()
Definition: VMjdwp.cpp:377
Utf8String filename
Definition: zip.hpp:78
classinfo * load_class_bootstrap(Utf8String name)
Definition: loader.cpp:1276
classinfo * classcache_store(classloader_t *initloader, classinfo *cls, bool mayfree)
Definition: classcache.cpp:730
Dummy implementation of a mutex.
Definition: mutex-none.hpp:33
static int32_t heap_hashcode(java_object_t *obj)
Definition: gc.hpp:150
#define LLNI_CRITICAL_END
Definition: llni.hpp:141
constant_classref * ref
Definition: references.hpp:62
java_handle_t * vm_call_method(methodinfo *m, java_handle_t *o,...)
void exceptions_throw_classformaterror(classinfo *c, const char *message,...)
Definition: exceptions.cpp:634
uint8_t u1
Definition: types.hpp:40
classinfo * class_java_lang_VMThread
Definition: globals.cpp:48
Definition: zip.hpp:98
JNIEnv jclass jobject const char * name
Definition: jvmti.h:312
Iterator begin()
Allows iteration over all entries in zip archive.
Definition: zip.hpp:111
classinfo * class_java_lang_Object
Definition: globals.cpp:28
constant_classref * classrefs
Definition: class.hpp:99
classref_or_classinfo catchtype
Definition: method.hpp:156
JNIEnv jthread jobject jclass jlong size
Definition: jvmti.h:387
ClassFileVersion version() const
Definition: suck.cpp:344
#define TRACESUBSYSTEMINITIALIZATION(text)
Definition: options.hpp:258
void class_set_packagename(classinfo *c)
Definition: class.cpp:102
#define MZERO(ptr, type, num)
Definition: memory.hpp:105
uint16_t type_index
Definition: loader.cpp:543
classloader_t * loader_hashtable_classloader_add(java_handle_t *cl)
Definition: loader.cpp:305
bool loader_skip_attribute_body(ClassBuffer &cb)
Definition: loader.cpp:499
static Mutex lock
Definition: atomic.cpp:34
#define RT_REGISTER_GROUP(var, name, description)
Register a new (toplevel) group.
Definition: rt-timing.hpp:683
cacao::ClassFileVersion version
Definition: class.hpp:92
int32_t fieldscount
Definition: class.hpp:109
classinfo * class_sun_reflect_ConstantPool
Definition: globals.cpp:97
typedesc paramtypes[1]
Definition: descriptor.hpp:167
uint16_t bootstrap_method_attr_index
Definition: loader.cpp:570
uint16_t this_index
Definition: loader.cpp:535
uint16_t this_index
Definition: loader.cpp:569
raw_exception_entry * rawexceptiontable
Definition: method.hpp:89
#define LLNI_class_get(obj, variable)
Definition: llni.hpp:60
fieldinfo * fields
Definition: class.hpp:110
uint16_t descriptor_index
Definition: loader.cpp:564
constant_classref * lookup_classref(Utf8String classname)
Definition: descriptor.cpp:657
bool add_field(Utf8String desc)
Definition: descriptor.cpp:543
Utf8String descriptor
Definition: field.hpp:62
bool class_load_attributes(ClassBuffer &cb)
Definition: class.cpp:456
Utf8String descriptor
Definition: method.hpp:72
uint16_t this_index
Definition: loader.cpp:541
uint16_t read_u2()
Definition: suck.hpp:150
A version of the Java class file format.
Definition: loader.hpp:108
classinfo * class_java_lang_Byte
Definition: globals.cpp:69
#define RT_REGISTER_GROUP_TIMER(var, name, description, group)
Register a new timer.
Definition: rt-timing.hpp:682
JNIEnv jthread jmethodID method
Definition: jvmti.h:207
void exceptions_print_current_exception(void)
classinfo * arrayclass_java_lang_Object
Definition: globals.cpp:94
classinfo * class_java_lang_reflect_VMField
Definition: globals.cpp:90
void exceptions_throw_incompatibleclasschangeerror(classinfo *c, const char *message)
Definition: exceptions.cpp:769
constant_classref * class_get_self_classref(classinfo *cls)
Definition: class.cpp:1013
Dump memory area.
Definition: dumpmemory.hpp:90
uint16_t u2
Definition: types.hpp:43
internally used tags
Definition: global.hpp:180
classinfo * clazz
Definition: method.hpp:80
static void version(bool opt_exit)
Definition: vm.cpp:529
static JNINativeMethod methods[]
alloc::list< PassInfo::IDTy >::type & stack
This file contains the statistics framework.
Utf8String name
Definition: class.hpp:91
uint16_t this_index
Definition: loader.cpp:556
classinfo * class_java_lang_ClassNotFoundException
Definition: globals.cpp:55
classinfo * class_java_lang_Class
Definition: globals.cpp:35
#define STAT_REGISTER_GROUP_VAR(type, var, init, name, description, group)
Register an statistics variable and add it to a group.
Definition: statistics.hpp:967
Definition: set.cpp:44
uint16_t name_index
Definition: loader.cpp:542
bool is_valid_name() const
Definition: utf8.cpp:393
classloader_t * loader_hashtable_classloader_find(java_handle_t *cl)
Definition: loader.cpp:387
Mutex * pool_lock
Definition: descriptor.hpp:165
DumpList< ForwardNameAndType > nameandtypes
Definition: loader.cpp:577
classinfo * class_java_lang_reflect_Method
Definition: globals.cpp:83
const Utf8String name
Definition: loader.hpp:83
JNIEnv jthread thread
Definition: jvmti.h:207
s4 flags
Definition: class.hpp:90
typedesc * parseddesc
Definition: field.hpp:64
typedesc * fd
Definition: references.hpp:74
void loader_load_all_classes(void)
Definition: loader.cpp:439
static Utf8String from_utf8(const char *, size_t)
Definition: utf8.cpp:335
jlong tag
Definition: jvmti.h:395
static bool load_constantpool(ClassBuffer &cb, ForwardReferences &fwd, DescriptorPool &descpool)
Definition: loader.cpp:585
MIIterator i
Fieldref, Methodref and InterfaceMethodref.
Definition: references.hpp:86
typedesc returntype
Definition: descriptor.hpp:166
Classpath entries list.
Definition: suck.hpp:62
uint8_t read_u1()
Definition: suck.hpp:145
classinfo * class_java_io_Serializable
Definition: globals.cpp:44
classinfo * class_java_lang_System
Definition: globals.cpp:40
int32_t read_s4()
Definition: suck.hpp:165
int32_t s4
Definition: types.hpp:45
s4 type
Definition: suck.hpp:51
JNIEnv jclass jobject loader
Definition: jvmti.h:312
Mutex * mutex
Definition: suck.hpp:50
s4 cpcount
Definition: class.hpp:94
void gc_reference_register(java_object_t **ref, int32_t reftype)
Definition: gc.c:164
DumpList< ForwardMethodHandle > methodhandles
Definition: loader.cpp:579
static java_handle_t * invoke_getSystemClassLoader()
Invokes the static Java method getSystemClassLoader().
Definition: javaobjects.cpp:51
CONSTANT_MethodHandle.
Definition: loader.cpp:555
Mutex * mutex
Definition: method.hpp:69
codeinfo * code
Definition: method.hpp:103
bool loader_load_attribute_signature(ClassBuffer &cb, Utf8String &signature)
Definition: loader.cpp:960
void params_from_paramtypes(s4 mflags)
Definition: descriptor.cpp:877
int32_t methodscount
Definition: class.hpp:112
void free()
Free memory held by this classbuffer.
Definition: suck.cpp:438
uint16_t name_index
Definition: loader.cpp:530
Iterator end()
Definition: zip.hpp:112
classinfo ** interfaces
Definition: class.hpp:107
bool opt_verify
Definition: options.cpp:103
OStream & err()
Definition: OStream.cpp:33
Definition: suck.hpp:49
This file contains the real-time timing utilities.
uint32_t read_u4()
Definition: suck.hpp:155
DumpList< ForwardFieldMethInt > fieldmethints
Definition: loader.cpp:578
void compilingtime_start(void)
Definition: statistics.cpp:81
DumpList< ForwardInvokeDynamic > invokedynamics
Definition: loader.cpp:581
static JavaString from_utf8_slash_to_dot(Utf8String)
Definition: string.cpp:202
uint32_t u4
Definition: types.hpp:46
bool opt_verboseclass
Definition: options.cpp:73
typedesc * parse_field_descriptor(Utf8String desc)
Definition: descriptor.cpp:708
void loadingtime_stop(void)
Definition: statistics.cpp:65
vftbl_t * vftbl
Definition: class.hpp:121
classinfo * class_java_lang_String
Definition: globals.cpp:39
#define LLNI_vftbl_direct(obj)
Definition: llni.hpp:120
u2 thrownexceptionscount
Definition: method.hpp:91
classinfo * get_class() const
Definition: suck.hpp:117
byte_iterator begin() const
Definition: utf8.hpp:106
methoddesc * parseddesc
Definition: method.hpp:78
ssize_t add_method(Utf8String desc)
Definition: descriptor.cpp:576
STAT_REGISTER_GROUP_VAR_EXTERN(int, size_classinfo, 0,"size classinfo","classinfo", info_struct_stat) STAT_REGISTER_GROUP_VAR(int
DumpList< ForwardClass > classes
Definition: loader.cpp:575
void loader_preinit(void)
Definition: loader.cpp:141
void class_free(classinfo *c)
Definition: class.cpp:739
int opt_PrintWarnings
Definition: options.cpp:198
#define MNEW(type, num)
Definition: memory.hpp:96
jmethodID jint const void jint const jvmtiAddrLocationMap * map
Definition: jvmti.h:338
CONSTANT_Class entries.
Definition: loader.cpp:528
classinfo * class_java_lang_Exception
Definition: globals.cpp:54
bool parse(jitdata *jd)
Definition: parse.cpp:604
classinfo * class_java_lang_Integer
Definition: globals.cpp:72
#define STAT_DECLARE_GROUP(var)
Declare an external group (or subgroup).
Definition: statistics.hpp:970
size_t remaining()
The number of unread bytes in the buffer.
Definition: suck.hpp:194
classref_or_classinfo * thrownexceptions
Definition: method.hpp:92
static void * allocate(size_t size)
Definition: dumpmemory.hpp:251
SuckClasspath & get_suckclasspath()
Definition: vm.hpp:129
methoddesc * parse_method_descriptor(Utf8String desc, s4 mflags, constant_classref *thisclass)
Definition: descriptor.cpp:751
int64_t read_s8()
Definition: suck.hpp:170
#define LLNI_CRITICAL_START
Definition: llni.hpp:140
void exceptions_throw_unsupportedclassversionerror(classinfo *c)
Definition: exceptions.cpp:948
classinfo * class_java_lang_SecurityManager
Definition: globals.cpp:38
Definition: loader.hpp:96
utf * c_ptr() const
Definition: utf8.hpp:170
java_handle_t * exceptions_get_exception(void)
Definition: exceptions.cpp:76
#define RT_TIMER_STOPSTART(var1, var2)
Stop the timer var1 and start the timer var2.
Definition: rt-timing.hpp:696
static classref_or_classinfo to_classref_or_classinfo(classinfo *c)
Functions for casting a classref/classinfo to a classref_or_classinfo.
Definition: references.hpp:176
#define LLNI_DIRECT(hdl)
Definition: llni.hpp:54
bool loadverbose
Definition: options.cpp:70
classinfo * load_class_from_classloader(Utf8String name, classloader_t *cl)
Definition: loader.cpp:1071
void ** cpinfos
Definition: class.hpp:96
float read_float()
Definition: suck.hpp:175
static java_object_t * next
Definition: copy.c:43
bool field_load(ClassBuffer &cb, fieldinfo *f, DescriptorPool &descpool)
Definition: field.cpp:66
uint16_t utf8_index
Definition: loader.cpp:536
bool check_size(size_t sz)
Assert that at least &lt;sz&gt; bytes are left to read.
Definition: suck.hpp:135
classinfo * class_java_lang_Double
Definition: globals.cpp:75
classinfo * class_java_lang_reflect_VMConstructor
Definition: globals.cpp:89
static const ClassFileVersion CACAO_VERSION
The class file format version supported by CACAO.
Definition: loader.hpp:112
classinfo * class_java_lang_Thread
Definition: globals.cpp:41
uint16_t reference_index
Definition: loader.cpp:558
#define LLNI_classinfo_unwrap(clazz)
Definition: llni.hpp:113
bool add_class(Utf8String name)
Definition: descriptor.cpp:511
const uint8_t * get_data() const
Definition: suck.hpp:118
static classinfo * get_class_by_char(char ch)
Returns the primitive class of the given type.
Definition: primitive.cpp:266
double read_double()
Definition: suck.hpp:180
DumpList< ForwardMethodType > methodtypes
Definition: loader.cpp:580
classinfo * class_java_lang_StackTraceElement
Definition: globals.cpp:80
classinfo * class_create_classinfo(Utf8String classname)
Definition: class.cpp:145
CONSTANT_String.
Definition: loader.cpp:534
s4 flags
Definition: method.hpp:70
#define MAGIC
Definition: global.hpp:150
classinfo * class_java_util_HashMap
Definition: globals.cpp:86
classinfo * resolve_classref_or_classinfo_eager(classref_or_classinfo cls, bool checkaccess)
Definition: resolve.cpp:437
static codeinfo * generate(methodinfo *m, functionptr f)
Wrapper for codegen_emit_stub_native.
Definition: stubs.cpp:282
classinfo * class_java_util_Vector
Definition: globals.cpp:85
void hashtable_create(hashtable *hash, u4 size)
Definition: hashtable.cpp:38
classinfo * class_java_lang_reflect_Constructor
Definition: globals.cpp:81
constant_classref * create_classrefs(s4 *count)
Definition: descriptor.cpp:630
classinfo * class_java_lang_Boolean
Definition: globals.cpp:68
Nl nl
Definition: OStream.cpp:56
#define STAT_REGISTER_VAR(type, var, init, name, description)
Register an external statistics variable.
Definition: statistics.hpp:966
uint8_t reference_kind
Definition: loader.cpp:557
MethodHandleKind
The kinds of methodhandles that can appear in a class file.
Definition: references.hpp:111
void log_message_utf(const char *msg, Utf8String u)
Definition: logging.cpp:214
const Utf8String descriptor
Definition: loader.hpp:84
#define MFREE(ptr, type, num)
Definition: memory.hpp:97
classinfo * class_java_security_PrivilegedAction
Definition: globals.cpp:84
void * mem_alloc(int32_t size)
Definition: memory.cpp:86
const char const void jint length
Definition: jvmti.h:352
#define MAJOR_VERSION
Definition: global.hpp:151
#define printf(...)
Definition: ssa2.cpp:40
classinfo * class_java_lang_Throwable
Definition: globals.cpp:43
constant_classref * classref
Definition: descriptor.hpp:135
static void add(Utf8String packagename)
Add a package to the boot-package list.
Definition: package.cpp:51
void log_message_class(const char *msg, classinfo *c)
Definition: logging.cpp:237
DumpList< ForwardString > strings
Definition: loader.cpp:576
classinfo * class_java_lang_Cloneable
Definition: globals.cpp:37
CONSTANT_MethodType.
Definition: loader.cpp:562
classinfo * class_java_lang_ClassLoader
Definition: globals.cpp:36
void compilingtime_stop(void)
Definition: statistics.cpp:96
void loadingtime_start(void)
Definition: statistics.cpp:49
static VM * get_current()
Definition: vm.hpp:99
Table::Iterator Iterator
Definition: zip.hpp:101
void class_loaded(classinfo *c)
Definition: hook.hpp:89