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