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