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