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