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