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