Improved (simpler) subtype check.
[cacao.git] / src / vm / builtin.c
1 /* src/vm/builtin.c - functions for unsupported operations
2
3    Copyright (C) 1996-2005, 2006, 2007, 2008
4    CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
5
6    This file is part of CACAO.
7
8    This program is free software; you can redistribute it and/or
9    modify it under the terms of the GNU General Public License as
10    published by the Free Software Foundation; either version 2, or (at
11    your option) any later version.
12
13    This program is distributed in the hope that it will be useful, but
14    WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16    General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21    02110-1301, USA.
22
23    Contains C functions for JavaVM Instructions that cannot be
24    translated to machine language directly. Consequently, the
25    generated machine code for these instructions contains function
26    calls instead of machine instructions, using the C calling
27    convention.
28
29 */
30
31
32 #include "config.h"
33
34 #include <assert.h>
35 #include <errno.h>
36 #include <stdlib.h>
37 #include <string.h>
38 #include <sys/time.h>
39
40 #include "vm/types.h"
41
42 #include "arch.h"
43 #include "md-abi.h"
44
45 #include "fdlibm/fdlibm.h"
46 #if defined(__CYGWIN__) && defined(Bias)
47 # undef Bias
48 #endif
49
50 #include "mm/gc-common.h"
51 #include "mm/memory.h"
52
53 #include "native/jni.h"
54 #include "native/llni.h"
55
56 #include "threads/lock-common.h"
57 #include "threads/thread.h"
58
59 #include "toolbox/logging.h"
60 #include "toolbox/util.h"
61
62 #include "vm/array.h"
63 #include "vm/builtin.h"
64 #include "vm/cycles-stats.h"
65 #include "vm/exceptions.h"
66 #include "vm/global.h"
67 #include "vm/initialize.h"
68 #include "vm/primitive.h"
69 #include "vm/stringlocal.h"
70
71 #include "vm/jit/asmpart.h"
72 #include "vm/jit/trace.h"
73
74 #include "vmcore/class.h"
75 #include "vmcore/linker.h"
76 #include "vmcore/loader.h"
77 #include "vmcore/options.h"
78 #include "vmcore/rt-timing.h"
79
80 #if defined(ENABLE_VMLOG)
81 #include <vmlog_cacao.h>
82 #endif
83
84
85 /* include builtin tables *****************************************************/
86
87 #include "vm/builtintable.inc"
88
89
90 CYCLES_STATS_DECLARE(builtin_new         ,100,5)
91 CYCLES_STATS_DECLARE(builtin_overhead    , 80,1)
92
93
94 /*============================================================================*/
95 /* BUILTIN TABLE MANAGEMENT FUNCTIONS                                         */
96 /*============================================================================*/
97
98 /* builtintable_init ***********************************************************
99
100    Parse the descriptors of builtin functions and create the parsed
101    descriptors.
102
103 *******************************************************************************/
104
105 static bool builtintable_init(void)
106 {
107         descriptor_pool    *descpool;
108         builtintable_entry *bte;
109         methodinfo         *m;
110         int32_t             dumpmarker;
111
112         /* mark start of dump memory area */
113
114         DMARKER;
115
116         /* create a new descriptor pool */
117
118         descpool = descriptor_pool_new(class_java_lang_Object);
119
120         /* add some entries we need */
121
122         if (!descriptor_pool_add_class(descpool, utf_java_lang_Object))
123                 return false;
124
125         if (!descriptor_pool_add_class(descpool, utf_java_lang_Class))
126                 return false;
127
128         /* first add all descriptors to the pool */
129
130         for (bte = builtintable_internal; bte->fp != NULL; bte++) {
131                 bte->name       = utf_new_char(bte->cname);
132                 bte->descriptor = utf_new_char(bte->cdescriptor);
133
134                 if (!descriptor_pool_add(descpool, bte->descriptor, NULL)) {
135                         /* release dump area */
136
137                         DRELEASE;
138
139                         return false;
140                 }
141         }
142
143         for (bte = builtintable_automatic; bte->fp != NULL; bte++) {
144                 bte->descriptor = utf_new_char(bte->cdescriptor);
145
146                 if (!descriptor_pool_add(descpool, bte->descriptor, NULL)) {
147                         DRELEASE;
148                         return false;
149                 }
150         }
151
152         for (bte = builtintable_function; bte->fp != NULL; bte++) {
153                 bte->classname  = utf_new_char(bte->cclassname);
154                 bte->name       = utf_new_char(bte->cname);
155                 bte->descriptor = utf_new_char(bte->cdescriptor);
156
157                 if (!descriptor_pool_add(descpool, bte->descriptor, NULL)) {
158                         DRELEASE;
159                         return false;
160                 }
161         }
162
163         /* create the class reference table */
164
165         (void) descriptor_pool_create_classrefs(descpool, NULL);
166
167         /* allocate space for the parsed descriptors */
168
169         descriptor_pool_alloc_parsed_descriptors(descpool);
170
171         /* Now parse all descriptors.  NOTE: builtin-functions are treated
172            like static methods (no `this' pointer). */
173
174         for (bte = builtintable_internal; bte->fp != NULL; bte++) {
175                 bte->md =
176                         descriptor_pool_parse_method_descriptor(descpool,
177                                                                                                         bte->descriptor,
178                                                                                                         ACC_STATIC | ACC_METHOD_BUILTIN,
179                                                                                                         NULL);
180
181                 /* generate a builtin stub if we need one */
182
183                 if (bte->flags & BUILTINTABLE_FLAG_STUB) {
184                         m = method_new_builtin(bte);
185                         codegen_generate_stub_builtin(m, bte);
186                 }
187         }
188
189         for (bte = builtintable_automatic; bte->fp != NULL; bte++) {
190                 bte->md =
191                         descriptor_pool_parse_method_descriptor(descpool,
192                                                                                                         bte->descriptor,
193                                                                                                         ACC_STATIC | ACC_METHOD_BUILTIN,
194                                                                                                         NULL);
195
196                 /* no stubs should be needed for this table */
197
198                 assert(!bte->flags & BUILTINTABLE_FLAG_STUB);
199         }
200
201         for (bte = builtintable_function; bte->fp != NULL; bte++) {
202                 bte->md =
203                         descriptor_pool_parse_method_descriptor(descpool,
204                                                                                                         bte->descriptor,
205                                                                                                         ACC_STATIC | ACC_METHOD_BUILTIN,
206                                                                                                         NULL);
207
208                 /* generate a builtin stub if we need one */
209
210                 if (bte->flags & BUILTINTABLE_FLAG_STUB) {
211                         m = method_new_builtin(bte);
212                         codegen_generate_stub_builtin(m, bte);
213                 }
214         }
215
216         /* release dump area */
217
218         DRELEASE;
219
220         return true;
221 }
222
223
224 /* builtintable_comparator *****************************************************
225
226    qsort comparator for the automatic builtin table.
227
228 *******************************************************************************/
229
230 static int builtintable_comparator(const void *a, const void *b)
231 {
232         builtintable_entry *bte1;
233         builtintable_entry *bte2;
234
235         bte1 = (builtintable_entry *) a;
236         bte2 = (builtintable_entry *) b;
237
238         return (bte1->opcode < bte2->opcode) ? -1 : (bte1->opcode > bte2->opcode);
239 }
240
241
242 /* builtintable_sort_automatic *************************************************
243
244    Sorts the automatic builtin table.
245
246 *******************************************************************************/
247
248 static void builtintable_sort_automatic(void)
249 {
250         s4 entries;
251
252         /* calculate table size statically (`- 1' comment see builtintable.inc) */
253
254         entries = sizeof(builtintable_automatic) / sizeof(builtintable_entry) - 1;
255
256         qsort(builtintable_automatic, entries, sizeof(builtintable_entry),
257                   builtintable_comparator);
258 }
259
260
261 /* builtin_init ****************************************************************
262
263    Initialize the global table of builtin functions.
264
265 *******************************************************************************/
266
267 bool builtin_init(void)
268 {
269         TRACESUBSYSTEMINITIALIZATION("builtin_init");
270
271         /* initialize the builtin tables */
272
273         if (!builtintable_init())
274                 return false;
275
276         /* sort builtin tables */
277
278         builtintable_sort_automatic();
279
280         return true;
281 }
282
283
284 /* builtintable_get_internal ***************************************************
285
286    Finds an entry in the builtintable for internal functions and
287    returns the a pointer to the structure.
288
289 *******************************************************************************/
290
291 builtintable_entry *builtintable_get_internal(functionptr fp)
292 {
293         builtintable_entry *bte;
294
295         for (bte = builtintable_internal; bte->fp != NULL; bte++) {
296                 if (bte->fp == fp)
297                         return bte;
298         }
299
300         return NULL;
301 }
302
303
304 /* builtintable_get_automatic **************************************************
305
306    Finds an entry in the builtintable for functions which are replaced
307    automatically and returns the a pointer to the structure.
308
309 *******************************************************************************/
310
311 builtintable_entry *builtintable_get_automatic(s4 opcode)
312 {
313         builtintable_entry *first;
314         builtintable_entry *last;
315         builtintable_entry *middle;
316         s4                  half;
317         s4                  entries;
318
319         /* calculate table size statically (`- 1' comment see builtintable.inc) */
320
321         entries = sizeof(builtintable_automatic) / sizeof(builtintable_entry) - 1;
322
323         first = builtintable_automatic;
324         last = builtintable_automatic + entries;
325
326         while (entries > 0) {
327                 half = entries / 2;
328                 middle = first + half;
329
330                 if (middle->opcode < opcode) {
331                         first = middle + 1;
332                         entries -= half + 1;
333                 }
334                 else
335                         entries = half;
336         }
337
338         return (first != last ? first : NULL);
339 }
340
341
342 /* builtintable_replace_function ***********************************************
343
344    XXX
345
346 *******************************************************************************/
347
348 #if defined(ENABLE_JIT)
349 bool builtintable_replace_function(void *iptr_)
350 {
351         constant_FMIref    *mr;
352         builtintable_entry *bte;
353         instruction        *iptr;
354
355         iptr = (instruction *) iptr_; /* twisti will kill me ;) */
356
357         /* get name and descriptor of the function */
358
359         switch (iptr->opc) {
360         case ICMD_INVOKESTATIC:
361                 /* The instruction MUST be resolved, otherwise we run into
362                    lazy loading troubles.  Anyway, we should/can only replace
363                    very VM-close functions. */
364
365                 if (INSTRUCTION_IS_UNRESOLVED(iptr))
366                         return false;
367
368                 mr = iptr->sx.s23.s3.fmiref;
369                 break;  
370
371         default:
372                 return false;
373         }
374
375         /* search the function table */
376
377         for (bte = builtintable_function; bte->fp != NULL; bte++) {
378                 if ((METHODREF_CLASSNAME(mr) == bte->classname) &&
379                         (mr->name                == bte->name) &&
380                         (mr->descriptor          == bte->descriptor)) {
381
382                         /* set the values in the instruction */
383
384                         iptr->opc           = bte->opcode;
385                         iptr->sx.s23.s3.bte = bte;
386
387                         if (bte->flags & BUILTINTABLE_FLAG_EXCEPTION)
388                                 iptr->flags.bits |= INS_FLAG_CHECK;
389                         else
390                                 iptr->flags.bits &= ~INS_FLAG_CHECK;
391
392                         return true;
393                 }
394         }
395
396         return false;
397 }
398 #endif /* defined(ENABLE_JIT) */
399
400
401 /*============================================================================*/
402 /* INTERNAL BUILTIN FUNCTIONS                                                 */
403 /*============================================================================*/
404
405 /* builtin_instanceof **********************************************************
406
407    Checks if an object is an instance of some given class (or subclass
408    of that class). If class is an interface, checks if the interface
409    is implemented.
410
411    RETURN VALUE:
412      1......o is an instance of class or implements the interface
413      0......otherwise or if o == NULL
414
415    NOTE: This builtin can be called from NATIVE code only.
416
417 *******************************************************************************/
418
419 bool builtin_instanceof(java_handle_t *o, classinfo *class)
420 {
421         classinfo *c;
422
423         if (o == NULL)
424                 return 0;
425
426         LLNI_class_get(o, c);
427
428         return class_isanysubclass(c, class);
429 }
430
431
432
433 /* builtin_checkcast ***********************************************************
434
435    The same as builtin_instanceof but with the exception
436    that 1 is returned when (o == NULL).
437
438    NOTE: This builtin can be called from NATIVE code only.
439
440 *******************************************************************************/
441
442 bool builtin_checkcast(java_handle_t *o, classinfo *class)
443 {
444         classinfo *c;
445
446         if (o == NULL)
447                 return 1;
448
449         LLNI_class_get(o, c);
450
451         if (class_isanysubclass(c, class))
452                 return 1;
453
454         return 0;
455 }
456
457
458 /* builtin_descriptorscompatible ***********************************************
459
460    Checks if two array type descriptors are assignment compatible.
461
462    RETURN VALUE:
463       1......target = desc is possible
464       0......otherwise
465                         
466 *******************************************************************************/
467
468 static bool builtin_descriptorscompatible(arraydescriptor *desc, arraydescriptor *target)
469 {
470         if (desc == target)
471                 return 1;
472
473         if (desc->arraytype != target->arraytype)
474                 return 0;
475
476         if (desc->arraytype != ARRAYTYPE_OBJECT)
477                 return 1;
478         
479         /* {both arrays are arrays of references} */
480
481         if (desc->dimension == target->dimension) {
482                 if (!desc->elementvftbl)
483                         return 0;
484                 /* an array which contains elements of interface types is
485            allowed to be casted to Object (JOWENN)*/
486
487                 if ((desc->elementvftbl->baseval < 0) &&
488                         (target->elementvftbl->baseval == 1))
489                         return 1;
490
491                 return class_isanysubclass(desc->elementvftbl->clazz,
492                                                                    target->elementvftbl->clazz);
493         }
494
495         if (desc->dimension < target->dimension)
496                 return 0;
497
498         /* {desc has higher dimension than target} */
499
500         return class_isanysubclass(pseudo_class_Arraystub,
501                                                            target->elementvftbl->clazz);
502 }
503
504
505 /* builtin_arraycheckcast ******************************************************
506
507    Checks if an object is really a subtype of the requested array
508    type.  The object has to be an array to begin with. For simple
509    arrays (int, short, double, etc.) the types have to match exactly.
510    For arrays of objects, the type of elements in the array has to be
511    a subtype (or the same type) of the requested element type. For
512    arrays of arrays (which in turn can again be arrays of arrays), the
513    types at the lowest level have to satisfy the corresponding sub
514    class relation.
515
516    NOTE: This is a FAST builtin and can be called from JIT code only.
517
518 *******************************************************************************/
519
520 bool builtin_fast_arraycheckcast(java_object_t *o, classinfo *targetclass)
521 {
522         arraydescriptor *desc;
523
524         if (o == NULL)
525                 return 1;
526
527         desc = o->vftbl->arraydesc;
528
529         if (desc == NULL)
530                 return 0;
531  
532         return builtin_descriptorscompatible(desc, targetclass->vftbl->arraydesc);
533 }
534
535
536 /* builtin_fast_arrayinstanceof ************************************************
537
538    NOTE: This is a FAST builtin and can be called from JIT code only.
539
540 *******************************************************************************/
541
542 bool builtin_fast_arrayinstanceof(java_object_t *o, classinfo *targetclass)
543 {
544         if (o == NULL)
545                 return 0;
546
547         return builtin_fast_arraycheckcast(o, targetclass);
548 }
549
550
551 /* builtin_arrayinstanceof *****************************************************
552
553    NOTE: This builtin can be called from NATIVE code only.
554
555 *******************************************************************************/
556
557 bool builtin_arrayinstanceof(java_handle_t *h, classinfo *targetclass)
558 {
559         bool result;
560
561         LLNI_CRITICAL_START;
562
563         result = builtin_fast_arrayinstanceof(LLNI_UNWRAP(h), targetclass);
564
565         LLNI_CRITICAL_END;
566
567         return result;
568 }
569
570
571 /* builtin_throw_exception *****************************************************
572
573    Sets the exception pointer with the thrown exception and prints some
574    debugging information.
575    
576    NOTE: This is a FAST builtin and can be called from JIT code,
577    or from asm_vm_call_method.
578
579 *******************************************************************************/
580
581 void *builtin_throw_exception(java_object_t *xptr)
582 {
583 #if !defined(NDEBUG)
584         /* print exception trace */
585
586         if (opt_TraceExceptions)
587                 trace_exception_builtin(xptr);
588 #endif /* !defined(NDEBUG) */
589
590         /* actually set the exception */
591
592         exceptions_set_exception(LLNI_QUICKWRAP(xptr));
593
594         /* Return a NULL pointer.  This is required for vm_call_method to
595            check for an exception.  This is for convenience. */
596
597         return NULL;
598 }
599
600
601 /* builtin_retrieve_exception **************************************************
602
603    Gets and clears the exception pointer of the current thread.
604
605    RETURN VALUE:
606       the exception object, or NULL if no exception was thrown.
607
608    NOTE: This is a FAST builtin and can be called from JIT code,
609    or from the signal handlers.
610
611 *******************************************************************************/
612
613 java_object_t *builtin_retrieve_exception(void)
614 {
615         java_handle_t *h;
616         java_object_t *o;
617
618         /* actually get and clear the exception */
619
620         h = exceptions_get_and_clear_exception();
621         o = LLNI_UNWRAP(h);
622
623         return o;
624 }
625
626
627 /* builtin_canstore ************************************************************
628
629    Checks, if an object can be stored in an array.
630
631    RETURN VALUE:
632       1......possible
633       0......otherwise (throws an ArrayStoreException)
634
635    NOTE: This is a SLOW builtin and can be called from JIT & NATIVE code.
636
637 *******************************************************************************/
638
639 bool builtin_canstore(java_handle_objectarray_t *oa, java_handle_t *o)
640 {
641         bool result;
642
643         LLNI_CRITICAL_START;
644
645         result = builtin_fast_canstore(LLNI_DIRECT(oa), LLNI_UNWRAP(o));
646
647         LLNI_CRITICAL_END;
648
649         /* if not possible, throw an exception */
650
651         if (result == 0)
652                 exceptions_throw_arraystoreexception();
653
654         return result;
655 }
656
657
658 /* builtin_fast_canstore *******************************************************
659
660    Checks, if an object can be stored in an array.
661
662    RETURN VALUE:
663       1......possible
664       0......otherwise (no exception thrown!)
665
666    NOTE: This is a FAST builtin and can be called from JIT code only.
667
668 *******************************************************************************/
669
670 bool fast_subtype_check(struct _vftbl *s, struct _vftbl *t)
671 {
672         if (s->subtype_display[t->subtype_depth] == t)
673                 return true;
674         if (t->subtype_offset != OFFSET(vftbl_t, subtype_display[DISPLAY_SIZE]))
675                 return false;
676         return s->subtype_overflow_length > (t->subtype_depth - DISPLAY_SIZE) && s->subtype_overflow[t->subtype_depth - DISPLAY_SIZE] == t;
677 }
678
679 bool builtin_fast_canstore(java_objectarray_t *oa, java_object_t *o)
680 {
681         arraydescriptor *desc;
682         arraydescriptor *valuedesc;
683         vftbl_t         *componentvftbl;
684         vftbl_t         *valuevftbl;
685         int32_t          baseval;
686         uint32_t         diffval;
687         bool             result;
688
689         if (o == NULL)
690                 return 1;
691
692         /* The following is guaranteed (by verifier checks):
693          *
694          *     *) oa->...vftbl->arraydesc != NULL
695          *     *) oa->...vftbl->arraydesc->componentvftbl != NULL
696          *     *) o->vftbl is not an interface vftbl
697          */
698
699         desc           = oa->header.objheader.vftbl->arraydesc;
700         componentvftbl = desc->componentvftbl;
701         valuevftbl     = o->vftbl;
702         valuedesc      = valuevftbl->arraydesc;
703
704         if ((desc->dimension - 1) == 0) {
705                 /* {oa is a one-dimensional array} */
706                 /* {oa is an array of references} */
707                 
708                 if (valuevftbl == componentvftbl)
709                         return 1;
710
711                 baseval = componentvftbl->baseval;
712
713                 if (baseval <= 0) {
714                         /* an array of interface references */
715
716                         result = ((valuevftbl->interfacetablelength > -baseval) &&
717                                           (valuevftbl->interfacetable[baseval] != NULL));
718                 }
719                 else {
720                         result = fast_subtype_check(valuevftbl, componentvftbl);
721                 }
722         }
723         else if (valuedesc == NULL) {
724                 /* {oa has dimension > 1} */
725                 /* {componentvftbl->arraydesc != NULL} */
726
727                 /* check if o is an array */
728
729                 return 0;
730         }
731         else {
732                 /* {o is an array} */
733
734                 result = builtin_descriptorscompatible(valuedesc, componentvftbl->arraydesc);
735         }
736
737         /* return result */
738
739         return result;
740 }
741
742
743 /* This is an optimized version where a is guaranteed to be one-dimensional */
744 bool builtin_fast_canstore_onedim(java_objectarray_t *a, java_object_t *o)
745 {
746         arraydescriptor *desc;
747         vftbl_t         *elementvftbl;
748         vftbl_t         *valuevftbl;
749         int32_t          baseval;
750         uint32_t         diffval;
751         bool             result;
752         
753         if (o == NULL)
754                 return 1;
755
756         /* The following is guaranteed (by verifier checks):
757          *
758          *     *) a->...vftbl->arraydesc != NULL
759          *     *) a->...vftbl->arraydesc->elementvftbl != NULL
760          *     *) a->...vftbl->arraydesc->dimension == 1
761          *     *) o->vftbl is not an interface vftbl
762          */
763
764         desc = a->header.objheader.vftbl->arraydesc;
765     elementvftbl = desc->elementvftbl;
766         valuevftbl = o->vftbl;
767
768         /* {a is a one-dimensional array} */
769         
770         if (valuevftbl == elementvftbl)
771                 return 1;
772
773         baseval = elementvftbl->baseval;
774
775         if (baseval <= 0) {
776                 /* an array of interface references */
777                 result = ((valuevftbl->interfacetablelength > -baseval) &&
778                                   (valuevftbl->interfacetable[baseval] != NULL));
779         }
780         else {
781                 result = fast_subtype_check(valuevftbl, elementvftbl);
782         }
783
784         return result;
785 }
786
787
788 /* This is an optimized version where a is guaranteed to be a
789  * one-dimensional array of a class type */
790 bool builtin_fast_canstore_onedim_class(java_objectarray_t *a, java_object_t *o)
791 {
792         vftbl_t  *elementvftbl;
793         vftbl_t  *valuevftbl;
794         uint32_t  diffval;
795         bool      result;
796         
797         if (o == NULL)
798                 return 1;
799
800         /* The following is guaranteed (by verifier checks):
801          *
802          *     *) a->...vftbl->arraydesc != NULL
803          *     *) a->...vftbl->arraydesc->elementvftbl != NULL
804          *     *) a->...vftbl->arraydesc->elementvftbl is not an interface vftbl
805          *     *) a->...vftbl->arraydesc->dimension == 1
806          *     *) o->vftbl is not an interface vftbl
807          */
808
809     elementvftbl = a->header.objheader.vftbl->arraydesc->elementvftbl;
810         valuevftbl = o->vftbl;
811
812         /* {a is a one-dimensional array} */
813         
814         if (valuevftbl == elementvftbl)
815                 return 1;
816
817         result = fast_subtype_check(valuevftbl, elementvftbl);
818
819         return result;
820 }
821
822
823 /* builtin_new *****************************************************************
824
825    Creates a new instance of class c on the heap.
826
827    RETURN VALUE:
828       pointer to the object, or NULL if no memory is available
829
830    NOTE: This builtin can be called from NATIVE code only.
831
832 *******************************************************************************/
833
834 java_handle_t *builtin_new(classinfo *c)
835 {
836         java_handle_t *o;
837 #if defined(ENABLE_RT_TIMING)
838         struct timespec time_start, time_end;
839 #endif
840 #if defined(ENABLE_CYCLES_STATS)
841         u8 cycles_start, cycles_end;
842 #endif
843
844         RT_TIMING_GET_TIME(time_start);
845         CYCLES_STATS_GET(cycles_start);
846
847         /* is the class loaded */
848
849         assert(c->state & CLASS_LOADED);
850
851         /* check if we can instantiate this class */
852
853         if (c->flags & ACC_ABSTRACT) {
854                 exceptions_throw_instantiationerror(c);
855                 return NULL;
856         }
857
858         /* is the class linked */
859
860         if (!(c->state & CLASS_LINKED))
861                 if (!link_class(c))
862                         return NULL;
863
864         if (!(c->state & CLASS_INITIALIZED)) {
865 #if !defined(NDEBUG)
866                 if (initverbose)
867                         log_message_class("Initialize class (from builtin_new): ", c);
868 #endif
869
870                 if (!initialize_class(c))
871                         return NULL;
872         }
873
874         o = heap_alloc(c->instancesize, c->flags & ACC_CLASS_HAS_POINTERS,
875                                    c->finalizer, true);
876
877         if (!o)
878                 return NULL;
879
880 #if !defined(ENABLE_GC_CACAO) && defined(ENABLE_HANDLES)
881         /* XXX this is only a dirty hack to make Boehm work with handles */
882
883         o = LLNI_WRAP((java_object_t *) o);
884 #endif
885
886         LLNI_vftbl_direct(o) = c->vftbl;
887
888 #if defined(ENABLE_THREADS)
889         lock_init_object_lock(LLNI_DIRECT(o));
890 #endif
891
892         CYCLES_STATS_GET(cycles_end);
893         RT_TIMING_GET_TIME(time_end);
894
895         CYCLES_STATS_COUNT(builtin_new,cycles_end - cycles_start);
896         RT_TIMING_TIME_DIFF(time_start, time_end, RT_TIMING_NEW_OBJECT);
897
898         return o;
899 }
900
901
902 /* builtin_java_new ************************************************************
903
904    NOTE: This is a SLOW builtin and can be called from JIT code only.
905
906 *******************************************************************************/
907
908 java_handle_t *builtin_java_new(java_handle_t *clazz)
909 {
910         return builtin_new(LLNI_classinfo_unwrap(clazz));
911 }
912
913
914 /* builtin_fast_new ************************************************************
915
916    Creates a new instance of class c on the heap.
917
918    RETURN VALUE:
919       pointer to the object, or NULL if no fast return
920       is possible for any reason.
921
922    NOTE: This is a FAST builtin and can be called from JIT code only.
923
924 *******************************************************************************/
925
926 java_object_t *builtin_fast_new(classinfo *c)
927 {
928         java_object_t *o;
929 #if defined(ENABLE_RT_TIMING)
930         struct timespec time_start, time_end;
931 #endif
932 #if defined(ENABLE_CYCLES_STATS)
933         u8 cycles_start, cycles_end;
934 #endif
935
936         RT_TIMING_GET_TIME(time_start);
937         CYCLES_STATS_GET(cycles_start);
938
939         /* is the class loaded */
940
941         assert(c->state & CLASS_LOADED);
942
943         /* check if we can instantiate this class */
944
945         if (c->flags & ACC_ABSTRACT)
946                 return NULL;
947
948         /* is the class linked */
949
950         if (!(c->state & CLASS_LINKED))
951                 return NULL;
952
953         if (!(c->state & CLASS_INITIALIZED))
954                 return NULL;
955
956         o = heap_alloc(c->instancesize, c->flags & ACC_CLASS_HAS_POINTERS,
957                                    c->finalizer, false);
958
959         if (!o)
960                 return NULL;
961
962         o->vftbl = c->vftbl;
963
964 #if defined(ENABLE_THREADS)
965         lock_init_object_lock(o);
966 #endif
967
968         CYCLES_STATS_GET(cycles_end);
969         RT_TIMING_GET_TIME(time_end);
970
971         CYCLES_STATS_COUNT(builtin_new,cycles_end - cycles_start);
972         RT_TIMING_TIME_DIFF(time_start, time_end, RT_TIMING_NEW_OBJECT);
973
974         return o;
975 }
976
977
978 /* builtin_newarray ************************************************************
979
980    Creates an array with the given vftbl on the heap. This function
981    takes as class argument an array class.
982
983    RETURN VALUE:
984       pointer to the array or NULL if no memory is available
985
986    NOTE: This builtin can be called from NATIVE code only.
987
988 *******************************************************************************/
989
990 java_handle_t *builtin_newarray(int32_t size, classinfo *arrayclass)
991 {
992         arraydescriptor *desc;
993         s4               dataoffset;
994         s4               componentsize;
995         s4               actualsize;
996         java_handle_t   *a;
997 #if defined(ENABLE_RT_TIMING)
998         struct timespec time_start, time_end;
999 #endif
1000
1001         RT_TIMING_GET_TIME(time_start);
1002
1003         desc          = arrayclass->vftbl->arraydesc;
1004         dataoffset    = desc->dataoffset;
1005         componentsize = desc->componentsize;
1006
1007         if (size < 0) {
1008                 exceptions_throw_negativearraysizeexception();
1009                 return NULL;
1010         }
1011
1012         actualsize = dataoffset + size * componentsize;
1013
1014         /* check for overflow */
1015
1016         if (((u4) actualsize) < ((u4) size)) {
1017                 exceptions_throw_outofmemoryerror();
1018                 return NULL;
1019         }
1020
1021         a = heap_alloc(actualsize, (desc->arraytype == ARRAYTYPE_OBJECT), NULL, true);
1022
1023         if (a == NULL)
1024                 return NULL;
1025
1026 #if !defined(ENABLE_GC_CACAO) && defined(ENABLE_HANDLES)
1027         /* XXX this is only a dirty hack to make Boehm work with handles */
1028
1029         a = LLNI_WRAP((java_object_t *) a);
1030 #endif
1031
1032         LLNI_vftbl_direct(a) = arrayclass->vftbl;
1033
1034 #if defined(ENABLE_THREADS)
1035         lock_init_object_lock(LLNI_DIRECT(a));
1036 #endif
1037
1038         LLNI_array_size(a) = size;
1039
1040         RT_TIMING_GET_TIME(time_end);
1041         RT_TIMING_TIME_DIFF(time_start, time_end, RT_TIMING_NEW_ARRAY);
1042
1043         return a;
1044 }
1045
1046
1047 /* builtin_java_newarray *******************************************************
1048
1049    NOTE: This is a SLOW builtin and can be called from JIT code only.
1050
1051 *******************************************************************************/
1052
1053 java_handle_t *builtin_java_newarray(int32_t size, java_handle_t *arrayclazz)
1054 {
1055         return builtin_newarray(size, LLNI_classinfo_unwrap(arrayclazz));
1056 }
1057
1058
1059 /* builtin_anewarray ***********************************************************
1060
1061    Creates an array of references to the given class type on the heap.
1062
1063    RETURN VALUE:
1064       pointer to the array or NULL if no memory is
1065       available
1066
1067    NOTE: This builtin can be called from NATIVE code only.
1068
1069 *******************************************************************************/
1070
1071 java_handle_objectarray_t *builtin_anewarray(int32_t size, classinfo *componentclass)
1072 {
1073         classinfo *arrayclass;
1074         
1075         /* is class loaded */
1076
1077         assert(componentclass->state & CLASS_LOADED);
1078
1079         /* is class linked */
1080
1081         if (!(componentclass->state & CLASS_LINKED))
1082                 if (!link_class(componentclass))
1083                         return NULL;
1084
1085         arrayclass = class_array_of(componentclass, true);
1086
1087         if (!arrayclass)
1088                 return NULL;
1089
1090         return (java_handle_objectarray_t *) builtin_newarray(size, arrayclass);
1091 }
1092
1093
1094 /* builtin_newarray_type ****************************************************
1095
1096    Creates an array of [type]s on the heap.
1097         
1098    RETURN VALUE:
1099       pointer to the array or NULL if no memory is available
1100
1101    NOTE: This is a SLOW builtin and can be called from JIT & NATIVE code.
1102
1103 *******************************************************************************/
1104
1105 #define BUILTIN_NEWARRAY_TYPE(type, arraytype)                             \
1106 java_handle_##type##array_t *builtin_newarray_##type(int32_t size)              \
1107 {                                                                          \
1108         return (java_handle_##type##array_t *)                                 \
1109                 builtin_newarray(size, primitivetype_table[arraytype].arrayclass); \
1110 }
1111
1112 BUILTIN_NEWARRAY_TYPE(boolean, ARRAYTYPE_BOOLEAN)
1113 BUILTIN_NEWARRAY_TYPE(byte,    ARRAYTYPE_BYTE)
1114 BUILTIN_NEWARRAY_TYPE(char,    ARRAYTYPE_CHAR)
1115 BUILTIN_NEWARRAY_TYPE(short,   ARRAYTYPE_SHORT)
1116 BUILTIN_NEWARRAY_TYPE(int,     ARRAYTYPE_INT)
1117 BUILTIN_NEWARRAY_TYPE(long,    ARRAYTYPE_LONG)
1118 BUILTIN_NEWARRAY_TYPE(float,   ARRAYTYPE_FLOAT)
1119 BUILTIN_NEWARRAY_TYPE(double,  ARRAYTYPE_DOUBLE)
1120
1121
1122 /* builtin_multianewarray_intern ***********************************************
1123
1124    Creates a multi-dimensional array on the heap. The dimensions are
1125    passed in an array of longs.
1126
1127    ARGUMENTS:
1128       n.............number of dimensions to create
1129       arrayclass....the array class
1130       dims..........array containing the size of each dimension to create
1131
1132    RETURN VALUE:
1133       pointer to the array or NULL if no memory is available
1134
1135 ******************************************************************************/
1136
1137 static java_handle_t *builtin_multianewarray_intern(int n,
1138                                                                                                         classinfo *arrayclass,
1139                                                                                                         long *dims)
1140 {
1141         s4             size;
1142         java_handle_t *a;
1143         classinfo     *componentclass;
1144         s4             i;
1145
1146         /* create this dimension */
1147
1148         size = (s4) dims[0];
1149         a = builtin_newarray(size, arrayclass);
1150
1151         if (!a)
1152                 return NULL;
1153
1154         /* if this is the last dimension return */
1155
1156         if (!--n)
1157                 return a;
1158
1159         /* get the class of the components to create */
1160
1161         componentclass = arrayclass->vftbl->arraydesc->componentvftbl->clazz;
1162
1163         /* The verifier guarantees that the dimension count is in the range. */
1164
1165         /* create the component arrays */
1166
1167         for (i = 0; i < size; i++) {
1168                 java_handle_t *ea =
1169 #if defined(__MIPS__) && (SIZEOF_VOID_P == 4)
1170                         /* we save an s4 to a s8 slot, 8-byte aligned */
1171
1172                         builtin_multianewarray_intern(n, componentclass, dims + 2);
1173 #else
1174                         builtin_multianewarray_intern(n, componentclass, dims + 1);
1175 #endif
1176
1177                 if (!ea)
1178                         return NULL;
1179
1180                 array_objectarray_element_set((java_handle_objectarray_t *) a, i, ea);
1181         }
1182
1183         return a;
1184 }
1185
1186
1187 /* builtin_multianewarray ******************************************************
1188
1189    Wrapper for builtin_multianewarray_intern which checks all
1190    dimensions before we start allocating.
1191
1192    NOTE: This is a SLOW builtin and can be called from JIT code only.
1193
1194 ******************************************************************************/
1195
1196 java_handle_objectarray_t *builtin_multianewarray(int n,
1197                                                                                                   java_handle_t *arrayclazz,
1198                                                                                                   long *dims)
1199 {
1200         classinfo *c;
1201         s4         i;
1202         s4         size;
1203
1204         /* check all dimensions before doing anything */
1205
1206         for (i = 0; i < n; i++) {
1207 #if defined(__MIPS__) && (SIZEOF_VOID_P == 4)
1208                 /* we save an s4 to a s8 slot, 8-byte aligned */
1209                 size = (s4) dims[i * 2];
1210 #else
1211                 size = (s4) dims[i];
1212 #endif
1213
1214                 if (size < 0) {
1215                         exceptions_throw_negativearraysizeexception();
1216                         return NULL;
1217                 }
1218         }
1219
1220         c = LLNI_classinfo_unwrap(arrayclazz);
1221
1222         /* now call the real function */
1223
1224         return (java_handle_objectarray_t *)
1225                 builtin_multianewarray_intern(n, c, dims);
1226 }
1227
1228
1229 /* builtin_verbosecall_enter ***************************************************
1230
1231    Print method call with arguments for -verbose:call.
1232
1233    XXX: Remove mew once all archs use the new tracer!
1234
1235 *******************************************************************************/
1236
1237 #if !defined(NDEBUG)
1238 #ifdef TRACE_ARGS_NUM
1239 void builtin_verbosecall_enter(s8 a0, s8 a1,
1240 # if TRACE_ARGS_NUM >= 4
1241                                                            s8 a2, s8 a3,
1242 # endif
1243 # if TRACE_ARGS_NUM >= 6
1244                                                            s8 a4, s8 a5,
1245 # endif
1246 # if TRACE_ARGS_NUM == 8
1247                                                            s8 a6, s8 a7,
1248 # endif
1249                                                            methodinfo *m)
1250 {
1251         log_text("builtin_verbosecall_enter: Do not call me anymore!");
1252 }
1253 #endif
1254 #endif /* !defined(NDEBUG) */
1255
1256
1257 /* builtin_verbosecall_exit ****************************************************
1258
1259    Print method exit for -verbose:call.
1260
1261    XXX: Remove mew once all archs use the new tracer!
1262
1263 *******************************************************************************/
1264
1265 #if !defined(NDEBUG)
1266 void builtin_verbosecall_exit(s8 l, double d, float f, methodinfo *m)
1267 {
1268         log_text("builtin_verbosecall_exit: Do not call me anymore!");
1269 }
1270 #endif /* !defined(NDEBUG) */
1271
1272
1273 /*============================================================================*/
1274 /* MISCELLANEOUS MATHEMATICAL HELPER FUNCTIONS                                */
1275 /*============================================================================*/
1276
1277 /*********** Functions for integer divisions *****************************
1278  
1279         On some systems (eg. DEC ALPHA), integer division is not supported by the
1280         CPU. These helper functions implement the missing functionality.
1281
1282 ******************************************************************************/
1283
1284 #if !SUPPORT_DIVISION || defined(DISABLE_GC)
1285 s4 builtin_idiv(s4 a, s4 b)
1286 {
1287         s4 c;
1288
1289         c = a / b;
1290
1291         return c;
1292 }
1293
1294 s4 builtin_irem(s4 a, s4 b)
1295 {
1296         s4 c;
1297
1298         c = a % b;
1299
1300         return c;
1301 }
1302 #endif /* !SUPPORT_DIVISION || defined(DISABLE_GC) */
1303
1304
1305 /* functions for long arithmetics **********************************************
1306
1307    On systems where 64 bit Integers are not supported by the CPU,
1308    these functions are needed.
1309
1310 ******************************************************************************/
1311
1312 #if !(SUPPORT_LONG && SUPPORT_LONG_ADD)
1313 s8 builtin_ladd(s8 a, s8 b)
1314 {
1315         s8 c;
1316
1317 #if U8_AVAILABLE
1318         c = a + b; 
1319 #else
1320         c = builtin_i2l(0);
1321 #endif
1322
1323         return c;
1324 }
1325
1326 s8 builtin_lsub(s8 a, s8 b)
1327 {
1328         s8 c;
1329
1330 #if U8_AVAILABLE
1331         c = a - b; 
1332 #else
1333         c = builtin_i2l(0);
1334 #endif
1335
1336         return c;
1337 }
1338
1339 s8 builtin_lneg(s8 a)
1340 {
1341         s8 c;
1342
1343 #if U8_AVAILABLE
1344         c = -a;
1345 #else
1346         c = builtin_i2l(0);
1347 #endif
1348
1349         return c;
1350 }
1351 #endif /* !(SUPPORT_LONG && SUPPORT_LONG_ADD) */
1352
1353
1354 #if !(SUPPORT_LONG && SUPPORT_LONG_MUL)
1355 s8 builtin_lmul(s8 a, s8 b)
1356 {
1357         s8 c;
1358
1359 #if U8_AVAILABLE
1360         c = a * b; 
1361 #else
1362         c = builtin_i2l(0);
1363 #endif
1364
1365         return c;
1366 }
1367 #endif /* !(SUPPORT_LONG && SUPPORT_LONG_MUL) */
1368
1369
1370 #if !(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_DIV) || defined (DISABLE_GC)
1371 s8 builtin_ldiv(s8 a, s8 b)
1372 {
1373         s8 c;
1374
1375 #if U8_AVAILABLE
1376         c = a / b; 
1377 #else
1378         c = builtin_i2l(0);
1379 #endif
1380
1381         return c;
1382 }
1383
1384 s8 builtin_lrem(s8 a, s8 b)
1385 {
1386         s8 c;
1387
1388 #if U8_AVAILABLE
1389         c = a % b; 
1390 #else
1391         c = builtin_i2l(0);
1392 #endif
1393
1394         return c;
1395 }
1396 #endif /* !(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_DIV) */
1397
1398
1399 #if !(SUPPORT_LONG && SUPPORT_LONG_SHIFT)
1400 s8 builtin_lshl(s8 a, s4 b)
1401 {
1402         s8 c;
1403
1404 #if U8_AVAILABLE
1405         c = a << (b & 63);
1406 #else
1407         c = builtin_i2l(0);
1408 #endif
1409
1410         return c;
1411 }
1412
1413 s8 builtin_lshr(s8 a, s4 b)
1414 {
1415         s8 c;
1416
1417 #if U8_AVAILABLE
1418         c = a >> (b & 63);
1419 #else
1420         c = builtin_i2l(0);
1421 #endif
1422
1423         return c;
1424 }
1425
1426 s8 builtin_lushr(s8 a, s4 b)
1427 {
1428         s8 c;
1429
1430 #if U8_AVAILABLE
1431         c = ((u8) a) >> (b & 63);
1432 #else
1433         c = builtin_i2l(0);
1434 #endif
1435
1436         return c;
1437 }
1438 #endif /* !(SUPPORT_LONG && SUPPORT_LONG_SHIFT) */
1439
1440
1441 #if !(SUPPORT_LONG && SUPPORT_LONG_LOGICAL)
1442 s8 builtin_land(s8 a, s8 b)
1443 {
1444         s8 c;
1445
1446 #if U8_AVAILABLE
1447         c = a & b; 
1448 #else
1449         c = builtin_i2l(0);
1450 #endif
1451
1452         return c;
1453 }
1454
1455 s8 builtin_lor(s8 a, s8 b)
1456 {
1457         s8 c;
1458
1459 #if U8_AVAILABLE
1460         c = a | b; 
1461 #else
1462         c = builtin_i2l(0);
1463 #endif
1464
1465         return c;
1466 }
1467
1468 s8 builtin_lxor(s8 a, s8 b) 
1469 {
1470         s8 c;
1471
1472 #if U8_AVAILABLE
1473         c = a ^ b; 
1474 #else
1475         c = builtin_i2l(0);
1476 #endif
1477
1478         return c;
1479 }
1480 #endif /* !(SUPPORT_LONG && SUPPORT_LONG_LOGICAL) */
1481
1482
1483 #if !(SUPPORT_LONG && SUPPORT_LONG_CMP)
1484 s4 builtin_lcmp(s8 a, s8 b)
1485
1486 #if U8_AVAILABLE
1487         if (a < b)
1488                 return -1;
1489
1490         if (a > b)
1491                 return 1;
1492
1493         return 0;
1494 #else
1495         return 0;
1496 #endif
1497 }
1498 #endif /* !(SUPPORT_LONG && SUPPORT_LONG_CMP) */
1499
1500
1501 /* functions for unsupported floating instructions ****************************/
1502
1503 /* used to convert FLT_xxx defines into float values */
1504
1505 static inline float intBitsToFloat(s4 i)
1506 {
1507         imm_union imb;
1508
1509         imb.i = i;
1510         return imb.f;
1511 }
1512
1513
1514 /* used to convert DBL_xxx defines into double values */
1515
1516 static inline float longBitsToDouble(s8 l)
1517 {
1518         imm_union imb;
1519
1520         imb.l = l;
1521         return imb.d;
1522 }
1523
1524
1525 #if !SUPPORT_FLOAT
1526 float builtin_fadd(float a, float b)
1527 {
1528         if (isnanf(a)) return intBitsToFloat(FLT_NAN);
1529         if (isnanf(b)) return intBitsToFloat(FLT_NAN);
1530         if (finitef(a)) {
1531                 if (finitef(b))
1532                         return a + b;
1533                 else
1534                         return b;
1535         }
1536         else {
1537                 if (finitef(b))
1538                         return a;
1539                 else {
1540                         if (copysignf(1.0, a) == copysignf(1.0, b))
1541                                 return a;
1542                         else
1543                                 return intBitsToFloat(FLT_NAN);
1544                 }
1545         }
1546 }
1547
1548
1549 float builtin_fsub(float a, float b)
1550 {
1551         return builtin_fadd(a, builtin_fneg(b));
1552 }
1553
1554
1555 float builtin_fmul(float a, float b)
1556 {
1557         if (isnanf(a)) return intBitsToFloat(FLT_NAN);
1558         if (isnanf(b)) return intBitsToFloat(FLT_NAN);
1559         if (finitef(a)) {
1560                 if (finitef(b)) return a * b;
1561                 else {
1562                         if (a == 0) return intBitsToFloat(FLT_NAN);
1563                         else return copysignf(b, copysignf(1.0, b)*a);
1564                 }
1565         }
1566         else {
1567                 if (finitef(b)) {
1568                         if (b == 0) return intBitsToFloat(FLT_NAN);
1569                         else return copysignf(a, copysignf(1.0, a)*b);
1570                 }
1571                 else {
1572                         return copysignf(a, copysignf(1.0, a)*copysignf(1.0, b));
1573                 }
1574         }
1575 }
1576
1577
1578 /* builtin_ddiv ****************************************************************
1579
1580    Implementation as described in VM Spec.
1581
1582 *******************************************************************************/
1583
1584 float builtin_fdiv(float a, float b)
1585 {
1586         if (finitef(a)) {
1587                 if (finitef(b)) {
1588                         /* If neither value1' nor value2' is NaN, the sign of the result */
1589                         /* is positive if both values have the same sign, negative if the */
1590                         /* values have different signs. */
1591
1592                         return a / b;
1593
1594                 } else {
1595                         if (isnanf(b)) {
1596                                 /* If either value1' or value2' is NaN, the result is NaN. */
1597
1598                                 return intBitsToFloat(FLT_NAN);
1599
1600                         } else {
1601                                 /* Division of a finite value by an infinity results in a */
1602                                 /* signed zero, with the sign-producing rule just given. */
1603
1604                                 /* is sign equal? */
1605
1606                                 if (copysignf(1.0, a) == copysignf(1.0, b))
1607                                         return 0.0;
1608                                 else
1609                                         return -0.0;
1610                         }
1611                 }
1612
1613         } else {
1614                 if (isnanf(a)) {
1615                         /* If either value1' or value2' is NaN, the result is NaN. */
1616
1617                         return intBitsToFloat(FLT_NAN);
1618
1619                 } else if (finitef(b)) {
1620                         /* Division of an infinity by a finite value results in a signed */
1621                         /* infinity, with the sign-producing rule just given. */
1622
1623                         /* is sign equal? */
1624
1625                         if (copysignf(1.0, a) == copysignf(1.0, b))
1626                                 return intBitsToFloat(FLT_POSINF);
1627                         else
1628                                 return intBitsToFloat(FLT_NEGINF);
1629
1630                 } else {
1631                         /* Division of an infinity by an infinity results in NaN. */
1632
1633                         return intBitsToFloat(FLT_NAN);
1634                 }
1635         }
1636 }
1637
1638
1639 float builtin_fneg(float a)
1640 {
1641         if (isnanf(a)) return a;
1642         else {
1643                 if (finitef(a)) return -a;
1644                 else return copysignf(a, -copysignf(1.0, a));
1645         }
1646 }
1647 #endif /* !SUPPORT_FLOAT */
1648
1649
1650 #if !SUPPORT_FLOAT || !SUPPORT_FLOAT_CMP || defined(ENABLE_INTRP)
1651 s4 builtin_fcmpl(float a, float b)
1652 {
1653         if (isnanf(a))
1654                 return -1;
1655
1656         if (isnanf(b))
1657                 return -1;
1658
1659         if (!finitef(a) || !finitef(b)) {
1660                 a = finitef(a) ? 0 : copysignf(1.0,     a);
1661                 b = finitef(b) ? 0 : copysignf(1.0, b);
1662         }
1663
1664         if (a > b)
1665                 return 1;
1666
1667         if (a == b)
1668                 return 0;
1669
1670         return -1;
1671 }
1672
1673
1674 s4 builtin_fcmpg(float a, float b)
1675 {
1676         if (isnanf(a)) return 1;
1677         if (isnanf(b)) return 1;
1678         if (!finitef(a) || !finitef(b)) {
1679                 a = finitef(a) ? 0 : copysignf(1.0, a);
1680                 b = finitef(b) ? 0 : copysignf(1.0, b);
1681         }
1682         if (a > b) return 1;
1683         if (a == b) return 0;
1684         return -1;
1685 }
1686 #endif /* !SUPPORT_FLOAT || !SUPPORT_FLOAT_CMP || defined(ENABLE_INTRP) */
1687
1688
1689 float builtin_frem(float a, float b)
1690 {
1691         return fmodf(a, b);
1692 }
1693
1694
1695 /* functions for unsupported double instructions ******************************/
1696
1697 #if !SUPPORT_DOUBLE
1698 double builtin_dadd(double a, double b)
1699 {
1700         if (isnan(a)) return longBitsToDouble(DBL_NAN);
1701         if (isnan(b)) return longBitsToDouble(DBL_NAN);
1702         if (finite(a)) {
1703                 if (finite(b)) return a + b;
1704                 else return b;
1705         }
1706         else {
1707                 if (finite(b)) return a;
1708                 else {
1709                         if (copysign(1.0, a)==copysign(1.0, b)) return a;
1710                         else return longBitsToDouble(DBL_NAN);
1711                 }
1712         }
1713 }
1714
1715
1716 double builtin_dsub(double a, double b)
1717 {
1718         return builtin_dadd(a, builtin_dneg(b));
1719 }
1720
1721
1722 double builtin_dmul(double a, double b)
1723 {
1724         if (isnan(a)) return longBitsToDouble(DBL_NAN);
1725         if (isnan(b)) return longBitsToDouble(DBL_NAN);
1726         if (finite(a)) {
1727                 if (finite(b)) return a * b;
1728                 else {
1729                         if (a == 0) return longBitsToDouble(DBL_NAN);
1730                         else return copysign(b, copysign(1.0, b) * a);
1731                 }
1732         }
1733         else {
1734                 if (finite(b)) {
1735                         if (b == 0) return longBitsToDouble(DBL_NAN);
1736                         else return copysign(a, copysign(1.0, a) * b);
1737                 }
1738                 else {
1739                         return copysign(a, copysign(1.0, a) * copysign(1.0, b));
1740                 }
1741         }
1742 }
1743
1744
1745 /* builtin_ddiv ****************************************************************
1746
1747    Implementation as described in VM Spec.
1748
1749 *******************************************************************************/
1750
1751 double builtin_ddiv(double a, double b)
1752 {
1753         if (finite(a)) {
1754                 if (finite(b)) {
1755                         /* If neither value1' nor value2' is NaN, the sign of the result */
1756                         /* is positive if both values have the same sign, negative if the */
1757                         /* values have different signs. */
1758
1759                         return a / b;
1760
1761                 } else {
1762                         if (isnan(b)) {
1763                                 /* If either value1' or value2' is NaN, the result is NaN. */
1764
1765                                 return longBitsToDouble(DBL_NAN);
1766
1767                         } else {
1768                                 /* Division of a finite value by an infinity results in a */
1769                                 /* signed zero, with the sign-producing rule just given. */
1770
1771                                 /* is sign equal? */
1772
1773                                 if (copysign(1.0, a) == copysign(1.0, b))
1774                                         return 0.0;
1775                                 else
1776                                         return -0.0;
1777                         }
1778                 }
1779
1780         } else {
1781                 if (isnan(a)) {
1782                         /* If either value1' or value2' is NaN, the result is NaN. */
1783
1784                         return longBitsToDouble(DBL_NAN);
1785
1786                 } else if (finite(b)) {
1787                         /* Division of an infinity by a finite value results in a signed */
1788                         /* infinity, with the sign-producing rule just given. */
1789
1790                         /* is sign equal? */
1791
1792                         if (copysign(1.0, a) == copysign(1.0, b))
1793                                 return longBitsToDouble(DBL_POSINF);
1794                         else
1795                                 return longBitsToDouble(DBL_NEGINF);
1796
1797                 } else {
1798                         /* Division of an infinity by an infinity results in NaN. */
1799
1800                         return longBitsToDouble(DBL_NAN);
1801                 }
1802         }
1803 }
1804
1805
1806 /* builtin_dneg ****************************************************************
1807
1808    Implemented as described in VM Spec.
1809
1810 *******************************************************************************/
1811
1812 double builtin_dneg(double a)
1813 {
1814         if (isnan(a)) {
1815                 /* If the operand is NaN, the result is NaN (recall that NaN has no */
1816                 /* sign). */
1817
1818                 return a;
1819
1820         } else {
1821                 if (finite(a)) {
1822                         /* If the operand is a zero, the result is the zero of opposite */
1823                         /* sign. */
1824
1825                         return -a;
1826
1827                 } else {
1828                         /* If the operand is an infinity, the result is the infinity of */
1829                         /* opposite sign. */
1830
1831                         return copysign(a, -copysign(1.0, a));
1832                 }
1833         }
1834 }
1835 #endif /* !SUPPORT_DOUBLE */
1836
1837
1838 #if !SUPPORT_DOUBLE || !SUPPORT_DOUBLE_CMP || defined(ENABLE_INTRP)
1839 s4 builtin_dcmpl(double a, double b)
1840 {
1841         if (isnan(a))
1842                 return -1;
1843
1844         if (isnan(b))
1845                 return -1;
1846
1847         if (!finite(a) || !finite(b)) {
1848                 a = finite(a) ? 0 : copysign(1.0, a);
1849                 b = finite(b) ? 0 : copysign(1.0, b);
1850         }
1851
1852         if (a > b)
1853                 return 1;
1854
1855         if (a == b)
1856                 return 0;
1857
1858         return -1;
1859 }
1860
1861
1862 s4 builtin_dcmpg(double a, double b)
1863 {
1864         if (isnan(a))
1865                 return 1;
1866
1867         if (isnan(b))
1868                 return 1;
1869
1870         if (!finite(a) || !finite(b)) {
1871                 a = finite(a) ? 0 : copysign(1.0, a);
1872                 b = finite(b) ? 0 : copysign(1.0, b);
1873         }
1874
1875         if (a > b)
1876                 return 1;
1877
1878         if (a == b)
1879                 return 0;
1880
1881         return -1;
1882 }
1883 #endif /* !SUPPORT_DOUBLE || !SUPPORT_DOUBLE_CMP || defined(ENABLE_INTRP) */
1884
1885
1886 double builtin_drem(double a, double b)
1887 {
1888         return fmod(a, b);
1889 }
1890
1891
1892 /* conversion operations ******************************************************/
1893
1894 #if 0
1895 s8 builtin_i2l(s4 i)
1896 {
1897 #if U8_AVAILABLE
1898         return i;
1899 #else
1900         s8 v;
1901         v.high = 0;
1902         v.low = i;
1903         return v;
1904 #endif
1905 }
1906
1907 s4 builtin_l2i(s8 l)
1908 {
1909 #if U8_AVAILABLE
1910         return (s4) l;
1911 #else
1912         return l.low;
1913 #endif
1914 }
1915 #endif
1916
1917
1918 #if !(SUPPORT_FLOAT && SUPPORT_I2F)
1919 float builtin_i2f(s4 a)
1920 {
1921         float f = (float) a;
1922         return f;
1923 }
1924 #endif /* !(SUPPORT_FLOAT && SUPPORT_I2F) */
1925
1926
1927 #if !(SUPPORT_DOUBLE && SUPPORT_I2D)
1928 double builtin_i2d(s4 a)
1929 {
1930         double d = (double) a;
1931         return d;
1932 }
1933 #endif /* !(SUPPORT_DOUBLE && SUPPORT_I2D) */
1934
1935
1936 #if !(SUPPORT_LONG && SUPPORT_FLOAT && SUPPORT_L2F)
1937 float builtin_l2f(s8 a)
1938 {
1939 #if U8_AVAILABLE
1940         float f = (float) a;
1941         return f;
1942 #else
1943         return 0.0;
1944 #endif
1945 }
1946 #endif /* !(SUPPORT_LONG && SUPPORT_FLOAT && SUPPORT_L2F) */
1947
1948
1949 #if !(SUPPORT_LONG && SUPPORT_DOUBLE && SUPPORT_L2D)
1950 double builtin_l2d(s8 a)
1951 {
1952 #if U8_AVAILABLE
1953         double d = (double) a;
1954         return d;
1955 #else
1956         return 0.0;
1957 #endif
1958 }
1959 #endif /* !(SUPPORT_LONG && SUPPORT_DOUBLE && SUPPORT_L2D) */
1960
1961
1962 #if !(SUPPORT_FLOAT && SUPPORT_F2I) || defined(ENABLE_INTRP) || defined(DISABLE_GC)
1963 s4 builtin_f2i(float a) 
1964 {
1965         s4 i;
1966
1967         i = builtin_d2i((double) a);
1968
1969         return i;
1970
1971         /*      float f;
1972         
1973                 if (isnanf(a))
1974                 return 0;
1975                 if (finitef(a)) {
1976                 if (a > 2147483647)
1977                 return 2147483647;
1978                 if (a < (-2147483648))
1979                 return (-2147483648);
1980                 return (s4) a;
1981                 }
1982                 f = copysignf((float) 1.0, a);
1983                 if (f > 0)
1984                 return 2147483647;
1985                 return (-2147483648); */
1986 }
1987 #endif /* !(SUPPORT_FLOAT && SUPPORT_F2I) || defined(ENABLE_INTRP) || defined(DISABLE_GC) */
1988
1989
1990 #if !(SUPPORT_FLOAT && SUPPORT_LONG && SUPPORT_F2L) || defined(DISABLE_GC)
1991 s8 builtin_f2l(float a)
1992 {
1993         s8 l;
1994
1995         l = builtin_d2l((double) a);
1996
1997         return l;
1998
1999         /*      float f;
2000         
2001                 if (finitef(a)) {
2002                 if (a > 9223372036854775807L)
2003                 return 9223372036854775807L;
2004                 if (a < (-9223372036854775808L))
2005                 return (-9223372036854775808L);
2006                 return (s8) a;
2007                 }
2008                 if (isnanf(a))
2009                 return 0;
2010                 f = copysignf((float) 1.0, a);
2011                 if (f > 0)
2012                 return 9223372036854775807L;
2013                 return (-9223372036854775808L); */
2014 }
2015 #endif /* !(SUPPORT_FLOAT && SUPPORT_LONG && SUPPORT_F2L) */
2016
2017
2018 #if !(SUPPORT_DOUBLE && SUPPORT_D2I) || defined(ENABLE_INTRP) || defined(DISABLE_GC)
2019 s4 builtin_d2i(double a) 
2020
2021         double d;
2022         
2023         if (finite(a)) {
2024                 if (a >= 2147483647)
2025                         return 2147483647;
2026                 if (a <= (-2147483647-1))
2027                         return (-2147483647-1);
2028                 return (s4) a;
2029         }
2030         if (isnan(a))
2031                 return 0;
2032         d = copysign(1.0, a);
2033         if (d > 0)
2034                 return 2147483647;
2035         return (-2147483647-1);
2036 }
2037 #endif /* !(SUPPORT_DOUBLE && SUPPORT_D2I) || defined(ENABLE_INTRP) || defined(DISABLE_GC) */
2038
2039
2040 #if !(SUPPORT_DOUBLE && SUPPORT_LONG && SUPPORT_D2L) || defined(DISABLE_GC)
2041 s8 builtin_d2l(double a)
2042 {
2043         double d;
2044         
2045         if (finite(a)) {
2046                 if (a >= 9223372036854775807LL)
2047                         return 9223372036854775807LL;
2048                 if (a <= (-9223372036854775807LL-1))
2049                         return (-9223372036854775807LL-1);
2050                 return (s8) a;
2051         }
2052         if (isnan(a))
2053                 return 0;
2054         d = copysign(1.0, a);
2055         if (d > 0)
2056                 return 9223372036854775807LL;
2057         return (-9223372036854775807LL-1);
2058 }
2059 #endif /* !(SUPPORT_DOUBLE && SUPPORT_LONG && SUPPORT_D2L) */
2060
2061
2062 #if !(SUPPORT_FLOAT && SUPPORT_DOUBLE)
2063 double builtin_f2d(float a)
2064 {
2065         if (finitef(a)) return (double) a;
2066         else {
2067                 if (isnanf(a))
2068                         return longBitsToDouble(DBL_NAN);
2069                 else
2070                         return copysign(longBitsToDouble(DBL_POSINF), (double) copysignf(1.0, a) );
2071         }
2072 }
2073
2074 float builtin_d2f(double a)
2075 {
2076         if (finite(a))
2077                 return (float) a;
2078         else {
2079                 if (isnan(a))
2080                         return intBitsToFloat(FLT_NAN);
2081                 else
2082                         return copysignf(intBitsToFloat(FLT_POSINF), (float) copysign(1.0, a));
2083         }
2084 }
2085 #endif /* !(SUPPORT_FLOAT && SUPPORT_DOUBLE) */
2086
2087
2088 /*============================================================================*/
2089 /* AUTOMATICALLY REPLACED FUNCTIONS                                           */
2090 /*============================================================================*/
2091
2092 /* builtin_arraycopy ***********************************************************
2093
2094    Builtin for java.lang.System.arraycopy.
2095
2096    NOTE: This is a SLOW builtin and can be called from JIT & NATIVE code.
2097
2098 *******************************************************************************/
2099
2100 void builtin_arraycopy(java_handle_t *src, s4 srcStart,
2101                                            java_handle_t *dest, s4 destStart, s4 len)
2102 {
2103         arraydescriptor *sdesc;
2104         arraydescriptor *ddesc;
2105         s4               i;
2106
2107         if ((src == NULL) || (dest == NULL)) {
2108                 exceptions_throw_nullpointerexception();
2109                 return;
2110         }
2111
2112         sdesc = LLNI_vftbl_direct(src)->arraydesc;
2113         ddesc = LLNI_vftbl_direct(dest)->arraydesc;
2114
2115         if (!sdesc || !ddesc || (sdesc->arraytype != ddesc->arraytype)) {
2116                 exceptions_throw_arraystoreexception();
2117                 return;
2118         }
2119
2120         /* we try to throw exception with the same message as SUN does */
2121
2122         if ((len < 0) || (srcStart < 0) || (destStart < 0) ||
2123                 (srcStart  + len < 0) || (srcStart  + len > LLNI_array_size(src)) ||
2124                 (destStart + len < 0) || (destStart + len > LLNI_array_size(dest))) {
2125                 exceptions_throw_arrayindexoutofboundsexception();
2126                 return;
2127         }
2128
2129         if (sdesc->componentvftbl == ddesc->componentvftbl) {
2130                 /* We copy primitive values or references of exactly the same type */
2131
2132                 s4 dataoffset = sdesc->dataoffset;
2133                 s4 componentsize = sdesc->componentsize;
2134
2135                 LLNI_CRITICAL_START;
2136
2137                 MMOVE(((u1 *) LLNI_DIRECT(dest)) + dataoffset + componentsize * destStart,
2138                           ((u1 *) LLNI_DIRECT(src))  + dataoffset + componentsize * srcStart,
2139                           u1, (size_t) len * componentsize);
2140
2141                 LLNI_CRITICAL_END;
2142         }
2143         else {
2144                 /* We copy references of different type */
2145
2146                 java_handle_objectarray_t *oas = (java_handle_objectarray_t *) src;
2147                 java_handle_objectarray_t *oad = (java_handle_objectarray_t *) dest;
2148  
2149                 if (destStart <= srcStart) {
2150                         for (i = 0; i < len; i++) {
2151                                 java_handle_t *o;
2152
2153                                 o = array_objectarray_element_get(oas, srcStart + i);
2154
2155                                 if (!builtin_canstore(oad, o))
2156                                         return;
2157
2158                                 array_objectarray_element_set(oad, destStart + i, o);
2159                         }
2160                 }
2161                 else {
2162                         /* XXX this does not completely obey the specification!
2163                            If an exception is thrown only the elements above the
2164                            current index have been copied. The specification
2165                            requires that only the elements *below* the current
2166                            index have been copied before the throw. */
2167
2168                         for (i = len - 1; i >= 0; i--) {
2169                                 java_handle_t *o;
2170
2171                                 o = array_objectarray_element_get(oas, srcStart + i);
2172
2173                                 if (!builtin_canstore(oad, o))
2174                                         return;
2175
2176                                 array_objectarray_element_set(oad, destStart + i, o);
2177                         }
2178                 }
2179         }
2180 }
2181
2182
2183 /* builtin_nanotime ************************************************************
2184
2185    Return the current time in nanoseconds.
2186
2187 *******************************************************************************/
2188
2189 s8 builtin_nanotime(void)
2190 {
2191         struct timeval tv;
2192         s8             usecs;
2193
2194         if (gettimeofday(&tv, NULL) == -1)
2195                 vm_abort("gettimeofday failed: %s", strerror(errno));
2196
2197         usecs = (s8) tv.tv_sec * (1000 * 1000) + (s8) tv.tv_usec;
2198
2199         return usecs * 1000;
2200 }
2201
2202
2203 /* builtin_currenttimemillis ***************************************************
2204
2205    Return the current time in milliseconds.
2206
2207 *******************************************************************************/
2208
2209 s8 builtin_currenttimemillis(void)
2210 {
2211         s8 msecs;
2212
2213         msecs = builtin_nanotime() / 1000 / 1000;
2214
2215         return msecs;
2216 }
2217
2218
2219 /* builtin_clone ***************************************************************
2220
2221    Function for cloning objects or arrays.
2222
2223    NOTE: This is a SLOW builtin and can be called from JIT & NATIVE code.
2224
2225 *******************************************************************************/
2226
2227 java_handle_t *builtin_clone(void *env, java_handle_t *o)
2228 {
2229         arraydescriptor *ad;
2230         u4               size;
2231         classinfo       *c;
2232         java_handle_t   *co;                /* cloned object header               */
2233
2234         /* get the array descriptor */
2235
2236         ad = LLNI_vftbl_direct(o)->arraydesc;
2237
2238         /* we are cloning an array */
2239
2240         if (ad != NULL) {
2241                 size = ad->dataoffset + ad->componentsize * LLNI_array_size(o);
2242         
2243                 co = heap_alloc(size, (ad->arraytype == ARRAYTYPE_OBJECT), NULL, true);
2244
2245                 if (co == NULL)
2246                         return NULL;
2247
2248 #if !defined(ENABLE_GC_CACAO) && defined(ENABLE_HANDLES)
2249                 /* XXX this is only a dirty hack to make Boehm work with handles */
2250
2251                 co = LLNI_WRAP((java_object_t *) co);
2252 #endif
2253
2254                 LLNI_CRITICAL_START;
2255
2256                 MCOPY(LLNI_DIRECT(co), LLNI_DIRECT(o), u1, size);
2257
2258 #if defined(ENABLE_GC_CACAO)
2259                 heap_init_objectheader(LLNI_DIRECT(co), size);
2260 #endif
2261
2262 #if defined(ENABLE_THREADS)
2263                 lock_init_object_lock(LLNI_DIRECT(co));
2264 #endif
2265
2266                 LLNI_CRITICAL_END;
2267
2268                 return co;
2269         }
2270     
2271     /* we are cloning a non-array */
2272
2273     if (!builtin_instanceof(o, class_java_lang_Cloneable)) {
2274         exceptions_throw_clonenotsupportedexception();
2275         return NULL;
2276     }
2277
2278         /* get the class of the object */
2279
2280         LLNI_class_get(o, c);
2281
2282         /* create new object */
2283
2284     co = builtin_new(c);
2285
2286     if (co == NULL)
2287         return NULL;
2288
2289         LLNI_CRITICAL_START;
2290
2291         MCOPY(LLNI_DIRECT(co), LLNI_DIRECT(o), u1, c->instancesize);
2292
2293 #if defined(ENABLE_GC_CACAO)
2294         heap_init_objectheader(LLNI_DIRECT(co), c->instancesize);
2295 #endif
2296
2297 #if defined(ENABLE_THREADS)
2298         lock_init_object_lock(LLNI_DIRECT(co));
2299 #endif
2300
2301         LLNI_CRITICAL_END;
2302
2303     return co;
2304 }
2305
2306
2307 #if defined(ENABLE_CYCLES_STATS)
2308 void builtin_print_cycles_stats(FILE *file)
2309 {
2310         fprintf(file,"builtin cylce count statistics:\n");
2311
2312         CYCLES_STATS_PRINT_OVERHEAD(builtin_overhead,file);
2313         CYCLES_STATS_PRINT(builtin_new         ,file);
2314
2315         fprintf(file,"\n");
2316 }
2317 #endif /* defined(ENABLE_CYCLES_STATS) */
2318
2319
2320 #if defined(ENABLE_VMLOG)
2321 #define NDEBUG
2322 #include <vmlog_cacao.c>
2323 #endif
2324
2325
2326 /*
2327  * These are local overrides for various environment variables in Emacs.
2328  * Please do not remove this and leave it at the end of the file, where
2329  * Emacs will automagically detect them.
2330  * ---------------------------------------------------------------------
2331  * Local variables:
2332  * mode: c
2333  * indent-tabs-mode: t
2334  * c-basic-offset: 4
2335  * tab-width: 4
2336  * End:
2337  * vim:noexpandtab:sw=4:ts=4:
2338  */