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