CACAO
method.cpp
Go to the documentation of this file.
1 /* src/vm/method.cpp - method functions
2 
3  Copyright (C) 1996-2013
4  CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
5 
6  This file is part of CACAO.
7 
8  This program is free software; you can redistribute it and/or
9  modify it under the terms of the GNU General Public License as
10  published by the Free Software Foundation; either version 2, or (at
11  your option) any later version.
12 
13  This program is distributed in the hope that it will be useful, but
14  WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  General Public License for more details.
17 
18  You should have received a copy of the GNU General Public License
19  along with this program; if not, write to the Free Software
20  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21  02110-1301, USA.
22 
23 */
24 
25 
26 #include "vm/method.hpp"
27 #include "config.h" // for ENABLE_ANNOTATIONS, etc
28 
29 #include <cassert> // for assert
30 #include <cstdio> // for printf
31 #include <stdint.h> // for int32_t
32 
33 #include "mm/memory.hpp"
34 
35 #include "native/llni.hpp"
36 
37 #include "threads/mutex.hpp" // for Mutex
38 
39 #include "vm/annotation.hpp"
40 #include "vm/array.hpp" // for ObjectArray, ClassArray
41 #include "vm/breakpoint.hpp" // for BreakpointTable
42 #include "vm/class.hpp" // for classinfo, etc
43 #include "vm/descriptor.hpp"
44 #include "vm/exceptions.hpp"
45 #include "vm/global.hpp" // for java_handle_bytearray_t, etc
46 #include "vm/globals.hpp"
47 #include "vm/linker.hpp"
48 #include "vm/loader.hpp" // for loader_skip_attribute_body, etc
49 #include "vm/options.hpp" // for opt_debugcolor, opt_verify, etc
50 #include "vm/references.hpp" // for classref_or_classinfo, etc
51 #include "vm/resolve.hpp" // for resolve_class_from_typedesc, etc
52 #include "vm/stackmap.hpp"
53 #include "vm/statistics.hpp"
54 #include "vm/suck.hpp" // for suck_u2, etc
55 #include "vm/types.hpp" // for s4, u2, u1, u4
56 #include "vm/utf8.hpp" // for Utf8String, etc
57 #include "vm/vftbl.hpp" // for vftbl_t
58 #include "vm/vm.hpp" // for vm_abort
59 
60 #include "vm/jit/builtin.hpp" // for builtintable_entry
61 #include "vm/jit/code.hpp" // for code_free_code_of_method, etc
62 #include "vm/jit/methodheader.hpp"
63 #include "vm/jit/stubs.hpp" // for CompilerStub, NativeStub
64 
65 using namespace cacao;
66 
67 
68 #if !defined(NDEBUG) && defined(ENABLE_INLINING)
69 #define INLINELOG(code) do { if (opt_TraceInlining) { code } } while (0)
70 #else
71 #define INLINELOG(code)
72 #endif
73 
74 
75 STAT_REGISTER_VAR(int,count_all_methods,0,"all methods","Number of loaded Methods")
76 
77 STAT_DECLARE_GROUP(info_struct_stat)
78 STAT_REGISTER_GROUP_VAR(int,size_lineinfo,0,"size lineinfo","lineinfo",info_struct_stat) // sizeof(lineinfo)?
79 
80 STAT_DECLARE_GROUP(memory_stat)
81 STAT_REGISTER_SUM_SUBGROUP(table_stat,"info structs","info struct usage",memory_stat)
82 STAT_REGISTER_GROUP_VAR(int,count_extable_len,0,"extable len","exception tables",table_stat)
83 STAT_REGISTER_GROUP_VAR_EXTERN(int,size_linenumbertable,0,"size linenumbertable","size of linenumber tables",table_stat)
84 STAT_REGISTER_GROUP_VAR_EXTERN(int,count_linenumbertable,0,"count linenumbertable","number of linenumber tables",table_stat)
85 STAT_REGISTER_GROUP_VAR_EXTERN(int,size_patchref,0,"patchref","patcher references",table_stat)
86 
87 STAT_DECLARE_VAR(int,count_vmcode_len,0)
88 /* global variables ***********************************************************/
89 
91 
92 
93 /* method_init *****************************************************************
94 
95  Initialize method subsystem.
96 
97 *******************************************************************************/
98 
99 void method_init(void)
100 {
101 #if defined(ENABLE_JAVASE)
102  /* Sanity check. */
103 
104  if (class_java_lang_reflect_Method == NULL)
105  vm_abort("method_init: class_java_lang_reflect_Method is NULL");
106 
107  /* Cache java.lang.reflect.Method.invoke() */
108 
109  method_java_lang_reflect_Method_invoke =
111 
112  if (method_java_lang_reflect_Method_invoke == NULL)
113  vm_abort("method_init: Could not resolve method java.lang.reflect.Method.invoke().");
114 #endif
115 }
116 
117 
118 /* method_load *****************************************************************
119 
120  Loads a method from the class file and fills an existing methodinfo
121  structure.
122 
123  method_info {
124  u2 access_flags;
125  u2 name_index;
126  u2 descriptor_index;
127  u2 attributes_count;
128  attribute_info attributes[attribute_count];
129  }
130 
131  attribute_info {
132  u2 attribute_name_index;
133  u4 attribute_length;
134  u1 info[attribute_length];
135  }
136 
137  LineNumberTable_attribute {
138  u2 attribute_name_index;
139  u4 attribute_length;
140  u2 line_number_table_length;
141  {
142  u2 start_pc;
143  u2 line_number;
144  } line_number_table[line_number_table_length];
145  }
146 
147  LocalVariableTable_attribute {
148  u2 attribute_name_index;
149  u4 attribute_length;
150  u2 local_variable_table_length;
151  {
152  u2 start_pc;
153  u2 length;
154  u2 name_index;
155  u2 descriptor_index;
156  u2 index;
157  } local_variable_table[local_variable_table_length];
158  }
159 
160 *******************************************************************************/
161 
163 {
164  int argcount;
165  s4 i, j, k, l;
166  Utf8String u;
167  u2 name_index;
168  u2 descriptor_index;
169  u2 attributes_count;
170  u2 attribute_name_index;
171  Utf8String attribute_name;
172  u2 code_attributes_count;
173  u2 code_attribute_name_index;
174  Utf8String code_attribute_name;
175 
176  /* get classinfo */
177 
178  classinfo *c = cb.get_class();
179 
180  m->mutex = new Mutex();
181 
182  STATISTICS(count_all_methods++);
183 
184  /* all fields of m have been zeroed in load_class_from_classbuffer */
185 
186  m->clazz = c;
187 
188  if (!cb.check_size(2 + 2 + 2))
189  return false;
190 
191  /* access flags */
192 
193  m->flags = cb.read_u2();
194 
195  /* name */
196 
197  name_index = cb.read_u2();
198 
199  if (!(u = (utf*) class_getconstant(c, name_index, CONSTANT_Utf8)))
200  return false;
201 
202  m->name = u;
203 
204  /* descriptor */
205 
206  descriptor_index = cb.read_u2();
207 
208  if (!(u = (utf*) class_getconstant(c, descriptor_index, CONSTANT_Utf8)))
209  return false;
210 
211  m->descriptor = u;
212 
213  if ((argcount = descpool.add_method(u)) == -1)
214  return false;
215 
216 #ifdef ENABLE_VERIFIER
217  if (opt_verify) {
218  if (!Utf8String(m->name).is_valid_name()) {
219  exceptions_throw_classformaterror(c, "Method with invalid name");
220  return false;
221  }
222 
223  if (m->name[0] == '<' &&
224  m->name != utf8::init && m->name != utf8::clinit) {
225  exceptions_throw_classformaterror(c, "Method with invalid special name");
226  return false;
227  }
228  }
229 #endif /* ENABLE_VERIFIER */
230 
231  /* Ignore flags for class initializer according to section 4.6
232  of "The Java Virtual Machine Specification, 2nd Edition" (see PR125). */
233 
234  if (m->name == utf8::clinit) {
235  m->flags &= ACC_STRICT;
236  m->flags |= ACC_STATIC;
237  }
238 
239  if (!(m->flags & ACC_STATIC))
240  argcount++; /* count the 'this' argument */
241 
242 #ifdef ENABLE_VERIFIER
243  if (opt_verify) {
244  if (argcount > 255) {
245  exceptions_throw_classformaterror(c, "Too many arguments in signature");
246  return false;
247  }
248 
249  /* check flag consistency */
250  if (m->name != utf8::clinit) {
251  i = (m->flags & (ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED));
252 
253  if (i != 0 && i != ACC_PUBLIC && i != ACC_PRIVATE && i != ACC_PROTECTED) {
255  "Illegal method modifiers: 0x%X",
256  m->flags);
257  return false;
258  }
259 
260  if (m->flags & ACC_ABSTRACT) {
261  if ((m->flags & (ACC_FINAL | ACC_NATIVE | ACC_PRIVATE |
264  "Illegal method modifiers: 0x%X",
265  m->flags);
266  return false;
267  }
268  }
269 
270  if (c->flags & ACC_INTERFACE) {
271  if ((m->flags & (ACC_ABSTRACT | ACC_PUBLIC)) != (ACC_ABSTRACT | ACC_PUBLIC)) {
273  "Illegal method modifiers: 0x%X",
274  m->flags);
275  return false;
276  }
277  }
278 
279  if (m->name == utf8::init) {
282  exceptions_throw_classformaterror(c, "Instance initialization method has invalid flags set");
283  return false;
284  }
285  }
286  }
287  }
288 #endif /* ENABLE_VERIFIER */
289 
290  /* mark the method as monomorphic until further notice */
291 
293 
294  /* non-abstract methods have an implementation in this class */
295 
296  if (!(m->flags & ACC_ABSTRACT))
298 
299  if (!cb.check_size(2))
300  return false;
301 
302  /* attributes count */
303 
304  attributes_count = cb.read_u2();
305 
306  for (i = 0; i < attributes_count; i++) {
307  if (!cb.check_size(2))
308  return false;
309 
310  /* attribute name index */
311 
312  attribute_name_index = cb.read_u2();
313 
314  attribute_name =
315  (utf*) class_getconstant(c, attribute_name_index, CONSTANT_Utf8);
316 
317  if (attribute_name == NULL)
318  return false;
319 
320  if (attribute_name == utf8::Code) {
321  /* Code */
322 
323  if (m->flags & (ACC_ABSTRACT | ACC_NATIVE)) {
324  exceptions_throw_classformaterror(c, "Code attribute in native or abstract methods");
325  return false;
326  }
327 
328  if (m->jcode) {
329  exceptions_throw_classformaterror(c, "Multiple Code attributes");
330  return false;
331  }
332 
333  if (!cb.check_size(4 + 2 + 2))
334  return false;
335 
336  cb.read_u4();
337  m->maxstack = cb.read_u2();
338  m->maxlocals = cb.read_u2();
339 
340  if (m->maxlocals < argcount) {
341  exceptions_throw_classformaterror(c, "Arguments can't fit into locals");
342  return false;
343  }
344 
345  if (!cb.check_size(4))
346  return false;
347 
348  m->jcodelength = cb.read_u4();
349 
350  if (m->jcodelength == 0) {
351  exceptions_throw_classformaterror(c, "Code of a method has length 0");
352  return false;
353  }
354 
355  if (m->jcodelength > 65535) {
356  exceptions_throw_classformaterror(c, "Code of a method longer than 65535 bytes");
357  return false;
358  }
359 
360  if (!cb.check_size(m->jcodelength))
361  return false;
362 
363  m->jcode = MNEW(u1, m->jcodelength);
364  cb.read_nbytes(m->jcode, m->jcodelength);
365 
366  if (!cb.check_size(2))
367  return false;
368 
370  if (!cb.check_size((2 + 2 + 2 + 2) * m->rawexceptiontablelength))
371  return false;
372 
374 
375  STATISTICS(count_vmcode_len += m->jcodelength + 18);
376  STATISTICS(count_extable_len +=
378 
379  for (j = 0; j < m->rawexceptiontablelength; j++) {
380  u4 idx;
381  m->rawexceptiontable[j].startpc = cb.read_u2();
382  m->rawexceptiontable[j].endpc = cb.read_u2();
383  m->rawexceptiontable[j].handlerpc = cb.read_u2();
384 
385  idx = cb.read_u2();
386 
387  if (!idx) {
388  m->rawexceptiontable[j].catchtype.any = NULL;
389  }
390  else {
391  /* the classref is created later */
392  if (!(m->rawexceptiontable[j].catchtype.any =
393  (utf *) class_getconstant(c, idx, CONSTANT_ClassName)))
394  return false;
395  }
396  }
397 
398  if (!cb.check_size(2))
399  return false;
400 
401  /* code attributes count */
402 
403  code_attributes_count = cb.read_u2();
404 
405  for (k = 0; k < code_attributes_count; k++) {
406  if (!cb.check_size(2))
407  return false;
408 
409  /* code attribute name index */
410 
411  code_attribute_name_index = cb.read_u2();
412 
413  code_attribute_name =
414  (utf*) class_getconstant(c, code_attribute_name_index, CONSTANT_Utf8);
415 
416  if (code_attribute_name == NULL)
417  return false;
418 
419  /* check which code attribute */
420 
421  if (code_attribute_name == utf8::LineNumberTable) {
422  /* LineNumberTable */
423 
424  if (!cb.check_size(4 + 2))
425  return false;
426 
427  /* attribute length */
428 
429  (void) cb.read_u4();
430 
431  /* line number table length */
432 
433  m->linenumbercount = cb.read_u2();
434 
435  if (!cb.check_size((2 + 2) * m->linenumbercount))
436  return false;
437 
439 
440  STATISTICS(size_lineinfo += sizeof(lineinfo) * m->linenumbercount);
441 
442  for (l = 0; l < m->linenumbercount; l++) {
443  m->linenumbers[l].start_pc = cb.read_u2();
444  m->linenumbers[l].line_number = cb.read_u2();
445  }
446  }
447 #if defined(ENABLE_JAVASE)
448  else if (code_attribute_name == utf8::StackMapTable) {
449  /* StackTableMap */
450 
452  return false;
453  }
454 # if defined(ENABLE_JVMTI)
455  else if (code_attribute_name == utf8::LocalVariableTable) {
456  /* LocalVariableTable */
457 
458  if (m->localvars != NULL) {
459  exceptions_throw_classformaterror(c, "Multiple LocalVariableTable attributes");
460  return false;
461  }
462 
463  if (!cb.check_size(4 + 2))
464  return false;
465 
466  // Attribute length.
467  (void) cb.read_u4();
468 
469  m->localvarcount = cb.read_u2();
470 
471  if (!cb.check_size(10 * m->localvarcount))
472  return false;
473 
474  m->localvars = MNEW(localvarinfo, m->localvarcount);
475 
476  for (l = 0; l < m->localvarcount; l++) {
477  m->localvars[l].start_pc = cb.read_u2();
478  m->localvars[l].length = cb.read_u2();
479 
480  uint16_t name_index = cb.read_u2();
481  if (!(m->localvars[l].name = (utf*) class_getconstant(c, name_index, CONSTANT_Utf8)))
482  return false;
483 
484  uint16_t descriptor_index = cb.read_u2();
485  if (!(m->localvars[l].descriptor = (utf*) class_getconstant(c, descriptor_index, CONSTANT_Utf8)))
486  return false;
487 
488  m->localvars[l].index = cb.read_u2();
489 
490  // XXX Check if index is in range.
491  // XXX Check if index already taken.
492  }
493  }
494 # endif /* defined(ENABLE_JVMTI) */
495 #endif /* defined(ENABLE_JAVASE) */
496  else {
497  /* unknown code attribute */
498 
500  return false;
501  }
502  }
503  }
504  else if (attribute_name == utf8::Exceptions) {
505  /* Exceptions */
506 
507  if (m->thrownexceptions != NULL) {
508  exceptions_throw_classformaterror(c, "Multiple Exceptions attributes");
509  return false;
510  }
511 
512  if (!cb.check_size(4 + 2))
513  return false;
514 
515  /* attribute length */
516 
517  (void) cb.read_u4();
518 
519  m->thrownexceptionscount = cb.read_u2();
520 
521  if (!cb.check_size(2 * m->thrownexceptionscount))
522  return false;
523 
525 
526  for (j = 0; j < m->thrownexceptionscount; j++) {
527  /* the classref is created later */
528  if (!((m->thrownexceptions)[j].any =
529  (utf*) class_getconstant(c, cb.read_u2(), CONSTANT_ClassName)))
530  return false;
531  }
532  }
533 #if defined(ENABLE_JAVASE)
534  else if (attribute_name == utf8::Signature) {
535  /* Signature */
536 
537  // TODO: change methodinfo.signature to Utf8String
538  // and use it directly
539 
540  Utf8String signature = m->signature;
541 
542  if (!loader_load_attribute_signature(cb, signature)) {
543  return false;
544  }
545 
546  m->signature = signature;
547  }
548 
549 # if defined(ENABLE_ANNOTATIONS)
550  else if (attribute_name == utf8::RuntimeVisibleAnnotations) {
551  /* RuntimeVisibleAnnotations */
553  return false;
554  }
555  else if (attribute_name == utf8::RuntimeInvisibleAnnotations) {
556  /* RuntimeInvisibleAnnotations */
558  return false;
559  }
560  else if (attribute_name == utf8::RuntimeVisibleParameterAnnotations) {
561  /* RuntimeVisibleParameterAnnotations */
563  return false;
564  }
565  else if (attribute_name == utf8::RuntimeInvisibleParameterAnnotations) {
566  /* RuntimeInvisibleParameterAnnotations */
568  return false;
569  }
570  else if (attribute_name == utf8::AnnotationDefault) {
571  /* AnnotationDefault */
573  return false;
574  }
575 # endif
576 #endif
577  else {
578  /* unknown attribute */
579 
581  return false;
582  }
583  }
584 
585  if ((m->jcode == NULL) && !(m->flags & (ACC_ABSTRACT | ACC_NATIVE))) {
586  exceptions_throw_classformaterror(c, "Missing Code attribute");
587  return false;
588  }
589 
590 #if defined(ENABLE_REPLACEMENT)
591  /* initialize the hit countdown field */
592 
593  m->hitcountdown = METHOD_INITIAL_HIT_COUNTDOWN;
594 #endif
595 
596  /* everything was ok */
597 
598  return true;
599 }
600 
601 
602 /* method_free *****************************************************************
603 
604  Frees all memory that was allocated for this method.
605 
606 *******************************************************************************/
607 
609 {
610  if (m->mutex)
611  delete m->mutex;
612 
613  if (m->jcode)
614  MFREE(m->jcode, u1, m->jcodelength);
615 
616  if (m->rawexceptiontable)
618 
620 
621  if (m->stubroutine) {
622  if (m->flags & ACC_NATIVE) {
624  }
625  else {
627  }
628  }
629 
630  if (m->breakpoints)
631  delete m->breakpoints;
632 }
633 
634 
635 /* method_canoverwrite *********************************************************
636 
637  Check if m and old are identical with respect to type and
638  name. This means that old can be overwritten with m.
639 
640 *******************************************************************************/
641 
643 {
644  if (m->name != old->name)
645  return false;
646 
647  if (m->descriptor != old->descriptor)
648  return false;
649 
650  if (m->flags & ACC_STATIC)
651  return false;
652 
653  return true;
654 }
655 
656 
657 /* method_new_builtin **********************************************************
658 
659  Creates a minimal methodinfo structure for builtins. This comes handy
660  when dealing with builtin stubs or stacktraces.
661 
662 *******************************************************************************/
663 
665 {
666  methodinfo *m;
667 
668  /* allocate the methodinfo structure */
669 
670  m = NEW(methodinfo);
671 
672  /* initialize methodinfo structure */
673 
674  MZERO(m, methodinfo, 1);
675 
676  m->mutex = new Mutex();
678  m->parseddesc = bte->md;
679  m->name = bte->name;
680  m->descriptor = bte->descriptor;
681 
682  /* return the newly created methodinfo */
683 
684  return m;
685 }
686 
687 
688 /* method_vftbl_lookup *********************************************************
689 
690  Does a method lookup in the passed virtual function table. This
691  function does exactly the same thing as JIT, but additionally
692  relies on the fact, that the methodinfo pointer is at the first
693  data segment slot (even for compiler stubs).
694 
695 *******************************************************************************/
696 
698 {
699  methodptr mptr;
700  methodptr *pmptr;
701  methodinfo *resm; /* pointer to new resolved method */
702 
703  /* If the method is not an instance method, just return it. */
704 
705  if (m->flags & ACC_STATIC)
706  return m;
707 
708  assert(vftbl);
709 
710  /* Get the method from the virtual function table. Is this an
711  interface method? */
712 
713  if (m->clazz->flags & ACC_INTERFACE) {
714  pmptr = vftbl->interfacetable[-(m->clazz->index)];
715  mptr = pmptr[(m - m->clazz->methods)];
716  }
717  else {
718  mptr = vftbl->table[m->vftblindex];
719  }
720 
721  /* and now get the codeinfo pointer from the first data segment slot */
722 
723  resm = code_get_methodinfo_for_pv(mptr);
724 
725  return resm;
726 }
727 
728 
729 /* method_get_parametercount **************************************************
730 
731  Use the descriptor of a method to determine the number of parameters
732  of the method. The this pointer of non-static methods is not counted.
733 
734  IN:
735  m........the method of which the parameters should be counted
736 
737  RETURN VALUE:
738  The parameter count.
739 
740 *******************************************************************************/
741 
743 {
744  methoddesc *md; /* method descriptor of m */
745  int32_t paramcount = 0; /* the parameter count of m */
746 
747  md = m->parseddesc;
748 
749  /* is the descriptor fully parsed? */
750 
752 
753  paramcount = md->paramcount;
754 
755  /* skip `this' pointer */
756 
757  if (!(m->flags & ACC_STATIC)) {
758  --paramcount;
759  }
760 
761  return paramcount;
762 }
763 
764 
765 /* method_get_parametertypearray ***********************************************
766 
767  Use the descriptor of a method to generate a java.lang.Class array
768  which contains the classes of the parametertypes of the method.
769 
770  This function is called by java.lang.reflect.{Constructor,Method}.
771 
772 *******************************************************************************/
773 
775 {
776  methoddesc* md;
777  typedesc* paramtypes;
778  int32_t paramcount;
779  int32_t i;
780  classinfo* c;
781 
782  md = m->parseddesc;
783 
784  /* is the descriptor fully parsed? */
785 
787 
788  paramtypes = md->paramtypes;
789  paramcount = md->paramcount;
790 
791  /* skip `this' pointer */
792 
793  if (!(m->flags & ACC_STATIC)) {
794  paramtypes++;
795  paramcount--;
796  }
797 
798  /* create class-array */
799 
800  ClassArray ca(paramcount);
801 
802  if (ca.is_null())
803  return NULL;
804 
805  /* get classes */
806 
807  for (i = 0; i < paramcount; i++) {
808  if (!resolve_class_from_typedesc(&paramtypes[i], true, false, &c))
809  return NULL;
810 
811  ca.set_element(i, c);
812  }
813 
814  return ca.get_handle();
815 }
816 
817 
818 /* method_get_exceptionarray ***************************************************
819 
820  Get the exceptions which can be thrown by a method.
821 
822 *******************************************************************************/
823 
825 {
826  classinfo* c;
827  s4 i;
828 
829  /* create class-array */
830 
832 
833  if (ca.is_null())
834  return NULL;
835 
836  /* iterate over all exceptions and store the class in the array */
837 
838  for (i = 0; i < m->thrownexceptionscount; i++) {
840 
841  if (c == NULL)
842  return NULL;
843 
844  ca.set_element(i, c);
845  }
846 
847  return ca.get_handle();
848 }
849 
850 
851 /* method_returntype_get *******************************************************
852 
853  Get the return type of the method.
854 
855 *******************************************************************************/
856 
858 {
859  typedesc *td;
860  classinfo *c;
861 
862  td = &(m->parseddesc->returntype);
863 
864  if (!resolve_class_from_typedesc(td, true, false, &c))
865  return NULL;
866 
867  return c;
868 }
869 
870 
871 /* method_count_implementations ************************************************
872 
873  Count the implementations of a method in a class cone (a class and all its
874  subclasses.)
875 
876  IN:
877  m................the method to count
878  c................class at which to start the counting (this class and
879  all its subclasses will be searched)
880 
881  OUT:
882  *found...........if found != NULL, *found receives the method
883  implementation that was found. This value is only
884  meaningful if the return value is 1.
885 
886  RETURN VALUE:
887  the number of implementations found
888 
889 *******************************************************************************/
890 
892 {
893  s4 count;
894  methodinfo *mp;
895  methodinfo *mend;
896  classinfo *child;
897 
898  count = 0;
899 
900  mp = c->methods;
901  mend = mp + c->methodscount;
902 
903  for (; mp < mend; ++mp) {
904  if (method_canoverwrite(mp, m)) {
905  if (found)
906  *found = mp;
907  count++;
908  break;
909  }
910  }
911 
912  for (child = c->sub; child != NULL; child = child->nextsub) {
913  count += method_count_implementations(m, child, found);
914  }
915 
916  return count;
917 }
918 
919 
920 /* method_get_annotations ******************************************************
921 
922  Get a methods' unparsed annotations in a byte array.
923 
924  IN:
925  m........the method of which the annotations should be returned
926 
927  RETURN VALUE:
928  The unparsed annotations in a byte array (or NULL if there aren't any).
929 
930 *******************************************************************************/
931 
933 {
934 #if defined(ENABLE_ANNOTATIONS)
935  classinfo *c; /* methods' declaring class */
936  int slot; /* methods' slot */
937  java_handle_t *method_annotations; /* all methods' unparsed annotations */
938  /* of the declaring class */
939 
940  c = m->clazz;
941  slot = m - c->methods;
942 
943  LLNI_classinfo_field_get(c, method_annotations, method_annotations);
944 
945  ObjectArray oa((java_handle_objectarray_t*) method_annotations);
946 
947  /* the method_annotations array might be shorter then the method
948  * count if the methods above a certain index have no annotations.
949  */
950  if (method_annotations != NULL && oa.get_length() > slot) {
951  return (java_handle_bytearray_t*) oa.get_element(slot);
952  } else {
953  return NULL;
954  }
955 #else
956  return NULL;
957 #endif
958 }
959 
960 
961 /* method_get_parameterannotations ********************************************
962 
963  Get a methods' unparsed parameter annotations in an array of byte
964  arrays.
965 
966  IN:
967  m........the method of which the parameter annotations should be
968  returned
969 
970  RETURN VALUE:
971  The unparsed parameter annotations in a byte array (or NULL if
972  there aren't any).
973 
974 *******************************************************************************/
975 
977 {
978 #if defined(ENABLE_ANNOTATIONS)
979  classinfo *c; /* methods' declaring class */
980  int slot; /* methods' slot */
981  java_handle_t *method_parameterannotations; /* all methods' unparsed */
982  /* parameter annotations of */
983  /* the declaring class */
984 
985  c = m->clazz;
986  slot = m - c->methods;
987 
989  c, method_parameterannotations, method_parameterannotations);
990 
991  ObjectArray oa((java_handle_objectarray_t*) method_parameterannotations);
992 
993  /* the method_annotations array might be shorter then the method
994  * count if the methods above a certain index have no annotations.
995  */
996  if (method_parameterannotations != NULL && oa.get_length() > slot) {
997  return (java_handle_bytearray_t*) oa.get_element(slot);
998  } else {
999  return NULL;
1000  }
1001 #else
1002  return NULL;
1003 #endif
1004 }
1005 
1006 
1007 /* method_get_annotationdefault ***********************************************
1008 
1009  Get a methods' unparsed annotation default value in a byte array.
1010 
1011  IN:
1012  m........the method of which the annotation default value should be
1013  returned
1014 
1015  RETURN VALUE:
1016  The unparsed annotation default value in a byte array (or NULL if
1017  there isn't one).
1018 
1019 *******************************************************************************/
1020 
1022 {
1023 #if defined(ENABLE_ANNOTATIONS)
1024  classinfo *c; /* methods' declaring class */
1025  int slot; /* methods' slot */
1026  java_handle_t *method_annotationdefaults; /* all methods' unparsed */
1027  /* annotation default values of */
1028  /* the declaring class */
1029 
1030  c = m->clazz;
1031  slot = m - c->methods;
1032 
1034  c, method_annotationdefaults, method_annotationdefaults);
1035 
1036  ObjectArray oa((java_handle_objectarray_t*) method_annotationdefaults);
1037 
1038  /* the method_annotations array might be shorter then the method
1039  * count if the methods above a certain index have no annotations.
1040  */
1041  if (method_annotationdefaults != NULL && oa.get_length() > slot) {
1042  return (java_handle_bytearray_t*) oa.get_element(slot);
1043  } else {
1044  return NULL;
1045  }
1046 #else
1047  return NULL;
1048 #endif
1049 }
1050 
1051 
1052 /* method_add_to_worklist ******************************************************
1053 
1054  Add the method to the given worklist. If the method already occurs in
1055  the worklist, the worklist remains unchanged.
1056 
1057 *******************************************************************************/
1058 
1060 {
1061  method_worklist *wi;
1062 
1063  for (wi = *wl; wi != NULL; wi = wi->next)
1064  if (wi->m == m)
1065  return;
1066 
1067  wi = NEW(method_worklist);
1068  wi->next = *wl;
1069  wi->m = m;
1070 
1071  *wl = wi;
1072 }
1073 
1074 
1075 /* method_add_assumption_monomorphic *******************************************
1076 
1077  Record the assumption that the method is monomorphic.
1078 
1079  IN:
1080  m.................the method
1081  caller............the caller making the assumption
1082 
1083 *******************************************************************************/
1084 
1086 {
1087  method_assumption *as;
1088 
1089  /* XXX LOCKING FOR THIS FUNCTION? */
1090 
1091  /* check if we already have registered this assumption */
1092 
1093  for (as = m->assumptions; as != NULL; as = as->next) {
1094  if (as->context == caller)
1095  return;
1096  }
1097 
1098  /* register the assumption */
1099 
1100  as = NEW(method_assumption);
1101  as->next = m->assumptions;
1102  as->context = caller;
1103 
1104  m->assumptions = as;
1105 }
1106 
1107 /* method_break_assumption_monomorphic *****************************************
1108 
1109  Break the assumption that this method is monomorphic. All callers that
1110  have registered this assumption are added to the worklist.
1111 
1112  IN:
1113  m.................the method
1114  wl................worklist where to add invalidated callers
1115 
1116 *******************************************************************************/
1117 
1119 {
1120  method_assumption *as;
1121 
1122  /* XXX LOCKING FOR THIS FUNCTION? */
1123 
1124  for (as = m->assumptions; as != NULL; as = as->next) {
1125  INLINELOG(
1126  printf("ASSUMPTION BROKEN (monomorphism): ");
1127  method_print(m);
1128  printf(" in ");
1129  method_println(as->context);
1130  );
1131 
1133 
1134 #if defined(ENABLE_TLH) && 0
1135  /* XXX hack */
1136  method_assumption *as2;
1137  as2 = m->assumptions;
1138  m->assumptions = NULL;
1140  /*
1141  assert(m->assumptions == NULL);
1142  m->assumptions = as2;*/
1143 #endif
1144 
1145  }
1146 }
1147 
1148 /* method_printflags ***********************************************************
1149 
1150  Prints the flags of a method to stdout like.
1151 
1152 *******************************************************************************/
1153 
1154 #if !defined(NDEBUG)
1156 {
1157  if (m == NULL) {
1158  printf("NULL");
1159  return;
1160  }
1161 
1162  if (m->flags & ACC_PUBLIC) printf(" PUBLIC");
1163  if (m->flags & ACC_PRIVATE) printf(" PRIVATE");
1164  if (m->flags & ACC_PROTECTED) printf(" PROTECTED");
1165  if (m->flags & ACC_STATIC) printf(" STATIC");
1166  if (m->flags & ACC_FINAL) printf(" FINAL");
1167  if (m->flags & ACC_SYNCHRONIZED) printf(" SYNCHRONIZED");
1168  if (m->flags & ACC_VOLATILE) printf(" VOLATILE");
1169  if (m->flags & ACC_TRANSIENT) printf(" TRANSIENT");
1170  if (m->flags & ACC_NATIVE) printf(" NATIVE");
1171  if (m->flags & ACC_INTERFACE) printf(" INTERFACE");
1172  if (m->flags & ACC_ABSTRACT) printf(" ABSTRACT");
1173  if (m->flags & ACC_METHOD_BUILTIN) printf(" (builtin)");
1174  if (m->flags & ACC_METHOD_MONOMORPHIC) printf(" (mono)");
1175  if (m->flags & ACC_METHOD_IMPLEMENTED) printf(" (impl)");
1176 }
1177 #endif /* !defined(NDEBUG) */
1178 
1179 
1180 /* method_print ****************************************************************
1181 
1182  Prints a method to stdout like:
1183 
1184  java.lang.Object.<init>()V
1185 
1186 *******************************************************************************/
1187 
1188 #if !defined(NDEBUG)
1190 {
1191  if (m == NULL) {
1192  printf("NULL");
1193  return;
1194  }
1195 
1196  if (m->clazz != NULL)
1198  else
1199  printf("NULL");
1200  printf(".");
1203 
1204  method_printflags(m);
1205 }
1206 #endif /* !defined(NDEBUG) */
1207 
1208 
1209 /* method_println **************************************************************
1210 
1211  Prints a method plus new line to stdout like:
1212 
1213  java.lang.Object.<init>()V
1214 
1215 *******************************************************************************/
1216 
1217 #if !defined(NDEBUG)
1219 {
1220  if (opt_debugcolor) printf("\033[31m"); /* red */
1221  method_print(m);
1222  if (opt_debugcolor) printf("\033[m");
1223  printf("\n");
1224 }
1225 #endif /* !defined(NDEBUG) */
1226 
1227 
1228 /* method_methodref_print ******************************************************
1229 
1230  Prints a method reference to stdout.
1231 
1232 *******************************************************************************/
1233 
1234 #if !defined(NDEBUG)
1236 {
1237  if (!mr) {
1238  printf("(constant_FMIref *)NULL");
1239  return;
1240  }
1241 
1242  if (mr->is_resolved()) {
1243  printf("<method> ");
1244  method_print(mr->p.method);
1245  }
1246  else {
1247  printf("<methodref> ");
1249  printf(".");
1252  }
1253 }
1254 #endif /* !defined(NDEBUG) */
1255 
1256 
1257 /* method_methodref_println ****************************************************
1258 
1259  Prints a method reference to stdout, followed by a newline.
1260 
1261 *******************************************************************************/
1262 
1263 #if !defined(NDEBUG)
1265 {
1267  printf("\n");
1268 }
1269 #endif /* !defined(NDEBUG) */
1270 
1271 bool method_matches(methodinfo *m, const char* name) {
1272  if (!m || !name)
1273  return false;
1274  return m->name == Utf8String::from_utf8(name);
1275 }
1276 
1277 namespace cacao {
1278 namespace {
1279 
1280 inline OStream& method_printflags_OS(OStream &OS, const struct methodinfo &m)
1281 {
1282  if (m.flags & ACC_PUBLIC) OS << " PUBLIC" ;
1283  if (m.flags & ACC_PRIVATE) OS << " PRIVATE" ;
1284  if (m.flags & ACC_PROTECTED) OS << " PROTECTED" ;
1285  if (m.flags & ACC_STATIC) OS << " STATIC" ;
1286  if (m.flags & ACC_FINAL) OS << " FINAL" ;
1287  if (m.flags & ACC_SYNCHRONIZED) OS << " SYNCHRONIZED" ;
1288  if (m.flags & ACC_VOLATILE) OS << " VOLATILE" ;
1289  if (m.flags & ACC_TRANSIENT) OS << " TRANSIENT" ;
1290  if (m.flags & ACC_NATIVE) OS << " NATIVE" ;
1291  if (m.flags & ACC_INTERFACE) OS << " INTERFACE" ;
1292  if (m.flags & ACC_ABSTRACT) OS << " ABSTRACT" ;
1293  if (m.flags & ACC_METHOD_BUILTIN) OS << " (builtin)" ;
1294  if (m.flags & ACC_METHOD_MONOMORPHIC) OS << " (mono)" ;
1295  if (m.flags & ACC_METHOD_IMPLEMENTED) OS << " (impl)" ;
1296  return OS;
1297 }
1298 } // end anonymous namespace
1299 
1300 OStream& operator<<(OStream &OS, const struct methodinfo &m)
1301 {
1302  OS << (Utf8String)m.clazz->name << "."
1303  << (Utf8String)m.name
1304  << (Utf8String)m.descriptor;
1305  method_printflags_OS(OS,m);
1306  return OS;
1307 }
1308 
1309 } // end namespace cacao
1310 
1311 /*
1312  * These are local overrides for various environment variables in Emacs.
1313  * Please do not remove this and leave it at the end of the file, where
1314  * Emacs will automagically detect them.
1315  * ---------------------------------------------------------------------
1316  * Local variables:
1317  * mode: c++
1318  * indent-tabs-mode: t
1319  * c-basic-offset: 4
1320  * tab-width: 4
1321  * End:
1322  * vim:noexpandtab:sw=4:ts=4:
1323  */
methodptr * interfacetable[1]
Definition: vftbl.hpp:99
Utf8String name
Definition: method.hpp:71
jlong jlong jlong jlong jint jmethodID jint slot
Definition: jvmti.h:497
#define mptr
Definition: md-asm.hpp:66
void method_break_assumption_monomorphic(methodinfo *m, method_worklist **wl)
Definition: method.cpp:1118
void method_free(methodinfo *m)
Definition: method.cpp:608
#define STATISTICS(x)
Wrapper for statistics only code.
Definition: statistics.hpp:975
bool method_load(ClassBuffer &cb, methodinfo *m, DescriptorPool &descpool)
Definition: method.cpp:162
void * class_getconstant(classinfo *c, u4 pos, ConstantPoolTag ctype)
Definition: class.cpp:679
void method_print(methodinfo *m)
Definition: method.cpp:1189
#define STAT_REGISTER_SUM_SUBGROUP(var, name, description, group)
Register a statistics summary group.
Definition: statistics.hpp:973
s4 jcodelength
Definition: method.hpp:85
methoddesc * md
Definition: builtin.hpp:71
methodinfo * code_get_methodinfo_for_pv(void *pv)
Definition: code.cpp:150
bool annotation_load_method_attribute_runtimevisibleparameterannotations(ClassBuffer &cb, methodinfo *m)
Definition: annotation.cpp:316
methodinfo * methods
Definition: class.hpp:113
#define NEW(type)
Definition: memory.hpp:93
bool annotation_load_method_attribute_runtimevisibleannotations(ClassBuffer &cb, methodinfo *m)
Definition: annotation.cpp:458
classinfo * nextsub
Definition: class.hpp:104
void method_init(void)
Definition: method.cpp:99
virtual java_handle_array_t * get_handle() const
Definition: array.hpp:103
s4 rawexceptiontablelength
Definition: method.hpp:88
method_assumption * assumptions
Definition: method.hpp:110
void utf_display_printable_ascii_classname(Utf8String u)
Definition: utf8.cpp:552
static void remove(void *stub)
Free a compiler stub from memory.
Definition: stubs.cpp:155
java_handle_bytearray_t * method_get_annotations(methodinfo *m)
Definition: method.cpp:932
Actual implementation of access class for Java Object arrays.
Definition: array.hpp:381
methodinfo * method_vftbl_lookup(vftbl_t *vftbl, methodinfo *m)
Definition: method.cpp:697
#define INLINELOG(code)
Definition: method.cpp:71
typedef void(JNICALL *jvmtiEventSingleStep)(jvmtiEnv *jvmti_env
T get_element(int32_t index)
Definition: array.hpp:238
union constant_FMIref::@26 p
static void usage()
Definition: VMjdwp.cpp:377
Dummy implementation of a mutex.
Definition: mutex-none.hpp:33
method_assumption * next
Definition: method.hpp:134
void exceptions_throw_classformaterror(classinfo *c, const char *message,...)
Definition: exceptions.cpp:634
u2 startpc
Definition: method.hpp:157
uint8_t u1
Definition: types.hpp:40
u1 * methodptr
Definition: global.hpp:40
method_worklist * next
Definition: method.hpp:146
methodinfo * method_new_builtin(builtintable_entry *bte)
Definition: method.cpp:664
JNIEnv jclass jobject const char * name
Definition: jvmti.h:312
void set_element(int32_t index, T value)
Definition: array.hpp:255
methodinfo * method
Definition: references.hpp:101
java_handle_objectarray_t * method_get_parametertypearray(methodinfo *m)
Definition: method.cpp:774
const Utf8String name
Definition: references.hpp:103
int32_t method_get_parametercount(methodinfo *m)
Definition: method.cpp:742
methodinfo * class_findmethod(classinfo *c, Utf8String name, Utf8String desc)
Definition: class.cpp:1124
Utf8String signature
Definition: method.hpp:74
bool resolve_class_from_typedesc(typedesc *d, bool checkaccess, bool link, classinfo **result)
Definition: resolve.cpp:473
classref_or_classinfo catchtype
Definition: method.hpp:156
JNIEnv jthread jobject jclass jlong size
Definition: jvmti.h:387
u2 endpc
Definition: method.hpp:158
#define MZERO(ptr, type, num)
Definition: memory.hpp:105
bool loader_skip_attribute_body(ClassBuffer &cb)
Definition: loader.cpp:499
void code_free_code_of_method(methodinfo *m)
Definition: code.cpp:249
void vm_abort(const char *text,...)
Definition: vm.cpp:2586
methodinfo * context
Definition: method.hpp:135
Utf8String descriptor
Definition: builtin.hpp:70
typedesc paramtypes[1]
Definition: descriptor.hpp:167
bool opt_debugcolor
Definition: options.cpp:68
raw_exception_entry * rawexceptiontable
Definition: method.hpp:89
bool stackmap_load_attribute_stackmaptable(ClassBuffer &cb, methodinfo *m)
Definition: stackmap.cpp:405
s4 method_count_implementations(methodinfo *m, classinfo *c, methodinfo **found)
Definition: method.cpp:891
Utf8String name
Definition: builtin.hpp:69
JNIEnv jthread jmethodID jlocation jobject exception
Definition: jvmti.h:272
Utf8String descriptor
Definition: method.hpp:72
uint16_t read_u2()
Definition: suck.hpp:150
bool annotation_load_method_attribute_annotationdefault(ClassBuffer &cb, methodinfo *m)
Definition: annotation.cpp:257
u1 * stubroutine
Definition: method.hpp:102
s4 vftblindex
Definition: method.hpp:81
bool is_resolved() const
Definition: references.hpp:107
int32_t get_length() const
Definition: array.hpp:189
uint16_t u2
Definition: types.hpp:43
internally used tags
Definition: global.hpp:180
void method_printflags(methodinfo *m)
Definition: method.cpp:1155
u2 handlerpc
Definition: method.hpp:159
void method_println(methodinfo *m)
Definition: method.cpp:1218
classinfo * clazz
Definition: method.hpp:80
This file contains the statistics framework.
classinfo * sub
Definition: class.hpp:103
Utf8String name
Definition: class.hpp:91
Definition: method.hpp:155
#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
Simple stream class for formatted output.
Definition: OStream.hpp:141
bool is_valid_name() const
Definition: utf8.cpp:393
classinfo * class_java_lang_reflect_Method
Definition: globals.cpp:83
bool method_matches(methodinfo *m, const char *name)
Definition: method.cpp:1271
void read_nbytes(uint8_t *dst, size_t num_bytes)
Transfer block of classfile into a buffer.
Definition: suck.hpp:186
s4 flags
Definition: class.hpp:90
u2 linenumbercount
Definition: method.hpp:94
static Utf8String from_utf8(const char *, size_t)
Definition: utf8.cpp:335
u1 * jcode
Definition: method.hpp:86
s4 maxstack
Definition: method.hpp:83
MIIterator i
Fieldref, Methodref and InterfaceMethodref.
Definition: references.hpp:86
typedesc returntype
Definition: descriptor.hpp:166
int32_t s4
Definition: types.hpp:45
#define LLNI_classinfo_field_get(cls, field, variable)
Definition: llni.hpp:82
s4 maxlocals
Definition: method.hpp:84
classinfo * method_returntype_get(methodinfo *m)
Definition: method.cpp:857
s4 index
Definition: class.hpp:116
const Utf8String descriptor
Definition: references.hpp:104
OStream & OS
bool annotation_load_method_attribute_runtimeinvisibleannotations(ClassBuffer &cb, methodinfo *m)
Definition: annotation.cpp:507
Mutex * mutex
Definition: method.hpp:69
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
OStream & operator<<(OStream &OS, const std::string &t)
Definition: OStream.hpp:459
bool opt_verify
Definition: options.cpp:103
uint32_t read_u4()
Definition: suck.hpp:155
void utf_display_printable_ascii(Utf8String u)
Definition: utf8.cpp:532
uint32_t u4
Definition: types.hpp:46
u2 line_number
Definition: method.hpp:167
u2 thrownexceptionscount
Definition: method.hpp:91
classinfo * get_class() const
Definition: suck.hpp:117
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
Definition: builtin.hpp:60
#define MNEW(type, num)
Definition: memory.hpp:96
u2 start_pc
Definition: method.hpp:166
void method_methodref_print(constant_FMIref *mr)
Definition: method.cpp:1235
static void method_add_to_worklist(methodinfo *m, method_worklist **wl)
Definition: method.cpp:1059
#define STAT_DECLARE_GROUP(var)
Declare an external group (or subgroup).
Definition: statistics.hpp:970
classref_or_classinfo * thrownexceptions
Definition: method.hpp:92
constant_classref * classref
Definition: references.hpp:97
java_handle_bytearray_t * method_get_annotationdefault(methodinfo *m)
Definition: method.cpp:1021
bool check_size(size_t sz)
Assert that at least &lt;sz&gt; bytes are left to read.
Definition: suck.hpp:135
static void remove(void *stub)
Free a native stub from memory.
Definition: stubs.cpp:413
lineinfo * linenumbers
Definition: method.hpp:95
BreakpointTable * breakpoints
Definition: method.hpp:112
void method_add_assumption_monomorphic(methodinfo *m, methodinfo *caller)
Definition: method.cpp:1085
methodptr table[1]
Definition: vftbl.hpp:116
void method_methodref_println(constant_FMIref *mr)
Definition: method.cpp:1264
s4 flags
Definition: method.hpp:70
methodinfo * method_java_lang_reflect_Method_invoke
classinfo * resolve_classref_or_classinfo_eager(classref_or_classinfo cls, bool checkaccess)
Definition: resolve.cpp:437
bool is_null() const
Definition: array.hpp:203
java_handle_objectarray_t * method_get_exceptionarray(methodinfo *m)
Definition: method.cpp:824
#define STAT_REGISTER_VAR(type, var, init, name, description)
Register an external statistics variable.
Definition: statistics.hpp:966
#define STAT_DECLARE_VAR(type, var, init)
Declare an external statistics variable.
Definition: statistics.hpp:963
Actual implementation of access class for java.lang.Class arrays.
Definition: array.hpp:391
#define MFREE(ptr, type, num)
Definition: memory.hpp:97
const Utf8String name
Definition: references.hpp:48
#define printf(...)
Definition: ssa2.cpp:40
java_handle_bytearray_t * method_get_parameterannotations(methodinfo *m)
Definition: method.cpp:976
bool method_canoverwrite(methodinfo *m, methodinfo *old)
Definition: method.cpp:642
methodinfo * m
Definition: method.hpp:147
bool annotation_load_method_attribute_runtimeinvisibleparameterannotations(ClassBuffer &cb, methodinfo *m)
Definition: annotation.cpp:394