1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2 * This source file is part of SableVM. *
3 * *
4 * See the file "LICENSE" for the copyright information and for *
5 * the terms and conditions for copying, distribution and *
6 * modification of this source file. *
7 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
8
9 /*
10 ----------------------------------------------------------------------
11 _svmf_prepare_interface_instanceof
12 ----------------------------------------------------------------------
13 */
14
15 svm_static jint
_svmf_prepare_interface_instanceof(_svmt_JNIEnv * env,_svmt_class_info * interface)16 _svmf_prepare_interface_instanceof (_svmt_JNIEnv *env,
17 _svmt_class_info *interface)
18 {
19 _svmt_JavaVM *vm = env->vm;
20 jint i;
21
22 interface->data.interface.interface_id =
23 vm->class_loading.next_interface_id++;
24
25 if (vm->class_loading.next_interface_id < 0)
26 {
27 /* we have exhausted the number of interfaces!!! Quite unlikely to
28 happen as OutOfMemory error is more likely to happen before this. */
29 _svmf_error_InternalError (env);
30 return JNI_ERR;
31 }
32
33 if (_svmm_cl_zmalloc_super_interfaces
34 (env, interface->class_loader_info,
35 (interface->data.interface.interface_id / 8) + 1,
36 interface->data.interface.super_interfaces) != JNI_OK)
37 {
38 _svmf_error_OutOfMemoryError (env);
39 return JNI_ERR;
40 }
41
42 /* interfaces have no super class other than java.lang.Object which
43 implements no interface. */
44
45 for (i = 0; i < interface->interfaces_count; i++)
46 {
47 _svmt_class_info *super_interface =
48 _svmf_cast_class (DREF (interface->interfaces[i], type));
49 jint bytes = (super_interface->data.interface.interface_id / 8) + 1;
50 jint j;
51
52 for (j = 0; j < bytes; j++)
53 {
54 interface->data.interface.super_interfaces[j] |=
55 super_interface->data.interface.super_interfaces[j];
56 }
57 }
58
59 _svmf_set_bit (interface->data.interface.super_interfaces,
60 interface->data.interface.interface_id);
61
62 return JNI_OK;
63 }
64
65 /*
66 ----------------------------------------------------------------------
67 _svmf_prepare_noninterface_instanceof
68 ----------------------------------------------------------------------
69 */
70
71 svm_static jint
_svmf_prepare_noninterface_instanceof(_svmt_JNIEnv * env,_svmt_class_info * class)72 _svmf_prepare_noninterface_instanceof (_svmt_JNIEnv *env,
73 _svmt_class_info *class)
74 {
75 if (CAN_DREF (class->super_class))
76 {
77 jint i;
78 _svmt_class_info *super_class =
79 _svmf_cast_class (DREF (class->super_class, type));
80
81 class->data.noninterface.super_classes_size =
82 super_class->data.noninterface.super_classes_size + 1;
83
84 if (class->data.noninterface.super_classes_size < 0)
85 {
86 _svmf_error_InternalError (env);
87 return JNI_ERR;
88 }
89
90 if (_svmm_cl_malloc_super_classes
91 (env, class->class_loader_info,
92 class->data.noninterface.super_classes_size,
93 class->data.noninterface.super_classes) != JNI_OK)
94 {
95 return JNI_ERR;
96 }
97
98 for (i = 0; i < super_class->data.noninterface.super_classes_size; i++)
99 {
100 class->data.noninterface.super_classes[i] =
101 super_class->data.noninterface.super_classes[i];
102 }
103
104 class->data.noninterface.super_classes[i] = class;
105
106 class->data.noninterface.max_interface_id =
107 super_class->data.noninterface.max_interface_id;
108 }
109 else
110 {
111 class->data.noninterface.super_classes_size = 1;
112
113 if (_svmm_cl_malloc_super_classes
114 (env, class->class_loader_info,
115 class->data.noninterface.super_classes_size,
116 class->data.noninterface.super_classes) != JNI_OK)
117 {
118 return JNI_ERR;
119 }
120
121 class->data.noninterface.super_classes[0] = class;
122
123 class->data.noninterface.max_interface_id = -1;
124 }
125
126 {
127 jint i;
128
129 for (i = 0; i < class->interfaces_count; i++)
130 {
131 _svmt_class_info *super_interface =
132 _svmf_cast_class (DREF (class->interfaces[i], type));
133
134 class->data.noninterface.max_interface_id =
135 _svmf_max_jint
136 (class->data.noninterface.max_interface_id,
137 super_interface->data.interface.interface_id);
138 }
139
140 if (class->data.noninterface.max_interface_id >= 0)
141 {
142 if (_svmm_cl_zmalloc_super_interfaces
143 (env, class->class_loader_info,
144 (class->data.noninterface.max_interface_id / 8) + 1,
145 class->data.noninterface.super_interfaces) != JNI_OK)
146 {
147 return JNI_ERR;
148 }
149
150 if (CAN_DREF (class->super_class))
151 {
152 _svmt_class_info *super_class =
153 _svmf_cast_class (DREF (class->super_class, type));
154
155 if (super_class->data.noninterface.max_interface_id >= 0)
156 {
157 jint bytes =
158 (super_class->data.noninterface.max_interface_id / 8) + 1;
159 jint j;
160
161 for (j = 0; j < bytes; j++)
162 {
163 class->data.noninterface.super_interfaces[j] |=
164 super_class->data.noninterface.super_interfaces[j];
165 }
166 }
167 }
168
169 for (i = 0; i < class->interfaces_count; i++)
170 {
171 _svmt_class_info *super_interface =
172 _svmf_cast_class (DREF (class->interfaces[i], type));
173 jint bytes =
174 (super_interface->data.interface.interface_id / 8) + 1;
175 jint j;
176
177 for (j = 0; j < bytes; j++)
178 {
179 class->data.noninterface.super_interfaces[j] |=
180 super_interface->data.interface.super_interfaces[j];
181 }
182 }
183 }
184 }
185
186 return JNI_OK;
187 }
188
189 /*
190 ----------------------------------------------------------------------
191 _svmf_prepare_interface_fields
192 ----------------------------------------------------------------------
193 */
194
195 svm_static jint
_svmf_prepare_interface_fields(_svmt_JNIEnv * env,_svmt_class_info * class)196 _svmf_prepare_interface_fields (_svmt_JNIEnv *env, _svmt_class_info *class)
197 {
198 jint i;
199 jint size = class->fields_count;
200
201 for (i = 0; i < size; i++)
202 {
203 jchar c = DREF (class->fields[i].descriptor, value)[0];
204
205 assert (_svmf_is_set_flag
206 (class->fields[i].access_flags, SVM_ACC_STATIC));
207
208 class->fields[i].class_info = class;
209
210 switch (c)
211 {
212 default:
213 {
214 _svmm_fatal_error ("impossible control flow");
215 }
216 break;
217
218 case (_svmt_u8) 'Z':
219 {
220 class->fields[i].type = SVM_TYPE_BOOLEAN;
221 }
222 break;
223
224 case (_svmt_u8) 'B':
225 {
226 class->fields[i].type = SVM_TYPE_BYTE;
227 }
228 break;
229
230 case (_svmt_u8) 'S':
231 {
232 class->fields[i].type = SVM_TYPE_SHORT;
233 }
234 break;
235
236 case (_svmt_u8) 'C':
237 {
238 class->fields[i].type = SVM_TYPE_CHAR;
239 }
240 break;
241
242 case (_svmt_u8) 'I':
243 {
244 class->fields[i].type = SVM_TYPE_INT;
245 }
246 break;
247
248 case (_svmt_u8) 'J':
249 {
250 class->fields[i].type = SVM_TYPE_LONG;
251 }
252 break;
253
254 case (_svmt_u8) 'F':
255 {
256 class->fields[i].type = SVM_TYPE_FLOAT;
257 }
258 break;
259
260 case (_svmt_u8) 'D':
261 {
262 class->fields[i].type = SVM_TYPE_DOUBLE;
263 }
264 break;
265
266 case (_svmt_u8) 'L':
267 case (_svmt_u8) '[':
268 {
269 class->fields[i].type = SVM_TYPE_REFERENCE;
270 }
271 break;
272 }
273
274 /* if reference, allocate native global */
275 if (class->fields[i].type == SVM_TYPE_REFERENCE)
276 {
277 if (_svmm_new_native_global
278 (env, class->fields[i].data.class_field.value.l) != JNI_OK)
279 {
280 return JNI_ERR;
281 }
282 }
283 }
284
285 return JNI_OK;
286 }
287
288 /*
289 ----------------------------------------------------------------------
290 _svmf_save_instance_free_space
291 ----------------------------------------------------------------------
292 */
293
294 svm_static void
_svmf_save_instance_free_space(_svmt_class_info * class,size_t size,size_t offset)295 _svmf_save_instance_free_space (_svmt_class_info *class, size_t size,
296 size_t offset)
297 {
298 jint i;
299 size_t power;
300
301 for (i = 0, power = 2; i < SVM_ALIGNMENT_POWER; i++, power *= 2)
302 {
303 if (size % power != 0)
304 {
305 assert (class->data.noninterface.free_space_offset[i] == 0);
306
307 class->data.noninterface.free_space_offset[i] = offset;
308 offset += power / 2;
309 size -= power / 2;
310 }
311 }
312 }
313
314 /*
315 ----------------------------------------------------------------------
316 _svmf_get_instance_free_space
317 ----------------------------------------------------------------------
318 */
319
320 svm_static size_t
_svmf_get_instance_free_space(_svmt_class_info * class,size_t size)321 _svmf_get_instance_free_space (_svmt_class_info *class, size_t size)
322 {
323 jint i;
324 size_t power;
325 size_t offset;
326
327 if (size >= SVM_ALIGNMENT)
328 {
329 assert (size % SVM_ALIGNMENT == 0);
330
331 offset = class->data.noninterface.next_offset_no_hashcode;
332 class->data.noninterface.next_offset_no_hashcode += size;
333 return offset;
334 }
335
336 for (i = 0, power = 1; i < SVM_ALIGNMENT_POWER; i++, power *= 2)
337 {
338 if (size == power)
339 {
340 break;
341 }
342 }
343
344 assert (i < SVM_ALIGNMENT_POWER);
345
346 for (; i < SVM_ALIGNMENT_POWER; i++, power *= 2)
347 {
348 offset = class->data.noninterface.free_space_offset[i];
349
350 if (offset != 0)
351 {
352 class->data.noninterface.free_space_offset[i] = 0;
353 _svmf_save_instance_free_space (class, power - size, offset + size);
354 return offset;
355 }
356 }
357
358 offset = class->data.noninterface.next_offset_no_hashcode;
359 class->data.noninterface.next_offset_no_hashcode += SVM_ALIGNMENT;
360 _svmf_save_instance_free_space (class, SVM_ALIGNMENT - size, offset + size);
361 return offset;
362 }
363
364 /*
365 ----------------------------------------------------------------------
366 _svmf_prepare_noninterface_fields
367 ----------------------------------------------------------------------
368 */
369
370 svm_static jint
_svmf_prepare_noninterface_fields(_svmt_JNIEnv * env,_svmt_class_info * class)371 _svmf_prepare_noninterface_fields (_svmt_JNIEnv *env, _svmt_class_info *class)
372 {
373 if (CAN_DREF (class->super_class))
374 {
375 _svmt_class_info *super_class =
376 _svmf_cast_class (DREF (class->super_class, type));
377 jint i;
378
379 class->data.noninterface.next_offset_no_hashcode =
380 super_class->data.noninterface.next_offset_no_hashcode;
381
382 #if defined (_SABLEVM_BIDIRECTIONAL_OBJECT_LAYOUT)
383
384 class->data.noninterface.start_offset =
385 super_class->data.noninterface.start_offset;
386 class->data.noninterface.ref_field_count =
387 super_class->data.noninterface.ref_field_count;
388
389 #elif defined(_SABLEVM_TRADITIONAL_OBJECT_LAYOUT)
390
391 class->data.noninterface.ref_field_count =
392 super_class->data.noninterface.ref_field_count;
393
394 #endif /* defined (_SABLEVM_BIDIRECTIONAL_OBJECT_LAYOUT) */
395
396 class->data.noninterface.free_bits_count =
397 super_class->data.noninterface.free_bits_count;
398 class->data.noninterface.free_bits_offset =
399 super_class->data.noninterface.free_bits_offset;
400
401 for (i = 0; i < SVM_ALIGNMENT_POWER; i++)
402 {
403 class->data.noninterface.free_space_offset[i] =
404 super_class->data.noninterface.free_space_offset[i];
405 }
406 }
407 else
408 {
409 class->data.noninterface.next_offset_no_hashcode =
410 _svmf_aligned_size_t (sizeof (_svmt_object_instance));
411 }
412
413 {
414 jint i;
415 jint size = class->fields_count;
416
417 for (i = 0; i < size; i++)
418 {
419 jchar c = DREF (class->fields[i].descriptor, value)[0];
420
421 class->fields[i].class_info = class;
422
423 switch (c)
424 {
425 default:
426 {
427 _svmm_fatal_error ("impossible control flow");
428 }
429 break;
430
431 case (_svmt_u8) 'Z':
432 {
433 class->fields[i].type = SVM_TYPE_BOOLEAN;
434 }
435 break;
436
437 case (_svmt_u8) 'B':
438 {
439 class->fields[i].type = SVM_TYPE_BYTE;
440 }
441 break;
442
443 case (_svmt_u8) 'S':
444 {
445 class->fields[i].type = SVM_TYPE_SHORT;
446 }
447 break;
448
449 case (_svmt_u8) 'C':
450 {
451 class->fields[i].type = SVM_TYPE_CHAR;
452 }
453 break;
454
455 case (_svmt_u8) 'I':
456 {
457 class->fields[i].type = SVM_TYPE_INT;
458 }
459 break;
460
461 case (_svmt_u8) 'J':
462 {
463 class->fields[i].type = SVM_TYPE_LONG;
464 }
465 break;
466
467 case (_svmt_u8) 'F':
468 {
469 class->fields[i].type = SVM_TYPE_FLOAT;
470 }
471 break;
472
473 case (_svmt_u8) 'D':
474 {
475 class->fields[i].type = SVM_TYPE_DOUBLE;
476 }
477 break;
478
479 case (_svmt_u8) 'L':
480 case (_svmt_u8) '[':
481 {
482 class->fields[i].type = SVM_TYPE_REFERENCE;
483 }
484 break;
485 }
486
487 if (_svmf_is_set_flag (class->fields[i].access_flags, SVM_ACC_STATIC))
488 {
489 /* if reference, allocate native global */
490 if (class->fields[i].type == SVM_TYPE_REFERENCE)
491 {
492 if (_svmm_new_native_global
493 (env,
494 class->fields[i].data.class_field.value.l) != JNI_OK)
495 {
496 return JNI_ERR;
497 }
498 }
499 }
500 else
501 {
502 switch (class->fields[i].type)
503 {
504 case SVM_TYPE_BOOLEAN:
505 {
506 if (class->data.noninterface.free_bits_count == 0)
507 {
508 class->data.noninterface.free_bits_count = 8;
509 class->data.noninterface.free_bits_offset =
510 _svmf_get_instance_free_space (class, 1);
511 }
512
513 /* offset of boolean fields calculated in bits */
514 class->fields[i].data.instance_field.offset =
515 --(class->data.noninterface.free_bits_count);
516 class->fields[i].data.instance_field.offset +=
517 8 * class->data.noninterface.free_bits_offset;
518 }
519 break;
520 case SVM_TYPE_BYTE:
521 {
522 class->fields[i].data.instance_field.offset =
523 _svmf_get_instance_free_space (class, 1);
524 }
525 break;
526 case SVM_TYPE_SHORT:
527 {
528 class->fields[i].data.instance_field.offset =
529 _svmf_get_instance_free_space (class, 2);
530 }
531 break;
532 case SVM_TYPE_CHAR:
533 {
534 class->fields[i].data.instance_field.offset =
535 _svmf_get_instance_free_space (class, 2);
536 }
537 break;
538 case SVM_TYPE_INT:
539 {
540 class->fields[i].data.instance_field.offset =
541 _svmf_get_instance_free_space (class, 4);
542 }
543 break;
544 case SVM_TYPE_LONG:
545 {
546 class->fields[i].data.instance_field.offset =
547 _svmf_get_instance_free_space (class, 8);
548 }
549 break;
550 case SVM_TYPE_FLOAT:
551 {
552 class->fields[i].data.instance_field.offset =
553 _svmf_get_instance_free_space (class, 4);
554 }
555 break;
556 case SVM_TYPE_DOUBLE:
557 {
558 class->fields[i].data.instance_field.offset =
559 _svmf_get_instance_free_space (class, 8);
560 }
561 break;
562 case SVM_TYPE_REFERENCE:
563 {
564 #if defined (_SABLEVM_BIDIRECTIONAL_OBJECT_LAYOUT)
565
566 class->fields[i].data.instance_field.offset = 0 -
567 ((++(class->data.noninterface.ref_field_count)) *
568 sizeof (void *));
569
570 if (class->data.noninterface.ref_field_count < 0)
571 {
572 _svmf_error_InternalError (env);
573 return JNI_ERR;
574 }
575
576 #elif defined(_SABLEVM_TRADITIONAL_OBJECT_LAYOUT)
577
578 class->fields[i].data.instance_field.offset =
579 _svmf_get_instance_free_space (class, sizeof (void *));
580 class->data.noninterface.ref_field_count++;
581
582 if (class->data.noninterface.ref_field_count < 0)
583 {
584 _svmf_error_InternalError (env);
585 return JNI_ERR;
586 }
587
588 #endif /* defined (_SABLEVM_BIDIRECTIONAL_OBJECT_LAYOUT) */
589 }
590 break;
591 }
592 }
593 }
594 }
595
596 #if defined (_SABLEVM_BIDIRECTIONAL_OBJECT_LAYOUT)
597
598 class->data.noninterface.start_offset =
599 _svmf_aligned_size_t (class->data.noninterface.ref_field_count *
600 sizeof (void *));
601
602 #elif defined(_SABLEVM_TRADITIONAL_OBJECT_LAYOUT)
603
604 if (_svmm_cl_malloc_size_t
605 (env, class->class_loader_info,
606 class->data.noninterface.ref_field_count,
607 class->data.noninterface.ref_field_offsets) != JNI_OK)
608 {
609 return JNI_ERR;
610 }
611
612 {
613 jint i = 0;
614 jint j;
615 jint size = class->fields_count;
616
617 if (CAN_DREF (class->super_class))
618 {
619 _svmt_class_info *super_class =
620 _svmf_cast_class (DREF (class->super_class, type));
621
622 for (; i < super_class->data.noninterface.ref_field_count; i++)
623 {
624 class->data.noninterface.ref_field_offsets[i] =
625 super_class->data.noninterface.ref_field_offsets[i];
626 }
627 }
628
629 for (j = 0; j < size; j++)
630 {
631 if (class->fields[j].type == SVM_TYPE_REFERENCE &&
632 (!_svmf_is_set_flag (class->fields[j].access_flags,
633 SVM_ACC_STATIC)))
634 {
635 class->data.noninterface.ref_field_offsets[i++] =
636 class->fields[j].data.instance_field.offset;
637 }
638 }
639
640 assert (i == class->data.noninterface.ref_field_count);
641 }
642
643 #endif /* defined (_SABLEVM_BIDIRECTIONAL_OBJECT_LAYOUT) */
644
645 class->data.noninterface.next_offset_with_hashcode =
646 class->data.noninterface.next_offset_no_hashcode +
647 _svmf_aligned_size_t (sizeof (jint));
648
649 return JNI_OK;
650 }
651
652 /*
653 ----------------------------------------------------------------------
654 _svmf_prepare_method_args_count
655 ----------------------------------------------------------------------
656 */
657
658 svm_static jint
_svmf_prepare_method_args_count(_svmt_JNIEnv * env,_svmt_method_info * method)659 _svmf_prepare_method_args_count (_svmt_JNIEnv *env, _svmt_method_info *method)
660 {
661 _svmt_JavaVM *vm = env->vm;
662 /* skip '(' */
663 char *p = &DREF (method->descriptor, value)[1];
664 jint count = 0;
665 jint map_size = 0;
666
667 if (DREF (method->name, value)[0] == '<')
668 {
669 if (strcmp (DREF (method->name, value), "<init>") == 0)
670 {
671 count++; /* implicit "this" parameter */
672 map_size = count;
673 }
674 else
675 {
676 /* just making sure the verifier works... */
677 assert (strcmp (DREF (method->name, value), "<clinit>") == 0);
678 }
679 }
680 else
681 {
682 if (!_svmf_is_set_flag (method->access_flags, SVM_ACC_STATIC))
683 {
684 count++; /* implicit "this" parameter */
685 map_size = count;
686 }
687 }
688
689 while (*p != ')')
690 {
691 switch (*p)
692 {
693 case 'B':
694 case 'C':
695 case 'F':
696 case 'I':
697 case 'S':
698 case 'Z':
699 {
700 count++;
701 }
702 break;
703
704 case 'D':
705 case 'J':
706 {
707 count += 2;
708 }
709 break;
710
711 case 'L':
712 {
713 count++;
714 map_size = count;
715
716 /* skip to next ';' */
717 while (*++p != ';');
718 }
719 break;
720
721 case '[':
722 {
723 count++;
724 map_size = count;
725
726 /* skip all '[' */
727 while (*++p == '[');
728
729 if (*p == 'L')
730 {
731 /* skip to next ';' */
732 while (*++p != ';');
733 }
734 }
735 break;
736
737 default:
738 {
739 _svmm_fatal_error ("impossible control flow");
740 }
741 break;
742 }
743
744 ++p;
745 }
746
747 method->java_args_count = count;
748
749 if (_svmm_gzalloc_gc_map_node (env, method->parameters_gc_map) != JNI_OK)
750 {
751 return JNI_ERR;
752 }
753
754 method->parameters_gc_map->size = map_size;
755
756 if (map_size > 0)
757 {
758 p = &DREF (method->descriptor, value)[1];
759 count = 0;
760
761 if (_svmm_gzmalloc_ubytes
762 (env, (map_size + 7) / 8,
763 method->parameters_gc_map->bits) != JNI_OK)
764 {
765 return JNI_ERR;
766 }
767
768 if (DREF (method->name, value)[0] == '<')
769 {
770 if (strcmp (DREF (method->name, value), "<init>") == 0)
771 {
772 _svmf_set_bit (method->parameters_gc_map->bits, count++);
773 }
774 else
775 {
776 /* just making sure the verifier works... */
777 assert (strcmp (DREF (method->name, value), "<clinit>") == 0);
778 }
779 }
780 else
781 {
782 if (!_svmf_is_set_flag (method->access_flags, SVM_ACC_STATIC))
783 {
784 _svmf_set_bit (method->parameters_gc_map->bits, count++);
785 }
786 }
787
788 while (*p != ')')
789 {
790 switch (*p)
791 {
792 case 'B':
793 case 'C':
794 case 'F':
795 case 'I':
796 case 'S':
797 case 'Z':
798 {
799 count++;
800 }
801 break;
802
803 case 'D':
804 case 'J':
805 {
806 count += 2;
807 }
808 break;
809
810 case 'L':
811 {
812 _svmf_set_bit (method->parameters_gc_map->bits, count++);
813
814 /* skip to next ';' */
815 while (*++p != ';');
816 }
817 break;
818
819 case '[':
820 {
821 _svmf_set_bit (method->parameters_gc_map->bits, count++);
822
823 /* skip all '[' */
824 while (*++p == '[');
825
826 if (*p == 'L')
827 {
828 /* skip to next ';' */
829 while (*++p != ';');
830 }
831 }
832 break;
833
834 default:
835 {
836 _svmm_fatal_error ("impossible control flow");
837 }
838 break;
839 }
840
841 ++p;
842 }
843 }
844
845 /* reuse identical map, if it exists */
846 {
847 _svmt_gc_map_node *map =
848 _svmm_tree_find_gc_map (vm->class_loading.gc_map_tree,
849 method->parameters_gc_map);
850
851 if (map == NULL)
852 {
853 #ifdef STATISTICS
854
855 vm->total_gc_maps_count++;
856 vm->total_gc_maps_size +=
857 _svmf_aligned_size_t (sizeof (_svmt_gc_map_node)) +
858 _svmf_aligned_size_t ((method->parameters_gc_map->size + 7) / 8);
859
860 #endif
861
862 _svmm_tree_insert_gc_map (vm->class_loading.gc_map_tree,
863 method->parameters_gc_map);
864 }
865 else
866 {
867 if (method->parameters_gc_map->size > 0)
868 {
869 _svmm_gzmfree_ubytes (method->parameters_gc_map->bits);
870 }
871
872 _svmm_gzfree_gc_map_node (method->parameters_gc_map);
873
874 method->parameters_gc_map = map;
875 }
876 }
877
878 return JNI_OK;
879 }
880
881 /*
882 ----------------------------------------------------------------------
883 _svmh_get_interface_method_id
884 ----------------------------------------------------------------------
885 */
886
887 svm_static jint
_svmh_get_interface_method_id(_svmt_JNIEnv * env,const char * name,const char * descriptor,jint * pmethod_id)888 _svmh_get_interface_method_id (_svmt_JNIEnv *env, const char *name,
889 const char *descriptor, jint *pmethod_id)
890 {
891 _svmt_JavaVM *vm = env->vm;
892 _svmt_imethod_signature_node sig = { NULL, NULL, 0, NULL, NULL, NULL };
893 _svmt_imethod_signature_node *node;
894
895 sig.name = name;
896 sig.descriptor = descriptor;
897
898 node =
899 _svmm_tree_find_imethod_signature (vm->class_loading.
900 interface_method_signature_tree, &sig);
901
902 if (node != NULL)
903 {
904 *pmethod_id = node->interface_method_id;
905 return JNI_OK;
906 }
907
908 if (vm->class_loading.next_interface_method_id < 0)
909 {
910 /* exceeded internal limits */
911 _svmf_error_InternalError (env);
912 return JNI_ERR;
913 }
914
915 if (_svmm_gzalloc_imethod_signature_node (env, node) != JNI_OK)
916 {
917 return JNI_ERR;
918 }
919
920 node->name = name;
921 node->descriptor = descriptor;
922 node->interface_method_id = vm->class_loading.next_interface_method_id++;
923
924 _svmm_tree_insert_imethod_signature (vm->class_loading.
925 interface_method_signature_tree, node);
926
927 *pmethod_id = node->interface_method_id;
928 return JNI_OK;
929 }
930
931 /*
932 ----------------------------------------------------------------------
933 _svmf_prepare_interface_methods
934 ----------------------------------------------------------------------
935 */
936
937 svm_static jint
_svmf_prepare_interface_methods(_svmt_JNIEnv * env,_svmt_class_info * interface)938 _svmf_prepare_interface_methods (_svmt_JNIEnv *env,
939 _svmt_class_info *interface)
940 {
941 jint i;
942 _svmt_JavaVM *vm = env->vm;
943
944 /* initialize max_interface_method_id (and interface_method_id's) */
945 interface->data.interface.max_interface_method_id = -1;
946
947 for (i = 0; i < interface->interfaces_count; i++)
948 {
949 _svmt_class_info *super_interface =
950 _svmf_cast_class (DREF (interface->interfaces[i], type));
951
952 interface->data.interface.max_interface_method_id = _svmf_max_jint
953 (interface->data.interface.max_interface_method_id,
954 super_interface->data.interface.max_interface_method_id);
955 }
956
957 for (i = 0; i < interface->methods_count; i++)
958 {
959 /* skip initializer */
960 if (DREF (interface->methods[i].name, value)[0] == '<')
961 {
962 continue;
963 }
964
965 if (_svmm_get_interface_method_id
966 (env, DREF (interface->methods[i].name, value),
967 DREF (interface->methods[i].descriptor, value),
968 interface->methods[i].method_id) != JNI_OK)
969 {
970 return JNI_ERR;
971 }
972
973 interface->data.interface.max_interface_method_id =
974 _svmf_max_jint (interface->data.interface.max_interface_method_id,
975 interface->methods[i].method_id);
976 }
977
978 /* prepare various method_info fields */
979 for (i = 0; i < interface->methods_count; i++)
980 {
981 _svmt_method_info *method = &interface->methods[i];
982 _svmt_method_frame_info *frame_info;
983
984 method->class_info = interface;
985
986 method->synchronized =
987 _svmf_is_set_flag (method->access_flags, SVM_ACC_SYNCHRONIZED);
988
989 if (_svmf_prepare_method_args_count (env, method) != JNI_OK)
990 {
991 return JNI_ERR;
992 }
993
994 if (DREF (method->name, value)[0] == '<')
995 {
996 int j;
997
998 assert (strcmp (DREF (method->name, value), "<clinit>") == 0);
999
1000 frame_info = &method->non_prepared_info;
1001 method->frame_info = frame_info;
1002
1003 for (j = 0; j < method->attributes_count; j++)
1004 {
1005 if (strcmp (DREF (method->attributes[j]->name, value),
1006 "Code") == 0)
1007 {
1008 method->data.code_attribute =
1009 _svmf_cast_code_attribute (method->attributes[j]);
1010 break;
1011 }
1012 }
1013
1014 assert (method->data.code_attribute != NULL);
1015 assert (method->data.code_attribute->max_locals >=
1016 method->java_args_count);
1017
1018 frame_info->code =
1019 &vm->instructions[SVM_INSTRUCTION_PREPARE_METHOD].code;
1020
1021 frame_info->start_offset =
1022 method->java_args_count * sizeof (_svmt_stack_value);
1023
1024 frame_info->end_offset = _svmv_stack_offset +
1025 method->data.code_attribute->max_stack *
1026 sizeof (_svmt_stack_value);
1027 frame_info->java_invoke_frame_size =
1028 frame_info->start_offset + frame_info->end_offset;
1029 frame_info->internal_invoke_frame_size =
1030 _svmf_aligned_size_t (sizeof (_svmt_stack_frame)) +
1031 frame_info->java_invoke_frame_size;
1032
1033 #ifdef STATISTICS
1034
1035 frame_info->local_count = method->java_args_count;
1036 frame_info->local_split_count = 0;
1037
1038 #endif
1039 }
1040 else
1041 {
1042 assert (_svmf_is_set_flag (method->access_flags, SVM_ACC_ABSTRACT));
1043
1044 frame_info = &method->prepared_info;
1045 method->frame_info = frame_info;
1046
1047 frame_info->code =
1048 &vm->instructions[SVM_INSTRUCTION_ABSTRACT_METHOD].code;
1049
1050 frame_info->start_offset =
1051 method->java_args_count * sizeof (_svmt_stack_value);
1052
1053 frame_info->end_offset = _svmv_stack_offset;
1054 frame_info->java_invoke_frame_size =
1055 frame_info->start_offset + frame_info->end_offset;
1056 frame_info->internal_invoke_frame_size =
1057 _svmf_aligned_size_t (sizeof (_svmt_stack_frame)) +
1058 frame_info->java_invoke_frame_size;
1059
1060 #ifdef STATISTICS
1061
1062 frame_info->local_count = method->java_args_count;
1063 frame_info->local_split_count = 0;
1064
1065 #endif
1066 }
1067 }
1068
1069 return JNI_OK;
1070 }
1071
1072 /*
1073 ----------------------------------------------------------------------
1074 _svmf_prepare_noninterface_methods
1075 ----------------------------------------------------------------------
1076 */
1077
1078 svm_static jint
_svmf_prepare_noninterface_methods(_svmt_JNIEnv * env,_svmt_class_info * class)1079 _svmf_prepare_noninterface_methods (_svmt_JNIEnv *env,
1080 _svmt_class_info *class)
1081 {
1082 jint i;
1083 _svmt_JavaVM *vm = env->vm;
1084
1085 /* initialize max_interface_method_id and max_virtual_method_id */
1086 if (CAN_DREF (class->super_class))
1087 {
1088 _svmt_class_info *super_class =
1089 _svmf_cast_class (DREF (class->super_class, type));
1090
1091 class->data.noninterface.max_virtual_method_id =
1092 super_class->data.noninterface.max_virtual_method_id;
1093 class->data.noninterface.max_interface_method_id =
1094 super_class->data.noninterface.max_interface_method_id;
1095 }
1096 else
1097 {
1098 class->data.noninterface.max_virtual_method_id = -1;
1099 class->data.noninterface.max_interface_method_id = -1;
1100 }
1101
1102 for (i = 0; i < class->interfaces_count; i++)
1103 {
1104 _svmt_class_info *super_interface =
1105 _svmf_cast_class (DREF (class->interfaces[i], type));
1106
1107 class->data.noninterface.max_interface_method_id =
1108 _svmf_max_jint (class->data.noninterface.max_interface_method_id,
1109 super_interface->data.interface.
1110 max_interface_method_id);
1111 }
1112
1113 for (i = 0; i < class->methods_count; i++)
1114 {
1115 _svmt_method_info *method = &class->methods[i];
1116
1117 /* skip <init>,<clinit>, and svm_static methods */
1118 if (DREF (method->name, value)[0] == '<' ||
1119 _svmf_is_set_flag (method->access_flags, SVM_ACC_STATIC))
1120 {
1121 continue;
1122 }
1123
1124 method->method_id = -1;
1125
1126 if (CAN_DREF (class->super_class))
1127 {
1128 _svmt_class_info *super_class =
1129 _svmf_cast_class (DREF (class->super_class, type));
1130 jint j;
1131 _svmt_method_info **methods =
1132 (_svmt_method_info **) (super_class->data.noninterface.vtable +
1133 1);
1134 jint size =
1135 super_class->data.noninterface.max_virtual_method_id + 1;
1136
1137 for (j = 0; j < size; j++)
1138 {
1139 if (strcmp
1140 (DREF (method->name, value),
1141 DREF (methods[j]->name, value)) == 0
1142 && strcmp (DREF (method->descriptor, value),
1143 DREF (methods[j]->descriptor, value)) == 0)
1144 {
1145 method->method_id = methods[j]->method_id;
1146 assert (method->method_id == j);
1147 break;
1148 }
1149 }
1150 }
1151
1152 if (method->method_id == -1)
1153 {
1154 method->method_id =
1155 ++(class->data.noninterface.max_virtual_method_id);
1156 }
1157 }
1158
1159 /* prepare various method_info fields */
1160 for (i = 0; i < class->methods_count; i++)
1161 {
1162 _svmt_method_info *method = &class->methods[i];
1163 _svmt_method_frame_info *frame_info;
1164
1165 method->class_info = class;
1166
1167 method->synchronized =
1168 _svmf_is_set_flag (method->access_flags, SVM_ACC_SYNCHRONIZED);
1169
1170 if (_svmf_prepare_method_args_count (env, method) != JNI_OK)
1171 {
1172 return JNI_ERR;
1173 }
1174
1175 if (DREF (method->name, value)[0] != '<' &&
1176 _svmf_is_set_flag (method->access_flags, SVM_ACC_ABSTRACT))
1177 {
1178 frame_info = &method->prepared_info;
1179 method->frame_info = frame_info;
1180
1181 frame_info->code =
1182 &vm->instructions[SVM_INSTRUCTION_ABSTRACT_METHOD].code;
1183
1184 frame_info->start_offset =
1185 method->java_args_count * sizeof (_svmt_stack_value);
1186
1187 frame_info->end_offset = _svmv_stack_offset;
1188 frame_info->java_invoke_frame_size =
1189 frame_info->start_offset + frame_info->end_offset;
1190 frame_info->internal_invoke_frame_size =
1191 _svmf_aligned_size_t (sizeof (_svmt_stack_frame)) +
1192 frame_info->java_invoke_frame_size;
1193
1194 #ifdef STATISTICS
1195
1196 frame_info->local_count = method->java_args_count;
1197 frame_info->local_split_count = 0;
1198
1199 #endif
1200 }
1201 else if (DREF (method->name, value)[0] != '<' &&
1202 _svmf_is_set_flag (method->access_flags, SVM_ACC_NATIVE))
1203 {
1204 if (_svmm_cl_zalloc_native_method_data
1205 (env, class->class_loader_info,
1206 method->data.native_method) != JNI_OK)
1207 {
1208 return JNI_ERR;
1209 }
1210
1211 if (_svmf_prepare_native_method_short_name (env, method) != JNI_OK)
1212 {
1213 return JNI_ERR;
1214 }
1215
1216 if (_svmf_prepare_native_method_long_name (env, method) != JNI_OK)
1217 {
1218 return JNI_ERR;
1219 }
1220
1221 if (_svmf_prepare_native_ffi_args (env, method) != JNI_OK)
1222 {
1223 return JNI_ERR;
1224 }
1225
1226 frame_info = &method->prepared_info;
1227 method->frame_info = frame_info;
1228
1229 frame_info->code =
1230 &vm->instructions[SVM_INSTRUCTION_LINK_NATIVE_METHOD].code;
1231
1232 frame_info->start_offset =
1233 method->data.native_method->java_args_and_ret_count *
1234 sizeof (_svmt_stack_value) +
1235 _svmf_aligned_size_t (method->data.native_method->args_count *
1236 sizeof (void *));
1237
1238 frame_info->end_offset =
1239 _svmv_stack_offset + _svmf_aligned_size_t
1240 (((SVM_FRAME_NATIVE_REFS_MIN + 2) +
1241 method->data.native_method->refargs_count) *
1242 sizeof (_svmt_stack_native_reference));
1243 frame_info->java_invoke_frame_size =
1244 frame_info->start_offset + frame_info->end_offset;
1245 frame_info->internal_invoke_frame_size =
1246 _svmf_aligned_size_t (sizeof (_svmt_stack_frame)) +
1247 frame_info->java_invoke_frame_size;
1248
1249 #ifdef STATISTICS
1250
1251 frame_info->local_count = method->java_args_count;
1252 frame_info->local_split_count = 0;
1253
1254 #endif
1255 }
1256 else
1257 {
1258 int j;
1259
1260 frame_info = &method->non_prepared_info;
1261 method->frame_info = frame_info;
1262
1263 for (j = 0; j < method->attributes_count; j++)
1264 {
1265 if (strcmp (DREF (method->attributes[j]->name, value), "Code")
1266 == 0)
1267 {
1268 method->data.code_attribute =
1269 _svmf_cast_code_attribute (method->attributes[j]);
1270 break;
1271 }
1272 }
1273
1274 assert (method->data.code_attribute != NULL);
1275 assert (method->data.code_attribute->max_locals >=
1276 method->java_args_count);
1277
1278 frame_info->code =
1279 &vm->instructions[SVM_INSTRUCTION_PREPARE_METHOD].code;
1280
1281 frame_info->start_offset =
1282 method->java_args_count * sizeof (_svmt_stack_value);
1283
1284 frame_info->end_offset = _svmv_stack_offset +
1285 method->data.code_attribute->max_stack *
1286 sizeof (_svmt_stack_value);
1287 frame_info->java_invoke_frame_size =
1288 frame_info->start_offset + frame_info->end_offset;
1289 frame_info->internal_invoke_frame_size =
1290 _svmf_aligned_size_t (sizeof (_svmt_stack_frame)) +
1291 frame_info->java_invoke_frame_size;
1292
1293 #ifdef STATISTICS
1294
1295 frame_info->local_count = method->java_args_count;
1296 frame_info->local_split_count = 0;
1297
1298 #endif
1299 }
1300 }
1301
1302 return JNI_OK;
1303 }
1304
1305 /*
1306 ----------------------------------------------------------------------
1307 _svmf_prepare_interface
1308 ----------------------------------------------------------------------
1309 */
1310
1311 svm_static jint
_svmf_prepare_interface(_svmt_JNIEnv * env,_svmt_class_info * interface)1312 _svmf_prepare_interface (_svmt_JNIEnv *env, _svmt_class_info *interface)
1313 {
1314 if (_svmf_prepare_interface_instanceof (env, interface) != JNI_OK)
1315 {
1316 return JNI_ERR;
1317 }
1318
1319 if (_svmf_prepare_interface_fields (env, interface) != JNI_OK)
1320 {
1321 return JNI_ERR;
1322 }
1323
1324 if (_svmf_prepare_interface_methods (env, interface) != JNI_OK)
1325 {
1326 return JNI_ERR;
1327 }
1328
1329 return JNI_OK;
1330 }
1331
1332
1333 /*
1334 ----------------------------------------------------------------------
1335 _svmf_fill_interface_table_with_interface
1336 ----------------------------------------------------------------------
1337 */
1338
1339 svm_static void
_svmf_fill_interface_table_with_interface(_svmt_class_info * interface,_svmt_method_info ** imethods,_svmt_method_info ** vmethods,jint vmethods_count,_svmt_u8 * visited)1340 _svmf_fill_interface_table_with_interface (_svmt_class_info *interface,
1341 _svmt_method_info **imethods,
1342 _svmt_method_info **vmethods,
1343 jint vmethods_count,
1344 _svmt_u8 *visited)
1345 {
1346 jint size = interface->methods_count;
1347 jint i;
1348
1349 if (_svmf_get_bit (visited, interface->data.interface.interface_id) == 1)
1350 {
1351 return;
1352 }
1353
1354 _svmf_set_bit (visited, interface->data.interface.interface_id);
1355
1356 /* fill the entry related to every method of this interface */
1357 for (i = 0; i < size; i++)
1358 {
1359 _svmt_method_info *method = &interface->methods[i];
1360 jint j;
1361
1362 /* skip initializer */
1363 if (DREF (method->name, value)[0] == '<')
1364 {
1365 continue;
1366 }
1367
1368 imethods[-1 - method->method_id] = method;
1369
1370 for (j = 0; j < vmethods_count; j++)
1371 {
1372 if (strcmp
1373 (DREF (method->name, value),
1374 DREF (vmethods[j]->name, value)) == 0
1375 && strcmp (DREF (method->descriptor, value),
1376 DREF (vmethods[j]->descriptor, value)) == 0)
1377 {
1378 imethods[-1 - method->method_id] = vmethods[j];
1379 break;
1380 }
1381 }
1382 }
1383
1384 /* recursively visit all super interfaces */
1385 size = interface->interfaces_count;
1386 for (i = 0; i < size; i++)
1387 {
1388 _svmf_fill_interface_table_with_interface (_svmf_cast_class
1389 (DREF
1390 (interface->interfaces[i],
1391 type)), imethods, vmethods,
1392 vmethods_count, visited);
1393 }
1394 }
1395
1396 /*
1397 ----------------------------------------------------------------------
1398 _svmf_fill_interface_table
1399 ----------------------------------------------------------------------
1400 */
1401
1402 svm_static jint
_svmf_fill_interface_table(_svmt_JNIEnv * env,_svmt_class_info * class)1403 _svmf_fill_interface_table (_svmt_JNIEnv *env, _svmt_class_info *class)
1404 {
1405 _svmt_u8 *visited;
1406 _svmt_method_info **imethods =
1407 (_svmt_method_info **) class->data.noninterface.vtable;
1408 _svmt_method_info **vmethods =
1409 (_svmt_method_info **) (class->data.noninterface.vtable + 1);
1410 jint vmethods_count = class->data.noninterface.max_virtual_method_id + 1;
1411
1412 assert (!_svmf_is_set_flag (class->access_flags, SVM_ACC_INTERFACE));
1413
1414 if (_svmm_gzmalloc_ubytes
1415 (env, class->data.noninterface.max_interface_id / 8 + 1,
1416 visited) != JNI_OK)
1417 {
1418 return JNI_ERR;
1419 }
1420
1421 while (class != NULL)
1422 {
1423 jint size = class->interfaces_count;
1424 jint i;
1425
1426 for (i = 0; i < size; i++)
1427 {
1428 _svmf_fill_interface_table_with_interface (_svmf_cast_class
1429 (DREF
1430 (class->interfaces[i],
1431 type)), imethods,
1432 vmethods, vmethods_count,
1433 visited);
1434 }
1435
1436 if (CAN_DREF (class->super_class))
1437 {
1438 class = _svmf_cast_class (DREF (class->super_class, type));
1439 }
1440 else
1441 {
1442 class = NULL;
1443 }
1444 }
1445
1446
1447 _svmm_gzmfree_ubytes (visited);
1448
1449 return JNI_OK;
1450 }
1451
1452 /*
1453 ----------------------------------------------------------------------
1454 _svmf_prepare_noninterface_vtable
1455 ----------------------------------------------------------------------
1456 */
1457
1458 svm_static jint
_svmf_prepare_noninterface_vtable(_svmt_JNIEnv * env,_svmt_class_info * class)1459 _svmf_prepare_noninterface_vtable (_svmt_JNIEnv *env, _svmt_class_info *class)
1460 {
1461 #ifdef STATISTICS
1462 _svmt_JavaVM *vm = env->vm;
1463 #endif
1464 jboolean is_abstract =
1465 _svmf_is_set_flag (class->access_flags, SVM_ACC_ABSTRACT);
1466
1467 if (_svmm_cl_zalloc_vtable
1468 (env, class->class_loader_info, class,
1469 class->data.noninterface.vtable) != JNI_OK)
1470 {
1471 return JNI_ERR;
1472 }
1473
1474 class->data.noninterface.vtable->type = _svmf_cast_type_class (class);
1475
1476 #if defined (_SABLEVM_BIDIRECTIONAL_OBJECT_LAYOUT)
1477
1478 assert (class->data.noninterface.next_offset_with_hashcode ==
1479 (class->data.noninterface.next_offset_no_hashcode +
1480 _svmf_aligned_size_t (sizeof (jint))));
1481
1482 class->data.noninterface.vtable->hashcode_offset =
1483 class->data.noninterface.next_offset_no_hashcode;
1484 class->data.noninterface.vtable->next_offset_no_hashcode =
1485 class->data.noninterface.next_offset_no_hashcode;
1486 class->data.noninterface.vtable->next_offset_with_hashcode =
1487 class->data.noninterface.next_offset_with_hashcode;
1488 class->data.noninterface.vtable->start_offset =
1489 class->data.noninterface.start_offset;
1490
1491 #elif defined(_SABLEVM_TRADITIONAL_OBJECT_LAYOUT)
1492
1493 assert (class->data.noninterface.next_offset_with_hashcode ==
1494 (class->data.noninterface.next_offset_no_hashcode +
1495 _svmf_aligned_size_t (sizeof (jint))));
1496
1497 class->data.noninterface.vtable->hashcode_offset =
1498 class->data.noninterface.next_offset_no_hashcode;
1499 class->data.noninterface.vtable->next_offset_no_hashcode =
1500 class->data.noninterface.next_offset_no_hashcode;
1501 class->data.noninterface.vtable->next_offset_with_hashcode =
1502 class->data.noninterface.next_offset_with_hashcode;
1503 class->data.noninterface.vtable->ref_field_count =
1504 class->data.noninterface.ref_field_count;
1505 class->data.noninterface.vtable->ref_field_offsets =
1506 class->data.noninterface.ref_field_offsets;
1507
1508 #endif /* defined (_SABLEVM_BIDIRECTIONAL_OBJECT_LAYOUT) */
1509
1510 /* initialize normal virtual method table from super class */
1511 if (CAN_DREF (class->super_class))
1512 {
1513 _svmt_class_info *super_class =
1514 _svmf_cast_class (DREF (class->super_class, type));
1515 _svmt_method_info **this_methods =
1516 (_svmt_method_info **) (class->data.noninterface.vtable + 1);
1517 _svmt_method_info **super_methods =
1518 (_svmt_method_info **) (super_class->data.noninterface.vtable + 1);
1519 jint i;
1520 jint size = super_class->data.noninterface.max_virtual_method_id + 1;
1521
1522 assert (class->data.noninterface.max_virtual_method_id >=
1523 super_class->data.noninterface.max_virtual_method_id);
1524
1525 for (i = 0; i < size; i++)
1526 {
1527 this_methods[i] = super_methods[i];
1528 }
1529 }
1530
1531 /* fill vtable with methods of this class */
1532 {
1533 jint i;
1534 jint size = class->methods_count;
1535 _svmt_method_info **methods =
1536 (_svmt_method_info **) (class->data.noninterface.vtable + 1);
1537
1538 for (i = 0; i < size; i++)
1539 {
1540 /* skip <init>, <clinit>, and svm_static methods */
1541 if (DREF (class->methods[i].name, value)[0] == '<' ||
1542 _svmf_is_set_flag (class->methods[i].access_flags,
1543 SVM_ACC_STATIC))
1544 {
1545 continue;
1546 }
1547
1548 assert (class->methods[i].method_id >= 0);
1549 assert (class->methods[i].method_id <=
1550 class->data.noninterface.max_virtual_method_id);
1551
1552 methods[class->methods[i].method_id] = &class->methods[i];
1553 }
1554 }
1555
1556 if (class->data.noninterface.max_interface_method_id >= 0 && !is_abstract)
1557 {
1558 _svmt_method_info **imethods =
1559 (_svmt_method_info **) class->data.noninterface.vtable;
1560 jint size = class->data.noninterface.max_interface_method_id + 1;
1561 jint i;
1562 size_t hole_size = 0;
1563 _svmt_method_info **hole = NULL;
1564
1565 /* fill interface table */
1566 if (_svmf_fill_interface_table (env, class) != JNI_OK)
1567 {
1568 return JNI_ERR;
1569 }
1570
1571 /* check that the latest entry is actually used */
1572 assert (imethods[-1 - class->data.noninterface.max_interface_method_id]
1573 != NULL);
1574
1575 /* free holes in the interface table */
1576 for (i = 0; i < size; i++)
1577 {
1578 if (imethods[-1 - i] == NULL)
1579 {
1580 hole_size += sizeof (void *);
1581 hole = &imethods[-1 - i];
1582 }
1583 else if (hole_size > 0)
1584 {
1585 #ifdef STATISTICS
1586 vm->total_holes += hole_size;
1587 #endif
1588
1589 _svmf_cl_free (env, class->class_loader_info, hole_size,
1590 (void **) &hole);
1591
1592 hole_size = 0;
1593 assert (hole == NULL);
1594 }
1595 }
1596 }
1597
1598 return JNI_OK;
1599 }
1600
1601 /*
1602 ----------------------------------------------------------------------
1603 _svmf_prepare_noninterface
1604 ----------------------------------------------------------------------
1605 */
1606
1607 svm_static jint
_svmf_prepare_noninterface(_svmt_JNIEnv * env,_svmt_class_info * class)1608 _svmf_prepare_noninterface (_svmt_JNIEnv *env, _svmt_class_info *class)
1609 {
1610 if (_svmf_prepare_noninterface_instanceof (env, class) != JNI_OK)
1611 {
1612 return JNI_ERR;
1613 }
1614
1615 if (_svmf_prepare_noninterface_fields (env, class) != JNI_OK)
1616 {
1617 return JNI_ERR;
1618 }
1619
1620 if (_svmf_prepare_noninterface_methods (env, class) != JNI_OK)
1621 {
1622 return JNI_ERR;
1623 }
1624
1625 if (_svmf_prepare_noninterface_vtable (env, class) != JNI_OK)
1626 {
1627 return JNI_ERR;
1628 }
1629
1630 _svmf_prepare_class_lockword (class);
1631
1632 return JNI_OK;
1633 }
1634
1635 /*
1636 ----------------------------------------------------------------------
1637 _svmf_prepare_class
1638 ----------------------------------------------------------------------
1639 */
1640
1641 svm_static jint
_svmf_prepare_class(_svmt_JNIEnv * env,_svmt_class_info * class)1642 _svmf_prepare_class (_svmt_JNIEnv *env, _svmt_class_info *class)
1643 {
1644 #ifdef STATISTICS
1645 _svmt_JavaVM *vm = env->vm;
1646 #endif
1647
1648 assert (_svmf_is_set_flag (class->state, SVM_TYPE_STATE_VERIFIED));
1649
1650 if (_svmf_is_set_flag (class->state, SVM_TYPE_STATE_PREPARED))
1651 {
1652 return JNI_OK;
1653 }
1654
1655 if (class->preparation_error != NULL)
1656 {
1657 assert (*(class->preparation_error) != NULL);
1658
1659 *(env->throwable) = *(class->preparation_error);
1660 return JNI_ERR;
1661 }
1662
1663 if (_svmm_new_native_global (env, class->preparation_error) != JNI_OK)
1664 {
1665 return JNI_ERR;
1666 }
1667
1668 if (CAN_DREF (class->super_class))
1669 {
1670 if (_svmf_link_class
1671 (env, _svmf_cast_class (DREF (class->super_class, type))) != JNI_OK)
1672 {
1673 *(class->preparation_error) = *(env->throwable);
1674 return JNI_ERR;
1675 }
1676 }
1677
1678 {
1679 jint i;
1680
1681 for (i = 0; i < class->interfaces_count; i++)
1682 {
1683 if (_svmf_link_class
1684 (env,
1685 _svmf_cast_class (DREF (class->interfaces[i], type))) != JNI_OK)
1686 {
1687 *(class->preparation_error) = *(env->throwable);
1688 return JNI_ERR;
1689 }
1690 }
1691 }
1692
1693 /* resolve file name */
1694 {
1695 jint i;
1696 jint attributes_count = class->attributes_count;
1697 ;
1698 for (i = 0; i < attributes_count; i++)
1699 {
1700 if (strcmp (DREF (class->attributes[i]->name, value), "SourceFile") ==
1701 0)
1702 {
1703 _svmt_SourceFile_attribute *sourceFile =
1704 _svmf_cast_SourceFile_attribute (class->attributes[i]);
1705 class->file_name = DREF (sourceFile->sourcefile, value);
1706 break;
1707 }
1708 }
1709 }
1710
1711 if (_svmf_is_set_flag (class->access_flags, SVM_ACC_INTERFACE))
1712 {
1713 if (_svmf_prepare_interface (env, class) != JNI_OK)
1714 {
1715 *(class->preparation_error) = *(env->throwable);
1716 return JNI_ERR;
1717 }
1718
1719 #ifdef STATISTICS
1720 vm->interface_count++;
1721 #endif
1722 }
1723 else
1724 {
1725 if (_svmf_prepare_noninterface (env, class) != JNI_OK)
1726 {
1727 *(class->preparation_error) = *(env->throwable);
1728 return JNI_ERR;
1729 }
1730
1731 #ifdef STATISTICS
1732 vm->class_count++;
1733 #endif
1734 }
1735
1736 _svmm_set_flag (class->state, SVM_TYPE_STATE_PREPARED);
1737 _svmm_free_native_global (env, class->preparation_error);
1738 return JNI_OK;
1739 }
1740
1741 /*
1742 ----------------------------------------------------------------------
1743 _svmf_prepare_array_vtable
1744 ----------------------------------------------------------------------
1745 */
1746
1747 svm_static jint
_svmf_prepare_array_vtable(_svmt_JNIEnv * env,_svmt_array_info * array)1748 _svmf_prepare_array_vtable (_svmt_JNIEnv *env, _svmt_array_info *array)
1749 {
1750 _svmt_JavaVM *vm = env->vm;
1751 _svmt_class_info *jlobject = vm->class_loading.boot_loader.classes.jlobject;
1752
1753 if (_svmm_cl_zalloc_vtable
1754 (env, array->class_loader_info, jlobject, array->vtable) != JNI_OK)
1755 {
1756 return JNI_ERR;
1757 }
1758
1759 array->vtable->type = _svmf_cast_type_array (array);
1760
1761 /* fill vtable with methods of java/lang/Object */
1762 {
1763 jint size = jlobject->data.noninterface.max_virtual_method_id + 1;
1764 _svmt_method_info **jlobject_methods =
1765 (_svmt_method_info **) (jlobject->data.noninterface.vtable + 1);
1766 _svmt_method_info **array_methods =
1767 (_svmt_method_info **) (array->vtable + 1);
1768
1769 memcpy (array_methods, jlobject_methods, size * sizeof (void *));
1770 }
1771
1772 return JNI_OK;
1773 }
1774
1775 /*
1776 ----------------------------------------------------------------------
1777 _svmf_prepare_array
1778 ----------------------------------------------------------------------
1779 */
1780
1781 svm_static jint
_svmf_prepare_array(_svmt_JNIEnv * env,_svmt_array_info * array)1782 _svmf_prepare_array (_svmt_JNIEnv *env, _svmt_array_info *array)
1783 {
1784 #ifdef STATISTICS
1785 _svmt_JavaVM *vm = env->vm;
1786 #endif
1787
1788 if (_svmf_is_set_flag (array->state, SVM_TYPE_STATE_PREPARED))
1789 {
1790 return JNI_OK;
1791 }
1792
1793 if (array->preparation_error != NULL)
1794 {
1795 assert (*(array->preparation_error) != NULL);
1796
1797 *(env->throwable) = *(array->preparation_error);
1798 return JNI_ERR;
1799 }
1800
1801 if (_svmm_new_native_global (env, array->preparation_error) != JNI_OK)
1802 {
1803 return JNI_ERR;
1804 }
1805
1806 if (array->dimensions > 1)
1807 {
1808 if (_svmf_link_array (env, array->array_element) != JNI_OK)
1809 {
1810 *(array->preparation_error) = *(env->throwable);
1811 return JNI_ERR;
1812 }
1813
1814 /* recursion should have taken care of linking the base class */
1815 assert (array->base_type != SVM_TYPE_REFERENCE ||
1816 _svmf_is_set_flag (array->base_class->state,
1817 SVM_TYPE_STATE_PREPARED));
1818 }
1819 else if (array->base_type == SVM_TYPE_REFERENCE)
1820 {
1821 if (_svmf_link_class (env, array->base_class) != JNI_OK)
1822 {
1823 *(array->preparation_error) = *(env->throwable);
1824 return JNI_ERR;
1825 }
1826 }
1827
1828 if (_svmf_prepare_array_vtable (env, array) != JNI_OK)
1829 {
1830 *(array->preparation_error) = *(env->throwable);
1831 return JNI_ERR;
1832 }
1833
1834 _svmf_prepare_array_lockword (array);
1835
1836 #ifdef STATISTICS
1837 vm->array_count++;
1838 #endif
1839
1840 _svmm_set_flag (array->state, SVM_TYPE_STATE_PREPARED);
1841 _svmm_free_native_global (env, array->preparation_error);
1842 return JNI_OK;
1843 }
1844