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 _svmm_identity_hashcode
12 ----------------------------------------------------------------------
13 */
14
15 #define _svmm_identity_hashcode(env, obj, hashcode) \
16 _svmh_identity_hashcode (env, obj, &hashcode)
17
18 svm_static jint
_svmh_identity_hashcode(_svmt_JNIEnv * env,jobject obj,jint * phashcode)19 _svmh_identity_hashcode (_svmt_JNIEnv *env, jobject obj, jint *phashcode)
20 {
21 _svmt_JavaVM *vm = env->vm;
22 jboolean monitor_acquired = JNI_FALSE;
23 _svmt_JNIEnv *owner = NULL;
24
25 /* is it an array? */
26 if (_svmf_lockword_is_array ((*obj)->lockword))
27 {
28 assert (!monitor_acquired);
29
30 *phashcode = (*(_svmf_cast_jarray (obj)))->hashcode;
31 return JNI_OK;
32 }
33
34 retry:
35 {
36 _svmt_object_instance *instance = *obj;
37 _svmt_word state = _svmf_lockword_get_hashstate (instance->lockword);
38
39 switch (state)
40 {
41 case SVM_HASH_NONE:
42 {
43 /* The untold story in the 2 bits hashcode within a thin
44 lock is that it cannot be modified unless a) the current
45 thread owns the lock, or b) the owning thread is
46 suspended.
47 */
48
49 if (!monitor_acquired)
50 {
51 jboolean succeeded = JNI_FALSE; /* init just to keep compiler happy */
52
53 if (_svmm_enter_object_monitor_non_blocking
54 (env, instance, succeeded))
55 {
56 return JNI_ERR;
57 }
58
59 if (succeeded)
60 {
61 monitor_acquired = JNI_TRUE;
62 goto retry;
63 }
64
65 /* refresh values, in case GC happened in enter_monitor call */
66 instance = *obj;
67
68 /* contention: another thread owns the lock. Suspend it. */
69 {
70 _svmt_word lockword = instance->lockword;
71
72 if (_svmf_lockword_is_thin (lockword))
73 {
74 jint owner_id = _svmf_lockword_get_thread_id (lockword);
75
76 assert (owner_id != env->thread.id);
77
78 owner = vm->threads.array[owner_id];
79
80 /* If the lock has been released, retry. */
81 if (owner == NULL)
82 {
83 goto retry;
84 }
85
86 _svmm_mutex_lock (vm->global_mutex);
87
88 assert (env != owner);
89
90 /* suspend owner thread */
91 _svmf_suspend_thread (env, owner);
92
93 _svmm_mutex_unlock ();
94
95 /* refresh values */
96 instance = *obj;
97 lockword = instance->lockword;
98
99 if (_svmf_lockword_is_thin (lockword))
100 {
101 owner_id = _svmf_lockword_get_thread_id (lockword);
102 }
103 else
104 {
105 owner_id = 0; /* so that we retry */
106 }
107
108 /* make sure it is still owner */
109 if (owner != vm->threads.array[owner_id])
110 {
111 _svmm_mutex_lock (vm->global_mutex);
112
113 /* resume owner thread */
114 _svmf_resume_thread (env, owner);
115
116 _svmm_mutex_unlock ();
117
118 owner = NULL;
119 goto retry;
120 }
121 }
122 else
123 {
124 /* it is a fat lock */
125
126 _svmt_word fat_index =
127 _svmf_lockword_get_fatlock_index (lockword);
128 _svmt_fat_lock *fat_lock = vm->fat_locks.array[fat_index];
129
130 _svmm_mutex_lock (fat_lock->mutex);
131
132 if (fat_lock->recursive_count != 0)
133 {
134 owner = fat_lock->owner;
135 }
136
137 _svmm_mutex_unlock ();
138
139 /* If the lock has been released, retry. */
140 if (owner == NULL)
141 {
142 goto retry;
143 }
144
145 _svmm_mutex_lock (vm->global_mutex);
146
147 assert (env != owner);
148
149 /* suspend owner thread */
150 _svmf_suspend_thread (env, owner);
151
152 _svmm_mutex_unlock ();
153
154 /* refresh values */
155 instance = *obj;
156 lockword = instance->lockword;
157
158 {
159 jboolean changed = JNI_FALSE;
160
161 if (!_svmf_lockword_is_thin (lockword))
162 {
163 fat_index =
164 _svmf_lockword_get_fatlock_index (lockword);
165 fat_lock = vm->fat_locks.array[fat_index];
166
167 _svmm_mutex_lock (fat_lock->mutex);
168
169 if (fat_lock->recursive_count == 0
170 || owner != fat_lock->owner)
171 {
172 changed = JNI_TRUE;
173 }
174
175 _svmm_mutex_unlock ();
176 }
177 else
178 {
179 changed = JNI_TRUE;
180 }
181
182 /* make sure it is still owner */
183 if (changed)
184 {
185 _svmm_mutex_lock (vm->global_mutex);
186
187 /* resume owner thread */
188 _svmf_resume_thread (env, owner);
189
190 _svmm_mutex_unlock ();
191
192 owner = NULL;
193 goto retry;
194 }
195 }
196 }
197 }
198 }
199
200 #if defined (_SABLEVM_COPY_GC) || defined (_SABLEVM_GENCOPY_GC)
201
202 /* we must make sure there will be enough space to store the hashcode at gc time */
203 {
204 jint end_of_heap, status = JNI_OK;
205
206 _svmm_mutex_lock (vm->global_mutex);
207
208 /* remember that allocation is made in multiples of SVM_ALIGNMENT */
209 if (vm->heap.alloc == vm->heap.end)
210 end_of_heap = JNI_TRUE;
211 else
212 end_of_heap = JNI_FALSE;
213
214 if (end_of_heap == JNI_TRUE)
215 {
216 #if defined (_SABLEVM_COPY_GC)
217 status = _svmf_copy_gc_no_exception (env, SVM_ALIGNMENT);
218 #elif defined (_SABLEVM_GENCOPY_GC)
219 status = _svmf_gencopy_gc_no_exception (env, SVM_ALIGNMENT);
220 #endif
221 }
222
223 if ((end_of_heap == JNI_FALSE) || (status == JNI_OK))
224 {
225 #if defined (_SABLEVM_GENCOPY_GC)
226 if (_svmf_in_nursery (env, *obj))
227 vm->heap.hashed_notmoved_nursery++;
228 #endif
229 vm->heap.hashed_notmoved++;
230 vm->heap.end = ((char *) vm->heap.end) - SVM_ALIGNMENT;
231 }
232
233 _svmm_mutex_unlock ();
234
235 if (status != JNI_OK)
236 {
237 if (monitor_acquired)
238 {
239 assert (owner == NULL);
240
241 if (_svmf_exit_object_monitor (env, *obj) != JNI_OK)
242 {
243 return JNI_ERR;
244 }
245 }
246 else
247 {
248 assert (owner != NULL);
249
250 _svmm_mutex_lock (vm->global_mutex);
251
252 /* resume owner thread */
253 _svmf_resume_thread (env, owner);
254
255 _svmm_mutex_unlock ();
256 }
257
258 _svmf_error_OutOfMemoryError (env);
259 return JNI_ERR;
260 }
261
262 /* in case gc moved things around */
263 instance = *obj;
264 }
265 #endif
266
267 _svmm_lockword_set_hashstate (instance->lockword,
268 SVM_HASH_NOT_MOVED);
269
270 #if defined (_SABLEVM_NO_GC) || defined (_SABLEVM_COPY_GC)
271
272 *phashcode = vm->heap.hashcode_base + (size_t) instance;
273
274 #elif defined (_SABLEVM_GENCOPY_GC)
275
276 if (_svmf_in_nursery (env, instance))
277 *phashcode = vm->heap.hashcode_base_nursery + (size_t) instance;
278 else
279 *phashcode = vm->heap.hashcode_base - (size_t) instance;
280
281 #else
282 #error todo
283 #endif
284 }
285 break;
286
287 case SVM_HASH_NOT_MOVED:
288 {
289 #if defined (_SABLEVM_NO_GC) || defined (_SABLEVM_COPY_GC)
290
291 *phashcode = vm->heap.hashcode_base + (size_t) instance;
292
293 #elif defined (_SABLEVM_GENCOPY_GC)
294
295 if (_svmf_in_nursery (env, instance))
296 *phashcode = vm->heap.hashcode_base_nursery + (size_t) instance;
297 else
298 *phashcode = vm->heap.hashcode_base - (size_t) instance;
299
300 #else
301 #error todo
302 #endif
303 }
304 break;
305
306 case SVM_HASH_MOVED:
307 {
308 *phashcode =
309 _svmf_get_INT_field (instance, instance->vtable->hashcode_offset);
310 }
311 break;
312
313 default:
314 {
315 _svmm_fatal_error ("impossible control flow");
316 }
317 break;
318 }
319 }
320
321 if (monitor_acquired)
322 {
323 monitor_acquired = JNI_FALSE;
324
325 if (_svmf_exit_object_monitor (env, *obj) != JNI_OK)
326 {
327 return JNI_ERR;
328 }
329 }
330 else if (owner != NULL)
331 {
332 _svmm_mutex_lock (vm->global_mutex);
333
334 /* resume owner thread */
335 _svmf_resume_thread (env, owner);
336
337 _svmm_mutex_unlock ();
338 }
339
340 return JNI_OK;
341 }
342
343 /*
344 ----------------------------------------------------------------------
345 _svmf_is_assignable_from
346 ----------------------------------------------------------------------
347 */
348
349 inline svm_static jboolean
_svmf_is_assignable_from(_svmt_JNIEnv * env,_svmt_type_info * from,_svmt_type_info * to)350 _svmf_is_assignable_from (_svmt_JNIEnv *env, _svmt_type_info *from,
351 _svmt_type_info *to)
352 {
353 _svmt_JavaVM *vm = env->vm;
354 _svmt_type_info *S = from;
355 _svmt_type_info *T = to;
356
357 #ifndef _SABLEVM_INLINED_THREADED_INTERPRETER
358 assert (S != NULL);
359 assert (T != NULL);
360 #endif
361
362 loop:
363 if (!(S->is_array))
364 {
365 _svmt_class_info *cS = _svmf_cast_class (S);
366
367 if (!_svmf_is_set_flag (cS->access_flags, SVM_ACC_INTERFACE))
368 {
369 /* S is a class */
370 if (!(T->is_array))
371 {
372 _svmt_class_info *cT = _svmf_cast_class (T);
373
374 if (!_svmf_is_set_flag (cT->access_flags, SVM_ACC_INTERFACE))
375 {
376 /* T is a class */
377 jint s = cS->data.noninterface.super_classes_size;
378 jint t = cT->data.noninterface.super_classes_size;
379
380 if ((s < t)
381 || (cS->data.noninterface.super_classes[t - 1] != cT))
382 {
383 return JNI_FALSE;
384 }
385 else
386 {
387 return JNI_TRUE;
388 }
389 }
390 else
391 {
392 /* T is an interface */
393 jint s = cS->data.noninterface.max_interface_id;
394 jint t = cT->data.interface.interface_id;
395
396 if ((s < t) ||
397 (_svmf_get_bit
398 (cS->data.noninterface.super_interfaces, t) == 0))
399 {
400 return JNI_FALSE;
401 }
402 else
403 {
404 return JNI_TRUE;
405 }
406 }
407 }
408 else
409 {
410 /* T is an array */
411 return JNI_FALSE;
412 }
413 }
414 else
415 {
416 /* S is an interface */
417 if (!(T->is_array))
418 {
419 _svmt_class_info *cT = _svmf_cast_class (T);
420
421 if (!_svmf_is_set_flag (cT->access_flags, SVM_ACC_INTERFACE))
422 {
423 /* T is a class */
424 if (cT == vm->class_loading.boot_loader.classes.jlobject)
425 {
426 return JNI_TRUE;
427 }
428 else
429 {
430 return JNI_FALSE;
431 }
432 }
433 else
434 {
435 /* T is an interface */
436 jint s = cS->data.interface.interface_id;
437 jint t = cT->data.interface.interface_id;
438
439 if ((s < t) ||
440 (_svmf_get_bit (cS->data.interface.super_interfaces, t)
441 == 0))
442 {
443 return JNI_FALSE;
444 }
445 else
446 {
447 return JNI_TRUE;
448 }
449 }
450 }
451 else
452 {
453 /* T is an array */
454 return JNI_FALSE;
455 }
456 }
457 }
458 else
459 {
460 /* S is an array */
461 _svmt_array_info *aS = _svmf_cast_array (S);
462
463 if (!(T->is_array))
464 {
465 _svmt_class_info *cT = _svmf_cast_class (T);
466
467 if (!_svmf_is_set_flag (cT->access_flags, SVM_ACC_INTERFACE))
468 {
469 /* T is a class */
470 if (cT == vm->class_loading.boot_loader.classes.jlobject)
471 {
472 return JNI_TRUE;
473 }
474 else
475 {
476 return JNI_FALSE;
477 }
478 }
479 else
480 {
481 /* T is an interface */
482 if ((cT == vm->class_loading.boot_loader.classes.jlcloneable) ||
483 (cT ==
484 vm->class_loading.boot_loader.classes.jiserializable))
485 {
486 return JNI_TRUE;
487 }
488 else
489 {
490 return JNI_FALSE;
491 }
492 }
493 }
494 else
495 {
496 /* T is an array */
497 _svmt_array_info *aT = _svmf_cast_array (T);
498
499 if ((aS->dimensions == 1 && aS->base_type != SVM_TYPE_REFERENCE) ||
500 (aT->dimensions == 1 && aT->base_type != SVM_TYPE_REFERENCE))
501 {
502 /* S or T is an array of primitive type */
503 if (aS->dimensions == aT->dimensions &&
504 aS->base_type == aT->base_type)
505 {
506 return JNI_TRUE;
507 }
508 else
509 {
510 return JNI_FALSE;
511 }
512 }
513
514 /* redo with element types */
515
516 if (aS->dimensions == 1)
517 {
518 #ifndef _SABLEVM_INLINED_THREADED_INTERPRETER
519 assert (aS->base_type == SVM_TYPE_REFERENCE);
520 assert (aS->base_class != NULL);
521 #endif
522
523 S = _svmf_cast_type_class (aS->base_class);
524 }
525 else
526 {
527 #ifndef _SABLEVM_INLINED_THREADED_INTERPRETER
528 assert (aS->array_element != NULL);
529 #endif
530
531 S = _svmf_cast_type_array (aS->array_element);
532 }
533
534 if (aT->dimensions == 1)
535 {
536 #ifndef _SABLEVM_INLINED_THREADED_INTERPRETER
537 assert (aT->base_type == SVM_TYPE_REFERENCE);
538 assert (aT->base_class != NULL);
539 #endif
540
541 T = _svmf_cast_type_class (aT->base_class);
542 }
543 else
544 {
545 #ifndef _SABLEVM_INLINED_THREADED_INTERPRETER
546 assert (aT->array_element != NULL);
547 #endif
548
549 T = _svmf_cast_type_array (aT->array_element);
550 }
551
552 goto loop;
553 }
554 }
555
556 #ifndef _SABLEVM_INLINED_THREADED_INTERPRETER
557 _svmm_fatal_error ("impossible control flow");
558 #endif
559 }
560
561 /*
562 ----------------------------------------------------------------------
563 _svmf_set_reference_array_element_no_exception
564 ----------------------------------------------------------------------
565 */
566
567 inline svm_static jint
_svmf_set_reference_array_element_no_exception(_svmt_JNIEnv * env,_svmt_array_instance * array,jint indx,_svmt_object_instance * value)568 _svmf_set_reference_array_element_no_exception (_svmt_JNIEnv *env,
569 _svmt_array_instance *array,
570 jint indx,
571 _svmt_object_instance *value)
572 {
573 _svmt_object_instance **elements;
574
575 #ifndef _SABLEVM_INLINED_THREADED_INTERPRETER
576 assert (array != NULL);
577 assert (array->vtable->type->is_array);
578 assert (indx >= 0 && indx < array->size);
579 assert (array->vtable->type->is_array == JNI_TRUE);
580 #endif
581
582 /* check that value is of appropriate type */
583 if (value != NULL)
584 {
585 _svmt_array_info *array_type = _svmf_cast_array (array->vtable->type);
586 _svmt_type_info *element_type;
587
588 if (array_type->dimensions > 1)
589 {
590 #ifndef _SABLEVM_INLINED_THREADED_INTERPRETER
591 assert (array_type->array_element != NULL);
592 #endif
593
594 element_type = _svmf_cast_type_array (array_type->array_element);
595 }
596 else
597 {
598 #ifndef _SABLEVM_INLINED_THREADED_INTERPRETER
599 assert (array_type->dimensions == 1);
600 assert (array_type->base_type == SVM_TYPE_REFERENCE);
601 assert (array_type->base_class != NULL);
602 #endif
603
604 element_type = _svmf_cast_type_class (array_type->base_class);
605 }
606
607 if (!_svmf_is_assignable_from (env, value->vtable->type, element_type))
608 {
609 return JNI_ERR;
610 }
611 }
612
613 #if defined (_SABLEVM_BIDIRECTIONAL_OBJECT_LAYOUT)
614
615 elements = (_svmt_object_instance **) array;
616 elements[(-1) - indx] = value;
617 #if defined (_SABLEVM_GC_WRITE_BARRIER)
618 _svmf_write_barrier
619 (env, (_svmt_object_instance **) &elements[(-1) - indx]);
620 #endif /* _SABLEVM_GC_WRITE_BARRIER */
621
622 #else
623
624 elements = (_svmt_object_instance **)
625 (((char *) array) + _svmf_aligned_size_t (sizeof (_svmt_array_instance)));
626
627 elements[indx] = value;
628 #if defined (_SABLEVM_GC_WRITE_BARRIER)
629 _svmf_write_barrier (env, (_svmt_object_instance **) &elements[indx]);
630 #endif /* _SABLEVM_GC_WRITE_BARRIER */
631
632 #endif
633
634 return JNI_OK;
635 }
636
637 /*
638 ----------------------------------------------------------------------
639 _svmf_tree_compare_type
640 ----------------------------------------------------------------------
641 */
642
643 inline svm_static jint
_svmf_tree_compare_type(_svmt_type_node * value1,_svmt_type_node * value2)644 _svmf_tree_compare_type (_svmt_type_node *value1, _svmt_type_node *value2)
645 {
646 assert (value1 != NULL);
647 assert (value2 != NULL);
648
649 return strcmp (value1->name, value2->name);
650 }
651
652 /*
653 ----------------------------------------------------------------------
654 _svmf_tree_compare_interface_method_signature
655 ----------------------------------------------------------------------
656 */
657
658 inline svm_static jint
_svmf_tree_compare_imethod_signature(_svmt_imethod_signature_node * value1,_svmt_imethod_signature_node * value2)659 _svmf_tree_compare_imethod_signature (_svmt_imethod_signature_node *value1,
660 _svmt_imethod_signature_node *value2)
661 {
662 jint diff = strcmp (value1->name, value2->name);
663
664 if (diff == 0)
665 {
666 diff = strcmp (value1->descriptor, value2->descriptor);
667 }
668
669 return diff;
670 }
671
672 /*
673 ----------------------------------------------------------------------
674 _svmf_tree_compare_gc_map
675 ----------------------------------------------------------------------
676 */
677
678 inline svm_static jint
_svmf_tree_compare_gc_map(_svmt_gc_map_node * value1,_svmt_gc_map_node * value2)679 _svmf_tree_compare_gc_map (_svmt_gc_map_node *value1,
680 _svmt_gc_map_node *value2)
681 {
682 jint diff;
683 jint i;
684 jint size;
685
686 assert (value1 != NULL);
687 assert (value2 != NULL);
688
689 diff = value1->size - value2->size;
690 i = 0;
691 size = value1->size;
692
693 while (diff == 0 && i < size)
694 {
695 diff =
696 _svmf_get_bit (value1->bits, i) - _svmf_get_bit (value2->bits, i);
697 i++;
698 }
699
700 return diff;
701 }
702
703 /*
704 ----------------------------------------------------------------------
705 _svmf_tree_compare_sequence
706 ----------------------------------------------------------------------
707 */
708
709 inline svm_static jint
_svmf_tree_compare_sequence(_svmt_sequence_node * value1,_svmt_sequence_node * value2)710 _svmf_tree_compare_sequence (_svmt_sequence_node *value1,
711 _svmt_sequence_node *value2)
712 {
713 jint diff;
714 jint i;
715 jint size;
716
717 assert (value1 != NULL);
718 assert (value2 != NULL);
719
720 diff = value1->instructions_length - value2->instructions_length;
721 i = 0;
722 size = value1->instructions_length;
723
724 while (diff == 0 && i < size)
725 {
726 diff = value1->instructions[i] - value2->instructions[i];
727 i++;
728 }
729
730 return diff;
731 }
732
733 /*
734 ----------------------------------------------------------------------
735 _svmf_tree_compare_internal_method
736 ----------------------------------------------------------------------
737 */
738
739 inline svm_static jint
_svmf_tree_compare_internal_method(_svmt_internal_method_node * value1,_svmt_internal_method_node * value2)740 _svmf_tree_compare_internal_method (_svmt_internal_method_node *value1,
741 _svmt_internal_method_node *value2)
742 {
743 assert (value1 != NULL);
744 assert (value2 != NULL);
745
746 return strcmp (value1->name, value2->name);
747 }
748
749 /*
750 ----------------------------------------------------------------------
751 _svmh_global_copy_jobject
752 ----------------------------------------------------------------------
753 */
754
755 inline svm_static jint
_svmh_global_copy_jobject(_svmt_JNIEnv * env,jobject src,jobject * dest)756 _svmh_global_copy_jobject (_svmt_JNIEnv *env, jobject src, jobject *dest)
757 {
758 assert (src != NULL);
759
760 if (_svmm_new_native_global (env, *dest) != JNI_OK)
761 {
762 return JNI_ERR;
763 }
764
765 **dest = *src;
766 return JNI_OK;
767 }
768
769 /*
770 ----------------------------------------------------------------------
771 _svmh_galloc_copy_str_no_exception
772 ----------------------------------------------------------------------
773 */
774
775 #define _svmm_galloc_copy_str_no_exception(dst, src) \
776 _svmh_galloc_copy_str_no_exception (&dst, src)
777
778 svm_static jint
_svmh_galloc_copy_str_no_exception(char ** dest,const char * src)779 _svmh_galloc_copy_str_no_exception (char **dest, const char *src)
780 {
781 char *tmp;
782
783 assert (src != NULL);
784
785 tmp = _svmf_malloc (strlen (src) + 1);
786
787 if (tmp == NULL)
788 {
789 return JNI_ERR;
790 }
791
792 strcpy (tmp, src);
793
794 *dest = tmp;
795 return JNI_OK;
796 }
797
798 /*
799 ----------------------------------------------------------------------
800 _svmh_gfree_str_no_exception
801 ----------------------------------------------------------------------
802 */
803
804 #define _svmm_gfree_str_no_exception(str) \
805 _svmh_gfree_str_no_exception (&str)
806
807 svm_static void
_svmh_gfree_str_no_exception(char ** str)808 _svmh_gfree_str_no_exception (char **str)
809 {
810 assert (*str != NULL);
811
812 _svmf_free (*str);
813 *str = NULL;
814 }
815
816 /*
817 ----------------------------------------------------------------------
818 _svmh_galloc_copy_str
819 ----------------------------------------------------------------------
820 */
821
822 #define _svmm_galloc_copy_str(env, dst, src) \
823 _svmh_galloc_copy_str (env, &dst, src)
824
825 svm_static jint
_svmh_galloc_copy_str(_svmt_JNIEnv * env,char ** dest,const char * src)826 _svmh_galloc_copy_str (_svmt_JNIEnv *env, char **dest, const char *src)
827 {
828 char *tmp;
829
830 assert (src != NULL);
831
832 tmp = _svmf_malloc (strlen (src) + 1);
833
834 if (tmp == NULL)
835 {
836 _svmf_error_OutOfMemoryError (env);
837 return JNI_ERR;
838 }
839
840 strcpy (tmp, src);
841
842 *dest = tmp;
843 return JNI_OK;
844 }
845
846 /*
847 ----------------------------------------------------------------------
848 _svmh_gfree_str
849 ----------------------------------------------------------------------
850 */
851
852 #define _svmm_gfree_str(str) \
853 _svmh_gfree_str (&str)
854
855 svm_static void
_svmh_gfree_str(char ** str)856 _svmh_gfree_str (char **str)
857 {
858 assert (*str != NULL);
859
860 _svmf_free (*str);
861 *str = NULL;
862 }
863
864 /*
865 ----------------------------------------------------------------------
866 _svmh_new_native_global_array
867 ----------------------------------------------------------------------
868 */
869
870 #ifdef COMMENT
871
872 static jint
_svmh_new_native_global_array(_svmt_JNIEnv * env,jarray * array)873 _svmh_new_native_global_array (_svmt_JNIEnv *env, jarray *array)
874 {
875 return _svmh_new_native_global (env, (jobject *) array);
876 }
877
878 #endif /* COMMENT */
879
880 /*
881 ----------------------------------------------------------------------
882 _svmh_free_native_global_array
883 ----------------------------------------------------------------------
884 */
885
886 #ifdef COMMENT
887
888 static void
_svmh_free_native_global_array(_svmt_JNIEnv * env,jarray * pglobal_arrayref)889 _svmh_free_native_global_array (_svmt_JNIEnv *env, jarray *pglobal_arrayref)
890 {
891 _svmh_free_native_global (env, (jobject *) pglobal_arrayref);
892 }
893
894 #endif /* COMMENT */
895
896 /*
897 ----------------------------------------------------------------------
898 _svmh_new_native_local_array
899 ----------------------------------------------------------------------
900 */
901
902 static jint
_svmh_new_native_local_array(_svmt_JNIEnv * env,jarray * array)903 _svmh_new_native_local_array (_svmt_JNIEnv *env, jarray *array)
904 {
905 return _svmh_new_native_local (env, (jobject *) array);
906 }
907
908 /*
909 ----------------------------------------------------------------------
910 _svmh_free_native_local_array
911 ----------------------------------------------------------------------
912 */
913
914 static void
_svmh_free_native_local_array(_svmt_JNIEnv * env,jarray * pglobal_arrayref)915 _svmh_free_native_local_array (_svmt_JNIEnv *env, jarray *pglobal_arrayref)
916 {
917 _svmh_free_native_local (env, (jobject *) pglobal_arrayref);
918 }
919
920 /*
921 ----------------------------------------------------------------------
922 _svmh_local_wrap_pointer
923 ----------------------------------------------------------------------
924 */
925
926 svm_static jint
_svmh_local_wrap_pointer(_svmt_JNIEnv * env,void * pointer,jbyteArray * pwrapper)927 _svmh_local_wrap_pointer (_svmt_JNIEnv *env, void *pointer,
928 jbyteArray *pwrapper)
929 {
930 _svmt_JavaVM *vm = env->vm;
931 jbyteArray wrapper = NULL;
932
933 if (_svmm_new_native_local_array (env, wrapper) != JNI_OK)
934 {
935 return JNI_ERR;
936 }
937
938 if (_svmm_new_array_instance
939 (env, vm->class_loading.boot_loader.classes.byte_array, sizeof (void *),
940 *wrapper) != JNI_OK)
941 {
942 _svmm_free_native_local_array (env, wrapper);
943 return JNI_ERR;
944 }
945
946 /* put "pointer" into the "wrapper" array */
947 *((void **) (void *)
948 (((char *) *wrapper) + _svmf_aligned_size_t
949 (sizeof (_svmt_array_instance)))) = pointer;
950
951 *pwrapper = wrapper;
952
953 return JNI_OK;
954 }
955
956 /*
957 ----------------------------------------------------------------------
958 _svmf_wrap_pointer
959 ----------------------------------------------------------------------
960 */
961
962 svm_static jint
_svmf_wrap_pointer(_svmt_JNIEnv * env,void * pointer,jbyteArray wrapper)963 _svmf_wrap_pointer (_svmt_JNIEnv *env, void *pointer, jbyteArray wrapper)
964 {
965 _svmt_JavaVM *vm = env->vm;
966
967 if (_svmm_new_array_instance
968 (env, vm->class_loading.boot_loader.classes.byte_array, sizeof (void *),
969 *wrapper) != JNI_OK)
970 {
971 return JNI_ERR;
972 }
973
974 /* put "pointer" into the "wrapper" array */
975 *((void **) (void *)
976 (((char *) *wrapper) + _svmf_aligned_size_t
977 (sizeof (_svmt_array_instance)))) = pointer;
978
979 return JNI_OK;
980 }
981
982 /*
983 ----------------------------------------------------------------------
984 _svmf_unwrap_pointer
985 ----------------------------------------------------------------------
986 */
987
988 static void *
_svmf_unwrap_pointer(_svmt_array_instance * wrapper)989 _svmf_unwrap_pointer (_svmt_array_instance *wrapper)
990 {
991 return *((void **) (void *)
992 (((char *) wrapper) +
993 _svmf_aligned_size_t (sizeof (_svmt_array_instance))));
994 }
995
996 /*
997 ----------------------------------------------------------------------
998 _svmf_unwrap_class_instance
999 ----------------------------------------------------------------------
1000 */
1001
1002 svm_static _svmt_type_info *
_svmf_unwrap_class_instance(_svmt_JNIEnv * env,jclass class)1003 _svmf_unwrap_class_instance (_svmt_JNIEnv *env, jclass class)
1004 {
1005 _svmt_JavaVM *vm = env->vm;
1006 _svmt_array_instance *vmdata;
1007
1008 vmdata = _svmf_cast_array_instance
1009 (_svmf_get_REFERENCE_field (*class,
1010 vm->class_loading.boot_loader.fields.
1011 jlclass_vmdata->data.instance_field.offset));
1012
1013 return (_svmt_type_info *) _svmf_unwrap_pointer (vmdata);
1014 }
1015
1016 /*
1017 ----------------------------------------------------------------------
1018 _svmf_unwrap_field_instance
1019 ----------------------------------------------------------------------
1020 */
1021
1022 svm_static _svmt_field_info *
_svmf_unwrap_field_instance(_svmt_JNIEnv * env,jobject obj)1023 _svmf_unwrap_field_instance (_svmt_JNIEnv *env, jobject obj)
1024 {
1025 _svmt_JavaVM *vm = env->vm;
1026 _svmt_array_instance *vmdata;
1027
1028 vmdata = _svmf_cast_array_instance
1029 (_svmf_get_REFERENCE_field (*obj,
1030 vm->class_loading.boot_loader.fields.
1031 jlrfield_vmdata->data.instance_field.offset));
1032
1033 return (_svmt_field_info *) _svmf_unwrap_pointer (vmdata);
1034 }
1035
1036 /*
1037 ----------------------------------------------------------------------
1038 _svmf_unwrap_method_instance
1039 ----------------------------------------------------------------------
1040 */
1041
1042 svm_static _svmt_method_info *
_svmf_unwrap_method_instance(_svmt_JNIEnv * env,jobject obj)1043 _svmf_unwrap_method_instance (_svmt_JNIEnv *env, jobject obj)
1044 {
1045 _svmt_JavaVM *vm = env->vm;
1046 _svmt_array_instance *vmdata;
1047
1048 vmdata = _svmf_cast_array_instance
1049 (_svmf_get_REFERENCE_field (*obj,
1050 vm->class_loading.boot_loader.fields.
1051 jlrmethod_vmdata->data.instance_field.
1052 offset));
1053
1054 return (_svmt_method_info *) _svmf_unwrap_pointer (vmdata);
1055 }
1056
1057 /*
1058 ----------------------------------------------------------------------
1059 _svmf_unwrap_constructor_instance
1060 ----------------------------------------------------------------------
1061 */
1062
1063 svm_static _svmt_method_info *
_svmf_unwrap_constructor_instance(_svmt_JNIEnv * env,jobject obj)1064 _svmf_unwrap_constructor_instance (_svmt_JNIEnv *env, jobject obj)
1065 {
1066 _svmt_JavaVM *vm = env->vm;
1067 _svmt_array_instance *vmdata;
1068
1069 vmdata = _svmf_cast_array_instance
1070 (_svmf_get_REFERENCE_field (*obj,
1071 vm->class_loading.boot_loader.fields.
1072 jlrconstructor_vmdata->data.instance_field.
1073 offset));
1074
1075 return (_svmt_method_info *) _svmf_unwrap_pointer (vmdata);
1076 }
1077
1078 /*
1079 ----------------------------------------------------------------------
1080 _svmf_new_class
1081 ----------------------------------------------------------------------
1082 */
1083
1084 svm_static jint
_svmf_new_class_pd(_svmt_JNIEnv * env,_svmt_type_info * type,jobject protection_domain)1085 _svmf_new_class_pd (_svmt_JNIEnv *env, _svmt_type_info *type,
1086 jobject protection_domain)
1087 {
1088 _svmt_JavaVM *vm = env->vm;
1089 jbyteArray data = NULL;
1090 jclass class_instance = NULL;
1091
1092 if (_svmm_local_wrap_pointer (env, type, data) != JNI_OK)
1093 {
1094 return JNI_ERR;
1095 }
1096
1097 if (_svmm_new_native_global (env, class_instance) != JNI_OK)
1098 {
1099 _svmm_free_native_local_array (env, data);
1100 return JNI_ERR;
1101 }
1102
1103 if (_svmm_new_object_instance
1104 (env, vm->class_loading.boot_loader.classes.jlclass,
1105 *class_instance) != JNI_OK)
1106 {
1107 _svmm_free_native_local_array (env, data);
1108 _svmm_free_native_global (env, class_instance);
1109 return JNI_ERR;
1110 }
1111
1112 if (_svmm_invoke_nonvirtual_jlclass_init
1113 (env, class_instance, _svmf_cast_jobject (data),
1114 protection_domain) != JNI_OK)
1115 {
1116 _svmm_free_native_local_array (env, data);
1117 _svmm_free_native_global (env, class_instance);
1118 return JNI_ERR;
1119 }
1120
1121 _svmm_free_native_local_array (env, data);
1122
1123 type->class_instance = class_instance;
1124
1125 return JNI_OK;
1126 }
1127
1128 svm_static jint
_svmf_new_class(_svmt_JNIEnv * env,_svmt_type_info * type)1129 _svmf_new_class (_svmt_JNIEnv *env, _svmt_type_info *type)
1130 {
1131 return _svmf_new_class_pd (env, type, (jobject) (NULL));
1132 }
1133
1134 /*
1135 ----------------------------------------------------------------------
1136 _svmf_find_method_in_class
1137 ----------------------------------------------------------------------
1138 */
1139
1140 /*
1141 inline static _svmt_method_info *
1142 _svmf_find_method_in_class (_svmt_class_info *class, const char *name,
1143 const char *descriptor)
1144 {
1145 jint methods_count = class->methods_count;
1146 _svmt_method_info *methods = class->methods;
1147 jint i;
1148
1149 for (i = 0; i < methods_count; i++)
1150 {
1151 _svmt_method_info *method = &methods[i];
1152
1153 if (strcmp (name, DREF (method->name, value)) == 0 &&
1154 strcmp (descriptor, DREF (method->descriptor, value)) == 0)
1155 {
1156 return method;
1157 }
1158 }
1159
1160 return NULL;
1161 }
1162 */
1163
1164 /*
1165 ----------------------------------------------------------------------
1166 _svmf_get_string
1167 ----------------------------------------------------------------------
1168 */
1169
1170 svm_static jint
_svmf_get_string(_svmt_JNIEnv * env,const char * value,jstring str)1171 _svmf_get_string (_svmt_JNIEnv *env, const char *value, jstring str)
1172 {
1173 _svmt_JavaVM *vm = env->vm;
1174 jbyteArray data = NULL;
1175 jint length = strlen (value);
1176 jint status;
1177
1178 if (_svmm_new_native_local_array (env, data) != JNI_OK)
1179 {
1180 return JNI_ERR;
1181 }
1182
1183 if (_svmm_new_array_instance
1184 (env, vm->class_loading.boot_loader.classes.byte_array, length,
1185 *data) != JNI_OK)
1186 {
1187 _svmm_free_native_local_array (env, data);
1188 return JNI_ERR;
1189 }
1190
1191 /* put the string characters into the "wrapper" array without
1192 including the end-of-string '\0' marker */
1193 strncpy (((char *) *data) +
1194 _svmf_aligned_size_t (sizeof (_svmt_array_instance)), value,
1195 length);
1196
1197 status =
1198 _svmm_invoke_static_stringcreator_createstring
1199 (env, _svmf_cast_jobject (data), str);
1200
1201 _svmm_free_native_local_array (env, data);
1202
1203 return status;
1204 }
1205
1206 /*
1207 ----------------------------------------------------------------------
1208 _svmf_get_interned_string
1209 ----------------------------------------------------------------------
1210 */
1211
1212 svm_static jint
_svmf_get_interned_string(_svmt_JNIEnv * env,const char * value,jstring str)1213 _svmf_get_interned_string (_svmt_JNIEnv *env, const char *value, jstring str)
1214 {
1215 _svmt_JavaVM *vm = env->vm;
1216 jbyteArray data = NULL;
1217 jint length = strlen (value);
1218 jint status;
1219
1220 if (_svmm_new_native_local_array (env, data) != JNI_OK)
1221 {
1222 return JNI_ERR;
1223 }
1224
1225 if (_svmm_new_array_instance
1226 (env, vm->class_loading.boot_loader.classes.byte_array, length,
1227 *data) != JNI_OK)
1228 {
1229 _svmm_free_native_local_array (env, data);
1230 return JNI_ERR;
1231 }
1232
1233 /* put the string characters into the "wrapper" array without
1234 including the end-of-string '\0' marker */
1235 strncpy (((char *) *data) +
1236 _svmf_aligned_size_t (sizeof (_svmt_array_instance)), value,
1237 length);
1238
1239 status =
1240 _svmm_invoke_static_stringcreator_createinternedstring
1241 (env, _svmf_cast_jobject (data), str);
1242
1243 _svmm_free_native_local_array (env, data);
1244
1245 return status;
1246 }
1247
1248 /*
1249 ----------------------------------------------------------------------
1250 _svmf_get_current_working_directory
1251 ----------------------------------------------------------------------
1252 */
1253
1254 svm_static const char *
_svmf_get_current_working_directory(void)1255 _svmf_get_current_working_directory (void)
1256 {
1257 size_t size = 1024;
1258 char *buffer = _svmf_malloc (size);
1259
1260 while (buffer != NULL)
1261 {
1262 if (getcwd (buffer, size) != NULL)
1263 {
1264 return buffer;
1265 }
1266
1267 _svmf_free (buffer);
1268
1269 {
1270 size_t old_size = size;
1271
1272 size *= 2;
1273
1274 if (size <= old_size)
1275 {
1276 return NULL;
1277 }
1278 }
1279
1280 buffer = _svmf_malloc (size);
1281 }
1282
1283 return NULL;
1284 }
1285
1286 /*
1287 ----------------------------------------------------------------------
1288 _svmm_galloc_utf_chars
1289 ----------------------------------------------------------------------
1290 */
1291
1292 #define _svmm_galloc_utf_chars(env, src, dst) \
1293 _svmh_galloc_utf_chars (env, src, &dst)
1294
1295 #define _svmm_gfree_utf_chars(str) \
1296 _svmm_gfree_str(str)
1297
1298 svm_static jint
_svmh_galloc_utf_chars(_svmt_JNIEnv * env,jstring src,char ** pdst)1299 _svmh_galloc_utf_chars (_svmt_JNIEnv *env, jstring src, char **pdst)
1300 {
1301 jbyteArray bytes;
1302 char *result;
1303
1304 if (_svmm_new_native_local_array (env, bytes) != JNI_OK)
1305 {
1306 return JNI_ERR;
1307 }
1308
1309 if (_svmm_invoke_static_stringcreator_getutfchars
1310 (env, src, _svmf_cast_jobject (bytes)) != JNI_OK)
1311 {
1312 _svmm_free_native_local_array (env, bytes);
1313 return JNI_ERR;
1314 }
1315
1316 {
1317 char *str =
1318 ((char *) *bytes) +
1319 _svmf_aligned_size_t (sizeof (_svmt_array_instance));
1320
1321 if (_svmm_galloc_copy_str (env, result, str) != JNI_OK)
1322 {
1323 _svmm_free_native_local_array (env, bytes);
1324 return JNI_ERR;
1325 }
1326
1327 _svmm_free_native_local_array (env, bytes);
1328 *pdst = result;
1329 return JNI_OK;
1330 }
1331 }
1332
1333 /*
1334 ----------------------------------------------------------------------
1335 _svmf_is_super_class
1336 ----------------------------------------------------------------------
1337 */
1338
1339 svm_static jboolean
_svmf_is_super_class(_svmt_class_info * class1,_svmt_class_info * class2)1340 _svmf_is_super_class (_svmt_class_info *class1, _svmt_class_info *class2)
1341 {
1342 _svmt_class_info *current;
1343
1344 if (CAN_DREF (class2->super_class))
1345 {
1346 current = _svmf_cast_class (DREF (class2->super_class, type));
1347 }
1348 else
1349 {
1350 current = NULL;
1351 }
1352
1353 while (current != NULL)
1354 {
1355 if (current == class1)
1356 {
1357 return JNI_TRUE;
1358 }
1359
1360 if (CAN_DREF (current->super_class))
1361 {
1362 current = _svmf_cast_class (DREF (current->super_class, type));
1363 }
1364 else
1365 {
1366 current = NULL;
1367 }
1368 }
1369
1370 return JNI_FALSE;
1371 }
1372
1373 /*
1374 ----------------------------------------------------------------------
1375 _svmf_get_current_class_loader
1376 ----------------------------------------------------------------------
1377 */
1378
1379 svm_static _svmt_class_loader_info *
_svmf_get_current_class_loader(_svmt_JNIEnv * env)1380 _svmf_get_current_class_loader (_svmt_JNIEnv *env)
1381 {
1382 _svmt_JavaVM *vm = env->vm;
1383 _svmt_stack_frame *frame = env->stack.current_frame;
1384 _svmt_method_info *method = frame->method;
1385
1386 while (method != &vm->stack_bottom_method &&
1387 method != &vm->vm_initiated_call_method)
1388 {
1389 if ((!_svmf_is_set_flag (method->access_flags, SVM_ACC_INTERNAL)) &&
1390 method->class_info->class_loader_info->class_loader != NULL)
1391 {
1392 return method->class_info->class_loader_info;
1393 }
1394
1395 frame = (_svmt_stack_frame *) (void *)
1396 (((char *) frame) - frame->previous_offset);
1397 method = frame->method;
1398 }
1399
1400 return vm->class_loading.boot_loader.class_loader_info;
1401 }
1402
1403 /*
1404 ----------------------------------------------------------------------
1405 _svmf_enter_class_loader_monitor
1406 ----------------------------------------------------------------------
1407 */
1408
1409 svm_static jint
_svmf_enter_class_loader_monitor(_svmt_JNIEnv * env,_svmt_class_loader_info * class_loader_info)1410 _svmf_enter_class_loader_monitor (_svmt_JNIEnv *env,
1411 _svmt_class_loader_info *class_loader_info)
1412 {
1413 if (class_loader_info->class_loader == NULL)
1414 {
1415 _svmt_JavaVM *vm = env->vm;
1416 assert (class_loader_info ==
1417 vm->class_loading.boot_loader.class_loader_info);
1418
1419 if (_svmf_enter_object_monitor
1420 (env,
1421 *(vm->class_loading.boot_loader.classes.virtualmachine->
1422 class_instance)) != JNI_OK)
1423 {
1424 return JNI_ERR;
1425 }
1426 }
1427 else
1428 {
1429 if (_svmf_enter_object_monitor (env, *(class_loader_info->class_loader))
1430 != JNI_OK)
1431 {
1432 return JNI_ERR;
1433 }
1434 }
1435
1436 return JNI_OK;
1437 }
1438
1439 /*
1440 ----------------------------------------------------------------------
1441 _svmf_exit_class_loader_monitor
1442 ----------------------------------------------------------------------
1443 */
1444
1445 svm_static jint
_svmf_exit_class_loader_monitor(_svmt_JNIEnv * env,_svmt_class_loader_info * class_loader_info)1446 _svmf_exit_class_loader_monitor (_svmt_JNIEnv *env,
1447 _svmt_class_loader_info *class_loader_info)
1448 {
1449 if (class_loader_info->class_loader == NULL)
1450 {
1451 _svmt_JavaVM *vm = env->vm;
1452 assert (class_loader_info ==
1453 vm->class_loading.boot_loader.class_loader_info);
1454
1455 if (_svmf_exit_object_monitor
1456 (env,
1457 *(vm->class_loading.boot_loader.classes.virtualmachine->
1458 class_instance)) != JNI_OK)
1459 {
1460 return JNI_ERR;
1461 }
1462 }
1463 else
1464 {
1465 if (_svmf_exit_object_monitor (env, *(class_loader_info->class_loader))
1466 != JNI_OK)
1467 {
1468 return JNI_ERR;
1469 }
1470 }
1471
1472 return JNI_OK;
1473 }
1474
1475 /*
1476 ----------------------------------------------------------------------
1477 _svmf_wrap_exception_in_invocationte
1478 ----------------------------------------------------------------------
1479 */
1480
1481 /* This function wraps the "current_exception" parameter into a new
1482 InvocationTargetException instance, then throws it. */
1483
1484 svm_static int
_svmf_wrap_exception_in_invocationte(_svmt_JNIEnv * env,jobject current_exception)1485 _svmf_wrap_exception_in_invocationte (_svmt_JNIEnv *env,
1486 jobject current_exception)
1487 {
1488 _svmt_JavaVM *vm = env->vm;
1489 jobject invocationte = NULL;
1490 jint status;
1491
1492 if (_svmm_new_native_local (env, invocationte) != JNI_OK)
1493 {
1494 return JNI_ERR;
1495 }
1496
1497 if (_svmm_new_object_instance
1498 (env,
1499 vm->class_loading.boot_loader.classes.jlrinvocationtargetexception,
1500 *invocationte) != JNI_OK)
1501 {
1502 _svmm_free_native_local (env, invocationte);
1503 return JNI_ERR;
1504 }
1505
1506 status =
1507 _svmm_invoke_nonvirtual_jlrinvocationtargetexception_init (env,
1508 invocationte,
1509 current_exception);
1510
1511 /* if no exception was raised, throw InvocationTargetException
1512 instance */
1513 if (status == JNI_OK)
1514 {
1515 *(env->throwable) = *invocationte;
1516 }
1517
1518 _svmm_free_native_local (env, invocationte);
1519
1520 return JNI_ERR;
1521 }
1522
1523 /*
1524 ----------------------------------------------------------------------
1525 _svmf_verbose_methods_enter
1526 ----------------------------------------------------------------------
1527 */
1528
1529 #ifndef NDEBUG
1530
1531 inline svm_static void
_svmf_verbose_methods_enter(_svmt_JNIEnv * env)1532 _svmf_verbose_methods_enter (_svmt_JNIEnv *env)
1533 {
1534 if (env->vm->verbose_methods == JNI_TRUE)
1535 {
1536 _svmt_method_info *method = env->stack.current_frame->method;
1537
1538 _svmf_printf (env, stderr,
1539 "T%d: [verbose methods: entering method %s.%s%s]\n",
1540 env->thread.id,
1541 method->class_info->name,
1542 DREF (method->name, value),
1543 DREF (method->descriptor, value));
1544 }
1545 }
1546
1547 #endif /* !NDEBUG */
1548
1549 /*
1550 ----------------------------------------------------------------------
1551 _svmf_verbose_methods_exit
1552 ----------------------------------------------------------------------
1553 */
1554
1555 #ifndef NDEBUG
1556
1557 inline svm_static void
_svmf_verbose_methods_exit(_svmt_JNIEnv * env)1558 _svmf_verbose_methods_exit (_svmt_JNIEnv *env)
1559 {
1560 if (env->vm->verbose_methods == JNI_TRUE)
1561 {
1562 _svmt_method_info *method = env->stack.current_frame->method;
1563
1564 _svmf_printf (env, stderr,
1565 "T%d: [verbose methods: exiting method %s.%s%s]\n",
1566 env->thread.id,
1567 method->class_info->name,
1568 DREF (method->name, value),
1569 DREF (method->descriptor, value));
1570
1571 {
1572 _svmt_method_info *caller_method;
1573 _svmt_stack_frame *caller_frame = env->stack.current_frame;
1574 caller_frame = (_svmt_stack_frame *) (void *)
1575 (((char *) caller_frame) - caller_frame->previous_offset);
1576 caller_method = caller_frame->method;
1577
1578 while (_svmf_is_set_flag
1579 (caller_method->access_flags, SVM_ACC_INTERNAL)
1580 && caller_method != &env->vm->stack_bottom_method)
1581 {
1582 caller_frame = (_svmt_stack_frame *) (void *)
1583 (((char *) caller_frame) - caller_frame->previous_offset);
1584 caller_method = caller_frame->method;
1585 }
1586
1587 if (!_svmf_is_set_flag
1588 (caller_method->access_flags, SVM_ACC_INTERNAL))
1589 {
1590 _svmf_printf (env, stderr,
1591 "T%d: [ returning to %s.%s%s]\n",
1592 env->thread.id,
1593 caller_method->class_info->name,
1594 DREF (caller_method->name, value),
1595 DREF (caller_method->descriptor, value));
1596 }
1597 }
1598 }
1599 }
1600
1601 #endif /* !NDEBUG */
1602
1603 /*
1604 ----------------------------------------------------------------------
1605 _svmm_get_type_from_within_descriptor
1606 ----------------------------------------------------------------------
1607 */
1608
1609 #ifndef NDEBUG
1610
1611 #define _svmm_get_type_from_within_descriptor(env, method_info, current, index) \
1612 _svmh_get_type_from_within_descriptor (env, method_info, ¤t, &index)
1613
1614 svm_static _svmt_type_info *
_svmh_get_type_from_within_descriptor(_svmt_JNIEnv * env,_svmt_method_info * method_info,const char ** pcurrent,jint * pindex)1615 _svmh_get_type_from_within_descriptor (_svmt_JNIEnv *env,
1616 _svmt_method_info *method_info,
1617 const char **pcurrent, jint *pindex)
1618 {
1619 const char *current = *pcurrent;
1620 _svmt_type_info *result = NULL;
1621
1622 switch (*current)
1623 {
1624 case 'B':
1625 case 'C':
1626 case 'F':
1627 case 'I':
1628 case 'S':
1629 case 'Z':
1630 case 'V':
1631 {
1632 current++;
1633 (*pindex)++;
1634 }
1635 break;
1636
1637 case 'D':
1638 case 'J':
1639 {
1640 current++;
1641 (*pindex) += 2;
1642 }
1643 break;
1644
1645 case 'L':
1646 {
1647 jint length = 0;
1648 char *p = (char *) current;
1649 _svmt_u8 *name;
1650
1651 while (*++p != ';')
1652 {
1653 length++;
1654 }
1655
1656 if (_svmm_gzmalloc_ubytes (env, length + 1, name) != JNI_OK)
1657 {
1658 _svmm_fatal_error ("unsupported failure while debugging");
1659 }
1660
1661 p = (char *) name;
1662 while (*++current != ';')
1663 {
1664 *(p++) = *current;
1665 }
1666
1667 current++;
1668 (*pindex)++;
1669
1670 if (_svmm_create_type
1671 (env, method_info->class_info->class_loader_info,
1672 (const char *) name, result) != JNI_OK)
1673 {
1674 _svmm_fatal_error ("unsupported failure while debugging");
1675 }
1676
1677 _svmm_gzmfree_ubytes (name);
1678 }
1679 break;
1680
1681 case '[':
1682 {
1683 jint length = 0;
1684 char *p = (char *) current;
1685 _svmt_u8 *name;
1686
1687 while (*p == '[')
1688 {
1689 p++;
1690 length++;
1691 }
1692
1693 if (*p == 'L')
1694 {
1695 while (*p != ';')
1696 {
1697 p++;
1698 length++;
1699 }
1700 length++;
1701 }
1702 else
1703 {
1704 length++;
1705 }
1706
1707 if (_svmm_gzmalloc_ubytes (env, length + 1, name) != JNI_OK)
1708 {
1709 _svmm_fatal_error ("unsupported failure while debugging");
1710 }
1711
1712 p = (char *) name;
1713 while (*current == '[')
1714 {
1715 *(p++) = *current++;
1716 }
1717
1718 if (*current == 'L')
1719 {
1720 while (*current != ';')
1721 {
1722 *(p++) = *current++;
1723 }
1724 *(p++) = *current++;
1725 }
1726 else
1727 {
1728 *(p++) = *current++;
1729 }
1730
1731 (*pindex)++;
1732
1733 if (_svmm_create_type
1734 (env, method_info->class_info->class_loader_info,
1735 (const char *) name, result) != JNI_OK)
1736 {
1737 _svmm_fatal_error ("unsupported failure while debugging");
1738 }
1739
1740 if (_svmf_link_type (env, result) != JNI_OK)
1741 {
1742 _svmm_fatal_error ("unsupported failure while debugging");
1743 }
1744
1745 _svmm_gzmfree_ubytes (name);
1746 }
1747 break;
1748
1749 default:
1750 {
1751 _svmm_fatal_error ("impossible control flow");
1752 }
1753 }
1754
1755 *pcurrent = current;
1756 return result;
1757 }
1758
1759 #endif /* !NDEBUG */
1760
1761 /*
1762 ----------------------------------------------------------------------
1763 _svmm_skip_type_within_descriptor
1764 ----------------------------------------------------------------------
1765 */
1766
1767 #ifndef NDEBUG
1768
1769 #define _svmm_skip_type_within_descriptor(current, index) \
1770 _svmh_skip_type_within_descriptor (¤t, &index)
1771
1772 svm_static void
_svmh_skip_type_within_descriptor(const char ** pcurrent,jint * pindex)1773 _svmh_skip_type_within_descriptor (const char **pcurrent, jint *pindex)
1774 {
1775 const char *current = *pcurrent;
1776
1777 switch (*current++)
1778 {
1779 case 'B':
1780 case 'C':
1781 case 'F':
1782 case 'I':
1783 case 'S':
1784 case 'Z':
1785 case 'V':
1786 {
1787 (*pindex)++;
1788 }
1789 break;
1790
1791 case 'D':
1792 case 'J':
1793 {
1794 (*pindex) += 2;
1795 }
1796 break;
1797
1798 case 'L':
1799 {
1800 while (*current++ != ';');
1801
1802 (*pindex)++;
1803 }
1804 break;
1805
1806 case '[':
1807 {
1808 while (*current == '[')
1809 {
1810 current++;
1811 }
1812
1813 if (*current++ == 'L')
1814 {
1815 while (*current++ != ';');
1816 }
1817
1818 (*pindex)++;
1819 }
1820 break;
1821
1822 default:
1823 {
1824 _svmm_fatal_error ("impossible control flow");
1825 }
1826 }
1827
1828 *pcurrent = current;
1829 }
1830
1831 #endif /* !NDEBUG */
1832
1833 /*
1834 ----------------------------------------------------------------------
1835 _svmf_print_statistics
1836 ----------------------------------------------------------------------
1837 */
1838 #ifdef STATISTICS
1839 svm_static void
_svmf_print_statistics(_svmt_JNIEnv * env)1840 _svmf_print_statistics (_svmt_JNIEnv *env)
1841 {
1842 _svmt_JavaVM *vm = env->vm;
1843
1844 _svmf_printf (env, stderr, "\nSTATS: Number of prepared classes: %d\n",
1845 vm->class_count);
1846 _svmf_printf (env, stderr, "STATS: Number of prepared interfaces: %d\n",
1847 vm->interface_count);
1848 _svmf_printf (env, stderr, "STATS: Number of prepared arrays: %d\n",
1849 vm->array_count);
1850 _svmf_printf (env, stderr, "STATS: Number of prepared methods: %d\n",
1851 vm->method_count);
1852 _svmf_printf (env, stderr,
1853 "STATS: Number of prepared bytecode instructions: %d\n",
1854 vm->bytecode_instruction_count);
1855 _svmf_printf (env, stderr,
1856 "STATS: Number of prepared bytecodes: %d\n",
1857 vm->bytecode_count);
1858 _svmf_printf (env, stderr, "STATS: Code array size: %d\n\n", vm->code_size);
1859
1860 _svmf_printf (env, stderr,
1861 "STATS: Maximum stack size: %d\n", vm->max_stack_size);
1862 _svmf_printf (env, stderr,
1863 "STATS: Number of locals on stack: %d\n",
1864 vm->stack_local_count);
1865 _svmf_printf (env, stderr,
1866 "STATS: Number of split locals on stack: %d\n\n",
1867 vm->stack_local_split_count);
1868
1869 _svmf_printf (env, stderr,
1870 "STATS: Total sparse interface virtual tables size: %d\n",
1871 vm->total_ivtables);
1872 _svmf_printf (env, stderr,
1873 "STATS: Total interface virtual table holes size: %d\n",
1874 vm->total_holes);
1875 _svmf_printf (env, stderr, "STATS: Total wasted holes size: %d\n\n",
1876 vm->total_lost_holes);
1877
1878 _svmf_printf (env, stderr, "STATS: Total GC maps size: %d\n",
1879 vm->total_gc_maps_size);
1880 _svmf_printf (env, stderr, "STATS: GC maps count: %d\n",
1881 vm->total_gc_maps_count);
1882 _svmf_printf (env, stderr, "STATS: GC points count: %d\n\n",
1883 vm->check_points_count);
1884
1885 _svmf_printf (env, stderr, "STATS: Original locals count: %d\n",
1886 vm->total_orig_locals_count);
1887 _svmf_printf (env, stderr, "STATS: Unused locals count: %d\n",
1888 vm->total_unused_locals_count);
1889 _svmf_printf (env, stderr, "STATS: Added locals count: %d\n\n",
1890 vm->total_added_locals_count);
1891
1892 #if defined (_SABLEVM_INLINED_THREADED_INTERPRETER)
1893
1894 _svmf_printf (env, stderr,
1895 "STATS: Number of distinct (inlined) threads:: %d\n",
1896 vm->distinct_inlined_threads_count);
1897 _svmf_printf (env, stderr,
1898 "STATS: Total bytecode count of distinct threads: %d\n",
1899 vm->total_distinct_thread_bc_length);
1900 _svmf_printf (env, stderr,
1901 "STATS: Total inlined size of distinct threads: %d\n\n",
1902 vm->total_distinct_thread_inlined_length);
1903
1904 _svmf_printf (env, stderr, "STATS: Number of (inlined) threads:: %d\n",
1905 vm->inlined_threads_count);
1906 _svmf_printf (env, stderr, "STATS: Total bytecode count of threads: %d\n",
1907 vm->total_thread_bc_length);
1908 _svmf_printf (env, stderr, "STATS: Total inlined size of threads: %d\n\n",
1909 vm->total_thread_inlined_length);
1910
1911 _svmf_printf (env, stderr, "STATS: Maximum thread bytecode count: %d\n",
1912 vm->max_thread_bc_length);
1913 _svmf_printf (env, stderr, "STATS: Maximum thread inlined size: %d\n\n",
1914 vm->max_thread_inlined_length);
1915
1916 #endif
1917
1918 }
1919 #endif /* STATISTICS */
1920