Merge to subtype-trunk (manually: src/vm/linker.hpp, src/vm/vftbl.hpp)
[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.h"
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.h"
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 the restricted subtype relation (see
647    Cliff Click and John Rose: Fast subtype checking in the Hotspot JVM.)
648
649    RETURN VALUE:
650       1......s is a subtype of t.
651       0......otherwise
652
653 *******************************************************************************/
654
655 bool fast_subtype_check(struct _vftbl *s, struct _vftbl *t)
656 {
657    if (s->subtype_display[t->subtype_depth] == t)
658        return true;
659    if (t->subtype_offset != OFFSET(vftbl_t, subtype_display[DISPLAY_SIZE]))
660        return false;
661    return s->subtype_depth >= t->subtype_depth && s->subtype_overflow[t->subtype_depth - DISPLAY_SIZE] == t;
662 }
663 #endif
664
665 /* builtin_fast_canstore *******************************************************
666
667    Checks, if an object can be stored in an array.
668
669    RETURN VALUE:
670       1......possible
671       0......otherwise (no exception thrown!)
672
673    NOTE: This is a FAST builtin and can be called from JIT code only.
674
675 *******************************************************************************/
676
677 bool builtin_fast_canstore(java_objectarray_t *oa, java_object_t *o)
678 {
679         arraydescriptor *desc;
680         arraydescriptor *valuedesc;
681         vftbl_t         *componentvftbl;
682         vftbl_t         *valuevftbl;
683         int32_t          baseval;
684         uint32_t         diffval;
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                         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         uint32_t         diffval;
758         bool             result;
759         
760         if (o == NULL)
761                 return 1;
762
763         /* The following is guaranteed (by verifier checks):
764          *
765          *     *) a->...vftbl->arraydesc != NULL
766          *     *) a->...vftbl->arraydesc->elementvftbl != NULL
767          *     *) a->...vftbl->arraydesc->dimension == 1
768          *     *) o->vftbl is not an interface vftbl
769          */
770
771         desc = a->header.objheader.vftbl->arraydesc;
772     elementvftbl = desc->elementvftbl;
773         valuevftbl = o->vftbl;
774
775         /* {a is a one-dimensional array} */
776         
777         if (valuevftbl == elementvftbl)
778                 return 1;
779
780         LOCK_CLASSRENUMBER_LOCK;
781
782         baseval = elementvftbl->baseval;
783
784         if (baseval <= 0) {
785                 /* an array of interface references */
786                 result = ((valuevftbl->interfacetablelength > -baseval) &&
787                                   (valuevftbl->interfacetable[baseval] != NULL));
788         }
789         else {
790 #if USES_NEW_SUBTYPE
791                 result = fast_subtype_check(valuevftbl, elementvftbl);
792 #else
793                 diffval = valuevftbl->baseval - elementvftbl->baseval;
794                 result  = diffval <= (uint32_t) elementvftbl->diffval;
795 #endif
796         }
797
798         UNLOCK_CLASSRENUMBER_LOCK;
799
800         return result;
801 }
802
803
804 /* This is an optimized version where a is guaranteed to be a
805  * one-dimensional array of a class type */
806 bool builtin_fast_canstore_onedim_class(java_objectarray_t *a, java_object_t *o)
807 {
808         vftbl_t  *elementvftbl;
809         vftbl_t  *valuevftbl;
810         uint32_t  diffval;
811         bool      result;
812         
813         if (o == NULL)
814                 return 1;
815
816         /* The following is guaranteed (by verifier checks):
817          *
818          *     *) a->...vftbl->arraydesc != NULL
819          *     *) a->...vftbl->arraydesc->elementvftbl != NULL
820          *     *) a->...vftbl->arraydesc->elementvftbl is not an interface vftbl
821          *     *) a->...vftbl->arraydesc->dimension == 1
822          *     *) o->vftbl is not an interface vftbl
823          */
824
825     elementvftbl = a->header.objheader.vftbl->arraydesc->elementvftbl;
826         valuevftbl = o->vftbl;
827
828         /* {a is a one-dimensional array} */
829         
830         if (valuevftbl == elementvftbl)
831                 return 1;
832
833         LOCK_CLASSRENUMBER_LOCK;
834
835 #if USES_NEW_SUBTYPE
836         result = fast_subtype_check(valuevftbl, elementvftbl);
837 #else
838         diffval = valuevftbl->baseval - elementvftbl->baseval;
839         result  = diffval <= (uint32_t) elementvftbl->diffval;
840 #endif
841
842         UNLOCK_CLASSRENUMBER_LOCK;
843
844         return result;
845 }
846
847
848 /* builtin_new *****************************************************************
849
850    Creates a new instance of class c on the heap.
851
852    RETURN VALUE:
853       pointer to the object, or NULL if no memory is available
854
855    NOTE: This builtin can be called from NATIVE code only.
856
857 *******************************************************************************/
858
859 java_handle_t *builtin_new(classinfo *c)
860 {
861         java_handle_t *o;
862 #if defined(ENABLE_RT_TIMING)
863         struct timespec time_start, time_end;
864 #endif
865 #if defined(ENABLE_CYCLES_STATS)
866         u8 cycles_start, cycles_end;
867 #endif
868
869         RT_TIMING_GET_TIME(time_start);
870         CYCLES_STATS_GET(cycles_start);
871
872         /* is the class loaded */
873
874         assert(c->state & CLASS_LOADED);
875
876         /* check if we can instantiate this class */
877
878         if (c->flags & ACC_ABSTRACT) {
879                 exceptions_throw_instantiationerror(c);
880                 return NULL;
881         }
882
883         /* is the class linked */
884
885         if (!(c->state & CLASS_LINKED))
886                 if (!link_class(c))
887                         return NULL;
888
889         if (!(c->state & CLASS_INITIALIZED)) {
890 #if !defined(NDEBUG)
891                 if (initverbose)
892                         log_message_class("Initialize class (from builtin_new): ", c);
893 #endif
894
895                 if (!initialize_class(c))
896                         return NULL;
897         }
898
899         o = (java_handle_t*) heap_alloc(c->instancesize, c->flags & ACC_CLASS_HAS_POINTERS,
900                                                                         c->finalizer, true);
901
902         if (!o)
903                 return NULL;
904
905 #if !defined(ENABLE_GC_CACAO) && defined(ENABLE_HANDLES)
906         /* XXX this is only a dirty hack to make Boehm work with handles */
907
908         o = LLNI_WRAP((java_object_t *) o);
909 #endif
910
911         LLNI_vftbl_direct(o) = c->vftbl;
912
913 #if defined(ENABLE_THREADS)
914         LLNI_DIRECT(o)->lockword.init();
915 #endif
916
917         CYCLES_STATS_GET(cycles_end);
918         RT_TIMING_GET_TIME(time_end);
919
920         CYCLES_STATS_COUNT(builtin_new,cycles_end - cycles_start);
921         RT_TIMING_TIME_DIFF(time_start, time_end, RT_TIMING_NEW_OBJECT);
922
923         return o;
924 }
925
926 #if defined(ENABLE_ESCAPE_REASON)
927 java_handle_t *builtin_escape_reason_new(classinfo *c) {
928         print_escape_reasons();
929         return builtin_java_new(c);
930 }
931 #endif
932
933 #if defined(ENABLE_TLH)
934 java_handle_t *builtin_tlh_new(classinfo *c)
935 {
936         java_handle_t *o;
937 # if defined(ENABLE_RT_TIMING)
938         struct timespec time_start, time_end;
939 # endif
940 # if defined(ENABLE_CYCLES_STATS)
941         u8 cycles_start, cycles_end;
942 # endif
943
944         RT_TIMING_GET_TIME(time_start);
945         CYCLES_STATS_GET(cycles_start);
946
947         /* is the class loaded */
948
949         assert(c->state & CLASS_LOADED);
950
951         /* check if we can instantiate this class */
952
953         if (c->flags & ACC_ABSTRACT) {
954                 exceptions_throw_instantiationerror(c);
955                 return NULL;
956         }
957
958         /* is the class linked */
959
960         if (!(c->state & CLASS_LINKED))
961                 if (!link_class(c))
962                         return NULL;
963
964         if (!(c->state & CLASS_INITIALIZED)) {
965 # if !defined(NDEBUG)
966                 if (initverbose)
967                         log_message_class("Initialize class (from builtin_new): ", c);
968 # endif
969
970                 if (!initialize_class(c))
971                         return NULL;
972         }
973
974         /*
975         o = tlh_alloc(&(THREADOBJECT->tlh), c->instancesize);
976         */
977         o = NULL;
978
979         if (o == NULL) {
980                 o = (java_handle_t*) heap_alloc(c->instancesize, c->flags & ACC_CLASS_HAS_POINTERS,
981                                                                                 c->finalizer, true);
982         }
983
984         if (!o)
985                 return NULL;
986
987 # if !defined(ENABLE_GC_CACAO) && defined(ENABLE_HANDLES)
988         /* XXX this is only a dirty hack to make Boehm work with handles */
989
990         o = LLNI_WRAP((java_object_t *) o);
991 # endif
992
993         LLNI_vftbl_direct(o) = c->vftbl;
994
995 # if defined(ENABLE_THREADS)
996         LLNI_DIRECT(o)->lockword.init();
997 # endif
998
999         CYCLES_STATS_GET(cycles_end);
1000         RT_TIMING_GET_TIME(time_end);
1001
1002 /*
1003         CYCLES_STATS_COUNT(builtin_new,cycles_end - cycles_start);
1004         RT_TIMING_TIME_DIFF(time_start, time_end, RT_TIMING_NEW_OBJECT);
1005 */
1006
1007         return o;
1008 }
1009 #endif
1010
1011
1012 /* builtin_java_new ************************************************************
1013
1014    NOTE: This is a SLOW builtin and can be called from JIT code only.
1015
1016 *******************************************************************************/
1017
1018 java_handle_t *builtin_java_new(java_handle_t *clazz)
1019 {
1020         return builtin_new(LLNI_classinfo_unwrap(clazz));
1021 }
1022
1023
1024 /* builtin_fast_new ************************************************************
1025
1026    Creates a new instance of class c on the heap.
1027
1028    RETURN VALUE:
1029       pointer to the object, or NULL if no fast return
1030       is possible for any reason.
1031
1032    NOTE: This is a FAST builtin and can be called from JIT code only.
1033
1034 *******************************************************************************/
1035
1036 java_object_t *builtin_fast_new(classinfo *c)
1037 {
1038         java_object_t *o;
1039 #if defined(ENABLE_RT_TIMING)
1040         struct timespec time_start, time_end;
1041 #endif
1042 #if defined(ENABLE_CYCLES_STATS)
1043         u8 cycles_start, cycles_end;
1044 #endif
1045
1046         RT_TIMING_GET_TIME(time_start);
1047         CYCLES_STATS_GET(cycles_start);
1048
1049         /* is the class loaded */
1050
1051         assert(c->state & CLASS_LOADED);
1052
1053         /* check if we can instantiate this class */
1054
1055         if (c->flags & ACC_ABSTRACT)
1056                 return NULL;
1057
1058         /* is the class linked */
1059
1060         if (!(c->state & CLASS_LINKED))
1061                 return NULL;
1062
1063         if (!(c->state & CLASS_INITIALIZED))
1064                 return NULL;
1065
1066         o = (java_handle_t*) heap_alloc(c->instancesize, c->flags & ACC_CLASS_HAS_POINTERS,
1067                                                                         c->finalizer, false);
1068
1069         if (!o)
1070                 return NULL;
1071
1072         o->vftbl = c->vftbl;
1073
1074 #if defined(ENABLE_THREADS)
1075         LLNI_DIRECT(o)->lockword.init();
1076 #endif
1077
1078         CYCLES_STATS_GET(cycles_end);
1079         RT_TIMING_GET_TIME(time_end);
1080
1081         CYCLES_STATS_COUNT(builtin_new,cycles_end - cycles_start);
1082         RT_TIMING_TIME_DIFF(time_start, time_end, RT_TIMING_NEW_OBJECT);
1083
1084         return o;
1085 }
1086
1087
1088 /* builtin_newarray ************************************************************
1089
1090    Creates an array with the given vftbl on the heap. This function
1091    takes as class argument an array class.
1092
1093    RETURN VALUE:
1094       pointer to the array or NULL if no memory is available
1095
1096    NOTE: This builtin can be called from NATIVE code only.
1097
1098 *******************************************************************************/
1099
1100 java_handle_t *builtin_newarray(int32_t size, classinfo *arrayclass)
1101 {
1102         arraydescriptor *desc;
1103         s4               dataoffset;
1104         s4               componentsize;
1105         s4               actualsize;
1106         java_handle_t   *a;
1107 #if defined(ENABLE_RT_TIMING)
1108         struct timespec time_start, time_end;
1109 #endif
1110
1111         RT_TIMING_GET_TIME(time_start);
1112
1113         desc          = arrayclass->vftbl->arraydesc;
1114         dataoffset    = desc->dataoffset;
1115         componentsize = desc->componentsize;
1116
1117         if (size < 0) {
1118                 exceptions_throw_negativearraysizeexception();
1119                 return NULL;
1120         }
1121
1122         actualsize = dataoffset + size * componentsize;
1123
1124         /* check for overflow */
1125
1126         if (((u4) actualsize) < ((u4) size)) {
1127                 exceptions_throw_outofmemoryerror();
1128                 return NULL;
1129         }
1130
1131         a = (java_handle_t*) heap_alloc(actualsize, (desc->arraytype == ARRAYTYPE_OBJECT), NULL, true);
1132
1133         if (a == NULL)
1134                 return NULL;
1135
1136 #if !defined(ENABLE_GC_CACAO) && defined(ENABLE_HANDLES)
1137         /* XXX this is only a dirty hack to make Boehm work with handles */
1138
1139         a = LLNI_WRAP((java_object_t *) a);
1140 #endif
1141
1142         LLNI_vftbl_direct(a) = arrayclass->vftbl;
1143
1144 #if defined(ENABLE_THREADS)
1145         LLNI_DIRECT(a)->lockword.init();
1146 #endif
1147
1148         LLNI_array_size(a) = size;
1149
1150         RT_TIMING_GET_TIME(time_end);
1151         RT_TIMING_TIME_DIFF(time_start, time_end, RT_TIMING_NEW_ARRAY);
1152
1153         return a;
1154 }
1155
1156
1157 /* builtin_java_newarray *******************************************************
1158
1159    NOTE: This is a SLOW builtin and can be called from JIT code only.
1160
1161 *******************************************************************************/
1162
1163 java_handle_t *builtin_java_newarray(int32_t size, java_handle_t *arrayclazz)
1164 {
1165         return builtin_newarray(size, LLNI_classinfo_unwrap(arrayclazz));
1166 }
1167
1168
1169 /* builtin_anewarray ***********************************************************
1170
1171    Creates an array of references to the given class type on the heap.
1172
1173    RETURN VALUE:
1174       pointer to the array or NULL if no memory is
1175       available
1176
1177    NOTE: This builtin can be called from NATIVE code only.
1178
1179 *******************************************************************************/
1180
1181 java_handle_objectarray_t *builtin_anewarray(int32_t size, classinfo *componentclass)
1182 {
1183         classinfo *arrayclass;
1184         
1185         /* is class loaded */
1186
1187         assert(componentclass->state & CLASS_LOADED);
1188
1189         /* is class linked */
1190
1191         if (!(componentclass->state & CLASS_LINKED))
1192                 if (!link_class(componentclass))
1193                         return NULL;
1194
1195         arrayclass = class_array_of(componentclass, true);
1196
1197         if (!arrayclass)
1198                 return NULL;
1199
1200         return (java_handle_objectarray_t *) builtin_newarray(size, arrayclass);
1201 }
1202
1203
1204 /* builtin_newarray_type ****************************************************
1205
1206    Creates an array of [type]s on the heap.
1207         
1208    RETURN VALUE:
1209       pointer to the array or NULL if no memory is available
1210
1211    NOTE: This is a SLOW builtin and can be called from JIT & NATIVE code.
1212
1213 *******************************************************************************/
1214
1215 #define BUILTIN_NEWARRAY_TYPE(type, arraytype)                             \
1216 java_handle_##type##array_t *builtin_newarray_##type(int32_t size)              \
1217 {                                                                          \
1218         return (java_handle_##type##array_t *)                                 \
1219                 builtin_newarray(size, primitivetype_table[arraytype].arrayclass); \
1220 }
1221
1222 BUILTIN_NEWARRAY_TYPE(boolean, ARRAYTYPE_BOOLEAN)
1223 BUILTIN_NEWARRAY_TYPE(byte,    ARRAYTYPE_BYTE)
1224 BUILTIN_NEWARRAY_TYPE(char,    ARRAYTYPE_CHAR)
1225 BUILTIN_NEWARRAY_TYPE(short,   ARRAYTYPE_SHORT)
1226 BUILTIN_NEWARRAY_TYPE(int,     ARRAYTYPE_INT)
1227 BUILTIN_NEWARRAY_TYPE(long,    ARRAYTYPE_LONG)
1228 BUILTIN_NEWARRAY_TYPE(float,   ARRAYTYPE_FLOAT)
1229 BUILTIN_NEWARRAY_TYPE(double,  ARRAYTYPE_DOUBLE)
1230
1231
1232 /* builtin_multianewarray_intern ***********************************************
1233
1234    Creates a multi-dimensional array on the heap. The dimensions are
1235    passed in an array of longs.
1236
1237    ARGUMENTS:
1238       n.............number of dimensions to create
1239       arrayclass....the array class
1240       dims..........array containing the size of each dimension to create
1241
1242    RETURN VALUE:
1243       pointer to the array or NULL if no memory is available
1244
1245 ******************************************************************************/
1246
1247 static java_handle_t *builtin_multianewarray_intern(int n,
1248                                                                                                         classinfo *arrayclass,
1249                                                                                                         long *dims)
1250 {
1251         s4             size;
1252         java_handle_t *a;
1253         classinfo     *componentclass;
1254         s4             i;
1255
1256         /* create this dimension */
1257
1258         size = (s4) dims[0];
1259         a = builtin_newarray(size, arrayclass);
1260
1261         if (!a)
1262                 return NULL;
1263
1264         /* if this is the last dimension return */
1265
1266         if (!--n)
1267                 return a;
1268
1269         /* get the class of the components to create */
1270
1271         componentclass = arrayclass->vftbl->arraydesc->componentvftbl->clazz;
1272
1273         /* The verifier guarantees that the dimension count is in the range. */
1274
1275         /* create the component arrays */
1276
1277         for (i = 0; i < size; i++) {
1278                 java_handle_t *ea =
1279 #if defined(__MIPS__) && (SIZEOF_VOID_P == 4)
1280                         /* we save an s4 to a s8 slot, 8-byte aligned */
1281
1282                         builtin_multianewarray_intern(n, componentclass, dims + 2);
1283 #else
1284                         builtin_multianewarray_intern(n, componentclass, dims + 1);
1285 #endif
1286
1287                 if (!ea)
1288                         return NULL;
1289
1290                 array_objectarray_element_set((java_handle_objectarray_t *) a, i, ea);
1291         }
1292
1293         return a;
1294 }
1295
1296
1297 /* builtin_multianewarray ******************************************************
1298
1299    Wrapper for builtin_multianewarray_intern which checks all
1300    dimensions before we start allocating.
1301
1302    NOTE: This is a SLOW builtin and can be called from JIT code only.
1303
1304 ******************************************************************************/
1305
1306 java_handle_objectarray_t *builtin_multianewarray(int n,
1307                                                                                                   java_handle_t *arrayclazz,
1308                                                                                                   long *dims)
1309 {
1310         classinfo *c;
1311         s4         i;
1312         s4         size;
1313
1314         /* check all dimensions before doing anything */
1315
1316         for (i = 0; i < n; i++) {
1317 #if defined(__MIPS__) && (SIZEOF_VOID_P == 4)
1318                 /* we save an s4 to a s8 slot, 8-byte aligned */
1319                 size = (s4) dims[i * 2];
1320 #else
1321                 size = (s4) dims[i];
1322 #endif
1323
1324                 if (size < 0) {
1325                         exceptions_throw_negativearraysizeexception();
1326                         return NULL;
1327                 }
1328         }
1329
1330         c = LLNI_classinfo_unwrap(arrayclazz);
1331
1332         /* now call the real function */
1333
1334         return (java_handle_objectarray_t *)
1335                 builtin_multianewarray_intern(n, c, dims);
1336 }
1337
1338
1339 /* builtin_verbosecall_enter ***************************************************
1340
1341    Print method call with arguments for -verbose:call.
1342
1343    XXX: Remove mew once all archs use the new tracer!
1344
1345 *******************************************************************************/
1346
1347 #if !defined(NDEBUG)
1348 #ifdef TRACE_ARGS_NUM
1349 void builtin_verbosecall_enter(s8 a0, s8 a1,
1350 # if TRACE_ARGS_NUM >= 4
1351                                                            s8 a2, s8 a3,
1352 # endif
1353 # if TRACE_ARGS_NUM >= 6
1354                                                            s8 a4, s8 a5,
1355 # endif
1356 # if TRACE_ARGS_NUM == 8
1357                                                            s8 a6, s8 a7,
1358 # endif
1359                                                            methodinfo *m)
1360 {
1361         log_text("builtin_verbosecall_enter: Do not call me anymore!");
1362 }
1363 #endif
1364 #endif /* !defined(NDEBUG) */
1365
1366
1367 /* builtin_verbosecall_exit ****************************************************
1368
1369    Print method exit for -verbose:call.
1370
1371    XXX: Remove mew once all archs use the new tracer!
1372
1373 *******************************************************************************/
1374
1375 #if !defined(NDEBUG)
1376 void builtin_verbosecall_exit(s8 l, double d, float f, methodinfo *m)
1377 {
1378         log_text("builtin_verbosecall_exit: Do not call me anymore!");
1379 }
1380 #endif /* !defined(NDEBUG) */
1381
1382
1383 /*============================================================================*/
1384 /* MISCELLANEOUS MATHEMATICAL HELPER FUNCTIONS                                */
1385 /*============================================================================*/
1386
1387 /*********** Functions for integer divisions *****************************
1388  
1389         On some systems (eg. DEC ALPHA), integer division is not supported by the
1390         CPU. These helper functions implement the missing functionality.
1391
1392 ******************************************************************************/
1393
1394 #if !SUPPORT_DIVISION || defined(DISABLE_GC)
1395 s4 builtin_idiv(s4 a, s4 b)
1396 {
1397         s4 c;
1398
1399         c = a / b;
1400
1401         return c;
1402 }
1403
1404 s4 builtin_irem(s4 a, s4 b)
1405 {
1406         s4 c;
1407
1408         c = a % b;
1409
1410         return c;
1411 }
1412 #endif /* !SUPPORT_DIVISION || defined(DISABLE_GC) */
1413
1414
1415 /* functions for long arithmetics **********************************************
1416
1417    On systems where 64 bit Integers are not supported by the CPU,
1418    these functions are needed.
1419
1420 ******************************************************************************/
1421
1422 #if !(SUPPORT_LONG && SUPPORT_LONG_ADD)
1423 s8 builtin_ladd(s8 a, s8 b)
1424 {
1425         s8 c;
1426
1427         c = a + b; 
1428
1429         return c;
1430 }
1431
1432 s8 builtin_lsub(s8 a, s8 b)
1433 {
1434         s8 c;
1435
1436         c = a - b; 
1437
1438         return c;
1439 }
1440
1441 s8 builtin_lneg(s8 a)
1442 {
1443         s8 c;
1444
1445         c = -a;
1446
1447         return c;
1448 }
1449 #endif /* !(SUPPORT_LONG && SUPPORT_LONG_ADD) */
1450
1451
1452 #if !(SUPPORT_LONG && SUPPORT_LONG_MUL)
1453 s8 builtin_lmul(s8 a, s8 b)
1454 {
1455         s8 c;
1456
1457         c = a * b; 
1458
1459         return c;
1460 }
1461 #endif /* !(SUPPORT_LONG && SUPPORT_LONG_MUL) */
1462
1463
1464 #if !(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_DIV) || defined (DISABLE_GC)
1465 s8 builtin_ldiv(s8 a, s8 b)
1466 {
1467         s8 c;
1468
1469         c = a / b; 
1470
1471         return c;
1472 }
1473
1474 s8 builtin_lrem(s8 a, s8 b)
1475 {
1476         s8 c;
1477
1478         c = a % b; 
1479
1480         return c;
1481 }
1482 #endif /* !(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_DIV) */
1483
1484
1485 #if !(SUPPORT_LONG && SUPPORT_LONG_SHIFT)
1486 s8 builtin_lshl(s8 a, s4 b)
1487 {
1488         s8 c;
1489
1490         c = a << (b & 63);
1491
1492         return c;
1493 }
1494
1495 s8 builtin_lshr(s8 a, s4 b)
1496 {
1497         s8 c;
1498
1499         c = a >> (b & 63);
1500
1501         return c;
1502 }
1503
1504 s8 builtin_lushr(s8 a, s4 b)
1505 {
1506         s8 c;
1507
1508         c = ((u8) a) >> (b & 63);
1509
1510         return c;
1511 }
1512 #endif /* !(SUPPORT_LONG && SUPPORT_LONG_SHIFT) */
1513
1514
1515 #if !(SUPPORT_LONG && SUPPORT_LONG_LOGICAL)
1516 s8 builtin_land(s8 a, s8 b)
1517 {
1518         s8 c;
1519
1520         c = a & b; 
1521
1522         return c;
1523 }
1524
1525 s8 builtin_lor(s8 a, s8 b)
1526 {
1527         s8 c;
1528
1529         c = a | b; 
1530
1531         return c;
1532 }
1533
1534 s8 builtin_lxor(s8 a, s8 b) 
1535 {
1536         s8 c;
1537
1538         c = a ^ b; 
1539
1540         return c;
1541 }
1542 #endif /* !(SUPPORT_LONG && SUPPORT_LONG_LOGICAL) */
1543
1544
1545 #if !(SUPPORT_LONG && SUPPORT_LONG_CMP)
1546 s4 builtin_lcmp(s8 a, s8 b)
1547
1548         if (a < b)
1549                 return -1;
1550
1551         if (a > b)
1552                 return 1;
1553
1554         return 0;
1555 }
1556 #endif /* !(SUPPORT_LONG && SUPPORT_LONG_CMP) */
1557
1558
1559 /* functions for unsupported floating instructions ****************************/
1560
1561 /* used to convert FLT_xxx defines into float values */
1562
1563 static inline float intBitsToFloat(s4 i)
1564 {
1565         imm_union imb;
1566
1567         imb.i = i;
1568         return imb.f;
1569 }
1570
1571
1572 /* used to convert DBL_xxx defines into double values */
1573
1574 static inline float longBitsToDouble(s8 l)
1575 {
1576         imm_union imb;
1577
1578         imb.l = l;
1579         return imb.d;
1580 }
1581
1582
1583 #if !SUPPORT_FLOAT
1584 float builtin_fadd(float a, float b)
1585 {
1586         if (isnanf(a)) return intBitsToFloat(FLT_NAN);
1587         if (isnanf(b)) return intBitsToFloat(FLT_NAN);
1588         if (finitef(a)) {
1589                 if (finitef(b))
1590                         return a + b;
1591                 else
1592                         return b;
1593         }
1594         else {
1595                 if (finitef(b))
1596                         return a;
1597                 else {
1598                         if (copysignf(1.0, a) == copysignf(1.0, b))
1599                                 return a;
1600                         else
1601                                 return intBitsToFloat(FLT_NAN);
1602                 }
1603         }
1604 }
1605
1606
1607 float builtin_fsub(float a, float b)
1608 {
1609         return builtin_fadd(a, builtin_fneg(b));
1610 }
1611
1612
1613 float builtin_fmul(float a, float b)
1614 {
1615         if (isnanf(a)) return intBitsToFloat(FLT_NAN);
1616         if (isnanf(b)) return intBitsToFloat(FLT_NAN);
1617         if (finitef(a)) {
1618                 if (finitef(b)) return a * b;
1619                 else {
1620                         if (a == 0) return intBitsToFloat(FLT_NAN);
1621                         else return copysignf(b, copysignf(1.0, b)*a);
1622                 }
1623         }
1624         else {
1625                 if (finitef(b)) {
1626                         if (b == 0) return intBitsToFloat(FLT_NAN);
1627                         else return copysignf(a, copysignf(1.0, a)*b);
1628                 }
1629                 else {
1630                         return copysignf(a, copysignf(1.0, a)*copysignf(1.0, b));
1631                 }
1632         }
1633 }
1634
1635
1636 /* builtin_ddiv ****************************************************************
1637
1638    Implementation as described in VM Spec.
1639
1640 *******************************************************************************/
1641
1642 float builtin_fdiv(float a, float b)
1643 {
1644         if (finitef(a)) {
1645                 if (finitef(b)) {
1646                         /* If neither value1' nor value2' is NaN, the sign of the result */
1647                         /* is positive if both values have the same sign, negative if the */
1648                         /* values have different signs. */
1649
1650                         return a / b;
1651
1652                 } else {
1653                         if (isnanf(b)) {
1654                                 /* If either value1' or value2' is NaN, the result is NaN. */
1655
1656                                 return intBitsToFloat(FLT_NAN);
1657
1658                         } else {
1659                                 /* Division of a finite value by an infinity results in a */
1660                                 /* signed zero, with the sign-producing rule just given. */
1661
1662                                 /* is sign equal? */
1663
1664                                 if (copysignf(1.0, a) == copysignf(1.0, b))
1665                                         return 0.0;
1666                                 else
1667                                         return -0.0;
1668                         }
1669                 }
1670
1671         } else {
1672                 if (isnanf(a)) {
1673                         /* If either value1' or value2' is NaN, the result is NaN. */
1674
1675                         return intBitsToFloat(FLT_NAN);
1676
1677                 } else if (finitef(b)) {
1678                         /* Division of an infinity by a finite value results in a signed */
1679                         /* infinity, with the sign-producing rule just given. */
1680
1681                         /* is sign equal? */
1682
1683                         if (copysignf(1.0, a) == copysignf(1.0, b))
1684                                 return intBitsToFloat(FLT_POSINF);
1685                         else
1686                                 return intBitsToFloat(FLT_NEGINF);
1687
1688                 } else {
1689                         /* Division of an infinity by an infinity results in NaN. */
1690
1691                         return intBitsToFloat(FLT_NAN);
1692                 }
1693         }
1694 }
1695
1696
1697 float builtin_fneg(float a)
1698 {
1699         if (isnanf(a)) return a;
1700         else {
1701                 if (finitef(a)) return -a;
1702                 else return copysignf(a, -copysignf(1.0, a));
1703         }
1704 }
1705 #endif /* !SUPPORT_FLOAT */
1706
1707
1708 #if !SUPPORT_FLOAT || !SUPPORT_FLOAT_CMP || defined(ENABLE_INTRP)
1709 s4 builtin_fcmpl(float a, float b)
1710 {
1711         if (isnanf(a))
1712                 return -1;
1713
1714         if (isnanf(b))
1715                 return -1;
1716
1717         if (!finitef(a) || !finitef(b)) {
1718                 a = finitef(a) ? 0 : copysignf(1.0,     a);
1719                 b = finitef(b) ? 0 : copysignf(1.0, b);
1720         }
1721
1722         if (a > b)
1723                 return 1;
1724
1725         if (a == b)
1726                 return 0;
1727
1728         return -1;
1729 }
1730
1731
1732 s4 builtin_fcmpg(float a, float b)
1733 {
1734         if (isnanf(a)) return 1;
1735         if (isnanf(b)) return 1;
1736         if (!finitef(a) || !finitef(b)) {
1737                 a = finitef(a) ? 0 : copysignf(1.0, a);
1738                 b = finitef(b) ? 0 : copysignf(1.0, b);
1739         }
1740         if (a > b) return 1;
1741         if (a == b) return 0;
1742         return -1;
1743 }
1744 #endif /* !SUPPORT_FLOAT || !SUPPORT_FLOAT_CMP || defined(ENABLE_INTRP) */
1745
1746
1747 float builtin_frem(float a, float b)
1748 {
1749         return fmodf(a, b);
1750 }
1751
1752
1753 /* functions for unsupported double instructions ******************************/
1754
1755 #if !SUPPORT_DOUBLE
1756 double builtin_dadd(double a, double b)
1757 {
1758         if (isnan(a)) return longBitsToDouble(DBL_NAN);
1759         if (isnan(b)) return longBitsToDouble(DBL_NAN);
1760         if (finite(a)) {
1761                 if (finite(b)) return a + b;
1762                 else return b;
1763         }
1764         else {
1765                 if (finite(b)) return a;
1766                 else {
1767                         if (copysign(1.0, a)==copysign(1.0, b)) return a;
1768                         else return longBitsToDouble(DBL_NAN);
1769                 }
1770         }
1771 }
1772
1773
1774 double builtin_dsub(double a, double b)
1775 {
1776         return builtin_dadd(a, builtin_dneg(b));
1777 }
1778
1779
1780 double builtin_dmul(double a, double b)
1781 {
1782         if (isnan(a)) return longBitsToDouble(DBL_NAN);
1783         if (isnan(b)) return longBitsToDouble(DBL_NAN);
1784         if (finite(a)) {
1785                 if (finite(b)) return a * b;
1786                 else {
1787                         if (a == 0) return longBitsToDouble(DBL_NAN);
1788                         else return copysign(b, copysign(1.0, b) * a);
1789                 }
1790         }
1791         else {
1792                 if (finite(b)) {
1793                         if (b == 0) return longBitsToDouble(DBL_NAN);
1794                         else return copysign(a, copysign(1.0, a) * b);
1795                 }
1796                 else {
1797                         return copysign(a, copysign(1.0, a) * copysign(1.0, b));
1798                 }
1799         }
1800 }
1801
1802
1803 /* builtin_ddiv ****************************************************************
1804
1805    Implementation as described in VM Spec.
1806
1807 *******************************************************************************/
1808
1809 double builtin_ddiv(double a, double b)
1810 {
1811         if (finite(a)) {
1812                 if (finite(b)) {
1813                         /* If neither value1' nor value2' is NaN, the sign of the result */
1814                         /* is positive if both values have the same sign, negative if the */
1815                         /* values have different signs. */
1816
1817                         return a / b;
1818
1819                 } else {
1820                         if (isnan(b)) {
1821                                 /* If either value1' or value2' is NaN, the result is NaN. */
1822
1823                                 return longBitsToDouble(DBL_NAN);
1824
1825                         } else {
1826                                 /* Division of a finite value by an infinity results in a */
1827                                 /* signed zero, with the sign-producing rule just given. */
1828
1829                                 /* is sign equal? */
1830
1831                                 if (copysign(1.0, a) == copysign(1.0, b))
1832                                         return 0.0;
1833                                 else
1834                                         return -0.0;
1835                         }
1836                 }
1837
1838         } else {
1839                 if (isnan(a)) {
1840                         /* If either value1' or value2' is NaN, the result is NaN. */
1841
1842                         return longBitsToDouble(DBL_NAN);
1843
1844                 } else if (finite(b)) {
1845                         /* Division of an infinity by a finite value results in a signed */
1846                         /* infinity, with the sign-producing rule just given. */
1847
1848                         /* is sign equal? */
1849
1850                         if (copysign(1.0, a) == copysign(1.0, b))
1851                                 return longBitsToDouble(DBL_POSINF);
1852                         else
1853                                 return longBitsToDouble(DBL_NEGINF);
1854
1855                 } else {
1856                         /* Division of an infinity by an infinity results in NaN. */
1857
1858                         return longBitsToDouble(DBL_NAN);
1859                 }
1860         }
1861 }
1862
1863
1864 /* builtin_dneg ****************************************************************
1865
1866    Implemented as described in VM Spec.
1867
1868 *******************************************************************************/
1869
1870 double builtin_dneg(double a)
1871 {
1872         if (isnan(a)) {
1873                 /* If the operand is NaN, the result is NaN (recall that NaN has no */
1874                 /* sign). */
1875
1876                 return a;
1877
1878         } else {
1879                 if (finite(a)) {
1880                         /* If the operand is a zero, the result is the zero of opposite */
1881                         /* sign. */
1882
1883                         return -a;
1884
1885                 } else {
1886                         /* If the operand is an infinity, the result is the infinity of */
1887                         /* opposite sign. */
1888
1889                         return copysign(a, -copysign(1.0, a));
1890                 }
1891         }
1892 }
1893 #endif /* !SUPPORT_DOUBLE */
1894
1895
1896 #if !SUPPORT_DOUBLE || !SUPPORT_DOUBLE_CMP || defined(ENABLE_INTRP)
1897 s4 builtin_dcmpl(double a, double b)
1898 {
1899         if (isnan(a))
1900                 return -1;
1901
1902         if (isnan(b))
1903                 return -1;
1904
1905         if (!finite(a) || !finite(b)) {
1906                 a = finite(a) ? 0 : copysign(1.0, a);
1907                 b = finite(b) ? 0 : copysign(1.0, b);
1908         }
1909
1910         if (a > b)
1911                 return 1;
1912
1913         if (a == b)
1914                 return 0;
1915
1916         return -1;
1917 }
1918
1919
1920 s4 builtin_dcmpg(double a, double b)
1921 {
1922         if (isnan(a))
1923                 return 1;
1924
1925         if (isnan(b))
1926                 return 1;
1927
1928         if (!finite(a) || !finite(b)) {
1929                 a = finite(a) ? 0 : copysign(1.0, a);
1930                 b = finite(b) ? 0 : copysign(1.0, b);
1931         }
1932
1933         if (a > b)
1934                 return 1;
1935
1936         if (a == b)
1937                 return 0;
1938
1939         return -1;
1940 }
1941 #endif /* !SUPPORT_DOUBLE || !SUPPORT_DOUBLE_CMP || defined(ENABLE_INTRP) */
1942
1943
1944 double builtin_drem(double a, double b)
1945 {
1946         return fmod(a, b);
1947 }
1948
1949
1950 /* conversion operations ******************************************************/
1951
1952 #if !(SUPPORT_FLOAT && SUPPORT_I2F)
1953 float builtin_i2f(s4 a)
1954 {
1955         float f = (float) a;
1956         return f;
1957 }
1958 #endif /* !(SUPPORT_FLOAT && SUPPORT_I2F) */
1959
1960
1961 #if !(SUPPORT_DOUBLE && SUPPORT_I2D)
1962 double builtin_i2d(s4 a)
1963 {
1964         double d = (double) a;
1965         return d;
1966 }
1967 #endif /* !(SUPPORT_DOUBLE && SUPPORT_I2D) */
1968
1969
1970 #if !(SUPPORT_LONG && SUPPORT_FLOAT && SUPPORT_L2F)
1971 float builtin_l2f(s8 a)
1972 {
1973         float f = (float) a;
1974         return f;
1975 }
1976 #endif /* !(SUPPORT_LONG && SUPPORT_FLOAT && SUPPORT_L2F) */
1977
1978
1979 #if !(SUPPORT_LONG && SUPPORT_DOUBLE && SUPPORT_L2D)
1980 double builtin_l2d(s8 a)
1981 {
1982         double d = (double) a;
1983         return d;
1984 }
1985 #endif /* !(SUPPORT_LONG && SUPPORT_DOUBLE && SUPPORT_L2D) */
1986
1987
1988 #if !(SUPPORT_FLOAT && SUPPORT_F2I) || defined(ENABLE_INTRP) || defined(DISABLE_GC)
1989 s4 builtin_f2i(float a) 
1990 {
1991         s4 i;
1992
1993         i = builtin_d2i((double) a);
1994
1995         return i;
1996
1997         /*      float f;
1998         
1999                 if (isnanf(a))
2000                 return 0;
2001                 if (finitef(a)) {
2002                 if (a > 2147483647)
2003                 return 2147483647;
2004                 if (a < (-2147483648))
2005                 return (-2147483648);
2006                 return (s4) a;
2007                 }
2008                 f = copysignf((float) 1.0, a);
2009                 if (f > 0)
2010                 return 2147483647;
2011                 return (-2147483648); */
2012 }
2013 #endif /* !(SUPPORT_FLOAT && SUPPORT_F2I) || defined(ENABLE_INTRP) || defined(DISABLE_GC) */
2014
2015
2016 #if !(SUPPORT_FLOAT && SUPPORT_LONG && SUPPORT_F2L) || defined(DISABLE_GC)
2017 s8 builtin_f2l(float a)
2018 {
2019         s8 l;
2020
2021         l = builtin_d2l((double) a);
2022
2023         return l;
2024
2025         /*      float f;
2026         
2027                 if (finitef(a)) {
2028                 if (a > 9223372036854775807L)
2029                 return 9223372036854775807L;
2030                 if (a < (-9223372036854775808L))
2031                 return (-9223372036854775808L);
2032                 return (s8) a;
2033                 }
2034                 if (isnanf(a))
2035                 return 0;
2036                 f = copysignf((float) 1.0, a);
2037                 if (f > 0)
2038                 return 9223372036854775807L;
2039                 return (-9223372036854775808L); */
2040 }
2041 #endif /* !(SUPPORT_FLOAT && SUPPORT_LONG && SUPPORT_F2L) */
2042
2043
2044 #if !(SUPPORT_DOUBLE && SUPPORT_D2I) || defined(ENABLE_INTRP) || defined(DISABLE_GC)
2045 s4 builtin_d2i(double a) 
2046
2047         double d;
2048         
2049         if (finite(a)) {
2050                 if (a >= 2147483647)
2051                         return 2147483647;
2052                 if (a <= (-2147483647-1))
2053                         return (-2147483647-1);
2054                 return (s4) a;
2055         }
2056         if (isnan(a))
2057                 return 0;
2058         d = copysign(1.0, a);
2059         if (d > 0)
2060                 return 2147483647;
2061         return (-2147483647-1);
2062 }
2063 #endif /* !(SUPPORT_DOUBLE && SUPPORT_D2I) || defined(ENABLE_INTRP) || defined(DISABLE_GC) */
2064
2065
2066 #if !(SUPPORT_DOUBLE && SUPPORT_LONG && SUPPORT_D2L) || defined(DISABLE_GC)
2067 s8 builtin_d2l(double a)
2068 {
2069         double d;
2070         
2071         if (finite(a)) {
2072                 if (a >= 9223372036854775807LL)
2073                         return 9223372036854775807LL;
2074                 if (a <= (-9223372036854775807LL-1))
2075                         return (-9223372036854775807LL-1);
2076                 return (s8) a;
2077         }
2078         if (isnan(a))
2079                 return 0;
2080         d = copysign(1.0, a);
2081         if (d > 0)
2082                 return 9223372036854775807LL;
2083         return (-9223372036854775807LL-1);
2084 }
2085 #endif /* !(SUPPORT_DOUBLE && SUPPORT_LONG && SUPPORT_D2L) */
2086
2087
2088 #if !(SUPPORT_FLOAT && SUPPORT_DOUBLE)
2089 double builtin_f2d(float a)
2090 {
2091         if (finitef(a)) return (double) a;
2092         else {
2093                 if (isnanf(a))
2094                         return longBitsToDouble(DBL_NAN);
2095                 else
2096                         return copysign(longBitsToDouble(DBL_POSINF), (double) copysignf(1.0, a) );
2097         }
2098 }
2099
2100 float builtin_d2f(double a)
2101 {
2102         if (finite(a))
2103                 return (float) a;
2104         else {
2105                 if (isnan(a))
2106                         return intBitsToFloat(FLT_NAN);
2107                 else
2108                         return copysignf(intBitsToFloat(FLT_POSINF), (float) copysign(1.0, a));
2109         }
2110 }
2111 #endif /* !(SUPPORT_FLOAT && SUPPORT_DOUBLE) */
2112
2113
2114 /*============================================================================*/
2115 /* AUTOMATICALLY REPLACED FUNCTIONS                                           */
2116 /*============================================================================*/
2117
2118 /* builtin_arraycopy ***********************************************************
2119
2120    Builtin for java.lang.System.arraycopy.
2121
2122    NOTE: This is a SLOW builtin and can be called from JIT & NATIVE code.
2123
2124 *******************************************************************************/
2125
2126 void builtin_arraycopy(java_handle_t *src, s4 srcStart,
2127                                            java_handle_t *dest, s4 destStart, s4 len)
2128 {
2129         arraydescriptor *sdesc;
2130         arraydescriptor *ddesc;
2131         s4               i;
2132
2133         if ((src == NULL) || (dest == NULL)) {
2134                 exceptions_throw_nullpointerexception();
2135                 return;
2136         }
2137
2138         sdesc = LLNI_vftbl_direct(src)->arraydesc;
2139         ddesc = LLNI_vftbl_direct(dest)->arraydesc;
2140
2141         if (!sdesc || !ddesc || (sdesc->arraytype != ddesc->arraytype)) {
2142                 exceptions_throw_arraystoreexception();
2143                 return;
2144         }
2145
2146         // Check if offsets and length are positive.
2147         if ((srcStart < 0) || (destStart < 0) || (len < 0)) {
2148                 exceptions_throw_arrayindexoutofboundsexception();
2149                 return;
2150         }
2151
2152         // Check if ranges are valid.
2153         if ((((uint32_t) srcStart  + (uint32_t) len) > (uint32_t) LLNI_array_size(src)) ||
2154                 (((uint32_t) destStart + (uint32_t) len) > (uint32_t) LLNI_array_size(dest))) {
2155                 exceptions_throw_arrayindexoutofboundsexception();
2156                 return;
2157         }
2158
2159         // Special case.
2160         if (len == 0) {
2161                 return;
2162         }
2163
2164         if (sdesc->componentvftbl == ddesc->componentvftbl) {
2165                 /* We copy primitive values or references of exactly the same type */
2166
2167                 s4 dataoffset = sdesc->dataoffset;
2168                 s4 componentsize = sdesc->componentsize;
2169
2170                 LLNI_CRITICAL_START;
2171
2172                 MMOVE(((u1 *) LLNI_DIRECT(dest)) + dataoffset + componentsize * destStart,
2173                           ((u1 *) LLNI_DIRECT(src))  + dataoffset + componentsize * srcStart,
2174                           u1, (size_t) len * componentsize);
2175
2176                 LLNI_CRITICAL_END;
2177         }
2178         else {
2179                 /* We copy references of different type */
2180
2181                 java_handle_objectarray_t *oas = (java_handle_objectarray_t *) src;
2182                 java_handle_objectarray_t *oad = (java_handle_objectarray_t *) dest;
2183  
2184                 if (destStart <= srcStart) {
2185                         for (i = 0; i < len; i++) {
2186                                 java_handle_t *o;
2187
2188                                 o = array_objectarray_element_get(oas, srcStart + i);
2189
2190                                 if (!builtin_canstore(oad, o))
2191                                         return;
2192
2193                                 array_objectarray_element_set(oad, destStart + i, o);
2194                         }
2195                 }
2196                 else {
2197                         /* XXX this does not completely obey the specification!
2198                            If an exception is thrown only the elements above the
2199                            current index have been copied. The specification
2200                            requires that only the elements *below* the current
2201                            index have been copied before the throw. */
2202
2203                         for (i = len - 1; i >= 0; i--) {
2204                                 java_handle_t *o;
2205
2206                                 o = array_objectarray_element_get(oas, srcStart + i);
2207
2208                                 if (!builtin_canstore(oad, o))
2209                                         return;
2210
2211                                 array_objectarray_element_set(oad, destStart + i, o);
2212                         }
2213                 }
2214         }
2215 }
2216
2217
2218 /* builtin_nanotime ************************************************************
2219
2220    Return the current time in nanoseconds.
2221
2222 *******************************************************************************/
2223
2224 s8 builtin_nanotime(void)
2225 {
2226         struct timeval tv;
2227         s8             usecs;
2228
2229         if (gettimeofday(&tv, NULL) == -1)
2230                 vm_abort("gettimeofday failed: %s", strerror(errno));
2231
2232         usecs = (s8) tv.tv_sec * (1000 * 1000) + (s8) tv.tv_usec;
2233
2234         return usecs * 1000;
2235 }
2236
2237
2238 /* builtin_currenttimemillis ***************************************************
2239
2240    Return the current time in milliseconds.
2241
2242 *******************************************************************************/
2243
2244 s8 builtin_currenttimemillis(void)
2245 {
2246         s8 msecs;
2247
2248         msecs = builtin_nanotime() / 1000 / 1000;
2249
2250         return msecs;
2251 }
2252
2253
2254 /* builtin_clone ***************************************************************
2255
2256    Function for cloning objects or arrays.
2257
2258    NOTE: This is a SLOW builtin and can be called from JIT & NATIVE code.
2259
2260 *******************************************************************************/
2261
2262 java_handle_t *builtin_clone(void *env, java_handle_t *o)
2263 {
2264         arraydescriptor *ad;
2265         u4               size;
2266         classinfo       *c;
2267         java_handle_t   *co;                /* cloned object header               */
2268
2269         /* get the array descriptor */
2270
2271         ad = LLNI_vftbl_direct(o)->arraydesc;
2272
2273         /* we are cloning an array */
2274
2275         if (ad != NULL) {
2276                 size = ad->dataoffset + ad->componentsize * LLNI_array_size(o);
2277         
2278                 co = (java_handle_t*) heap_alloc(size, (ad->arraytype == ARRAYTYPE_OBJECT), NULL, true);
2279
2280                 if (co == NULL)
2281                         return NULL;
2282
2283 #if !defined(ENABLE_GC_CACAO) && defined(ENABLE_HANDLES)
2284                 /* XXX this is only a dirty hack to make Boehm work with handles */
2285
2286                 co = LLNI_WRAP((java_object_t *) co);
2287 #endif
2288
2289                 LLNI_CRITICAL_START;
2290
2291                 MCOPY(LLNI_DIRECT(co), LLNI_DIRECT(o), u1, size);
2292
2293 #if defined(ENABLE_GC_CACAO)
2294                 heap_init_objectheader(LLNI_DIRECT(co), size);
2295 #endif
2296
2297 #if defined(ENABLE_THREADS)
2298                 LLNI_DIRECT(co)->lockword.init();
2299 #endif
2300
2301                 LLNI_CRITICAL_END;
2302
2303                 return co;
2304         }
2305     
2306     /* we are cloning a non-array */
2307
2308     if (!builtin_instanceof(o, class_java_lang_Cloneable)) {
2309         exceptions_throw_clonenotsupportedexception();
2310         return NULL;
2311     }
2312
2313         /* get the class of the object */
2314
2315         LLNI_class_get(o, c);
2316
2317         /* create new object */
2318
2319     co = builtin_new(c);
2320
2321     if (co == NULL)
2322         return NULL;
2323
2324         LLNI_CRITICAL_START;
2325
2326         MCOPY(LLNI_DIRECT(co), LLNI_DIRECT(o), u1, c->instancesize);
2327
2328 #if defined(ENABLE_GC_CACAO)
2329         heap_init_objectheader(LLNI_DIRECT(co), c->instancesize);
2330 #endif
2331
2332 #if defined(ENABLE_THREADS)
2333         LLNI_DIRECT(co)->lockword.init();
2334 #endif
2335
2336         LLNI_CRITICAL_END;
2337
2338     return co;
2339 }
2340
2341
2342 #if defined(ENABLE_CYCLES_STATS)
2343 void builtin_print_cycles_stats(FILE *file)
2344 {
2345         fprintf(file,"builtin cylce count statistics:\n");
2346
2347         CYCLES_STATS_PRINT_OVERHEAD(builtin_overhead,file);
2348         CYCLES_STATS_PRINT(builtin_new         ,file);
2349
2350         fprintf(file,"\n");
2351 }
2352 #endif /* defined(ENABLE_CYCLES_STATS) */
2353
2354
2355 #if defined(ENABLE_VMLOG)
2356 #define NDEBUG
2357 #include <vmlog_cacao.c>
2358 #endif
2359
2360
2361 /*
2362  * These are local overrides for various environment variables in Emacs.
2363  * Please do not remove this and leave it at the end of the file, where
2364  * Emacs will automagically detect them.
2365  * ---------------------------------------------------------------------
2366  * Local variables:
2367  * mode: c++
2368  * indent-tabs-mode: t
2369  * c-basic-offset: 4
2370  * tab-width: 4
2371  * End:
2372  * vim:noexpandtab:sw=4:ts=4:
2373  */