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