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