* src/native/jni.h: Removed.
[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.hpp"
51 #include "mm/memory.h"
52
53 #include "native/llni.h"
54
55 #include "threads/lock-common.h"
56 #include "threads/thread.hpp"
57
58 #include "toolbox/logging.h"
59 #include "toolbox/util.h"
60
61 #include "vm/array.h"
62 #include "vm/builtin.h"
63 #include "vm/class.h"
64 #include "vm/cycles-stats.h"
65 #include "vm/exceptions.hpp"
66 #include "vm/global.h"
67 #include "vm/globals.hpp"
68 #include "vm/initialize.h"
69 #include "vm/linker.h"
70 #include "vm/loader.h"
71 #include "vm/options.h"
72 #include "vm/primitive.hpp"
73 #include "vm/rt-timing.h"
74 #include "vm/string.hpp"
75
76 #include "vm/jit/asmpart.h"
77 #include "vm/jit/trace.hpp"
78
79 #if defined(ENABLE_VMLOG)
80 #include <vmlog_cacao.h>
81 #endif
82
83
84 /* include builtin tables *****************************************************/
85
86 #include "vm/builtintable.inc"
87
88
89 CYCLES_STATS_DECLARE(builtin_new         ,100,5)
90 CYCLES_STATS_DECLARE(builtin_overhead    , 80,1)
91
92
93 /*============================================================================*/
94 /* BUILTIN TABLE MANAGEMENT FUNCTIONS                                         */
95 /*============================================================================*/
96
97 /* builtintable_init ***********************************************************
98
99    Parse the descriptors of builtin functions and create the parsed
100    descriptors.
101
102 *******************************************************************************/
103
104 static bool builtintable_init(void)
105 {
106         descriptor_pool    *descpool;
107         builtintable_entry *bte;
108         methodinfo         *m;
109         int32_t             dumpmarker;
110
111         /* mark start of dump memory area */
112
113         DMARKER;
114
115         /* create a new descriptor pool */
116
117         descpool = descriptor_pool_new(class_java_lang_Object);
118
119         /* add some entries we need */
120
121         if (!descriptor_pool_add_class(descpool, utf_java_lang_Object))
122                 return false;
123
124         if (!descriptor_pool_add_class(descpool, utf_java_lang_Class))
125                 return false;
126
127         /* first add all descriptors to the pool */
128
129         for (bte = builtintable_internal; bte->fp != NULL; bte++) {
130                 bte->name       = utf_new_char(bte->cname);
131                 bte->descriptor = utf_new_char(bte->cdescriptor);
132
133                 if (!descriptor_pool_add(descpool, bte->descriptor, NULL)) {
134                         /* release dump area */
135
136                         DRELEASE;
137
138                         return false;
139                 }
140         }
141
142         for (bte = builtintable_automatic; bte->fp != NULL; bte++) {
143                 bte->descriptor = utf_new_char(bte->cdescriptor);
144
145                 if (!descriptor_pool_add(descpool, bte->descriptor, NULL)) {
146                         DRELEASE;
147                         return false;
148                 }
149         }
150
151         for (bte = builtintable_function; bte->fp != NULL; bte++) {
152                 bte->classname  = utf_new_char(bte->cclassname);
153                 bte->name       = utf_new_char(bte->cname);
154                 bte->descriptor = utf_new_char(bte->cdescriptor);
155
156                 if (!descriptor_pool_add(descpool, bte->descriptor, NULL)) {
157                         DRELEASE;
158                         return false;
159                 }
160         }
161
162         /* create the class reference table */
163
164         (void) descriptor_pool_create_classrefs(descpool, NULL);
165
166         /* allocate space for the parsed descriptors */
167
168         descriptor_pool_alloc_parsed_descriptors(descpool);
169
170         /* Now parse all descriptors.  NOTE: builtin-functions are treated
171            like static methods (no `this' pointer). */
172
173         for (bte = builtintable_internal; bte->fp != NULL; bte++) {
174                 bte->md =
175                         descriptor_pool_parse_method_descriptor(descpool,
176                                                                                                         bte->descriptor,
177                                                                                                         ACC_STATIC | ACC_METHOD_BUILTIN,
178                                                                                                         NULL);
179
180                 /* generate a builtin stub if we need one */
181
182                 if (bte->flags & BUILTINTABLE_FLAG_STUB) {
183                         m = method_new_builtin(bte);
184                         codegen_generate_stub_builtin(m, bte);
185                 }
186         }
187
188         for (bte = builtintable_automatic; bte->fp != NULL; bte++) {
189                 bte->md =
190                         descriptor_pool_parse_method_descriptor(descpool,
191                                                                                                         bte->descriptor,
192                                                                                                         ACC_STATIC | ACC_METHOD_BUILTIN,
193                                                                                                         NULL);
194
195                 /* no stubs should be needed for this table */
196
197                 assert(!bte->flags & BUILTINTABLE_FLAG_STUB);
198         }
199
200         for (bte = builtintable_function; bte->fp != NULL; bte++) {
201                 bte->md =
202                         descriptor_pool_parse_method_descriptor(descpool,
203                                                                                                         bte->descriptor,
204                                                                                                         ACC_STATIC | ACC_METHOD_BUILTIN,
205                                                                                                         NULL);
206
207                 /* generate a builtin stub if we need one */
208
209                 if (bte->flags & BUILTINTABLE_FLAG_STUB) {
210                         m = method_new_builtin(bte);
211                         codegen_generate_stub_builtin(m, bte);
212                 }
213         }
214
215         /* release dump area */
216
217         DRELEASE;
218
219         return true;
220 }
221
222
223 /* builtintable_comparator *****************************************************
224
225    qsort comparator for the automatic builtin table.
226
227 *******************************************************************************/
228
229 static int builtintable_comparator(const void *a, const void *b)
230 {
231         builtintable_entry *bte1;
232         builtintable_entry *bte2;
233
234         bte1 = (builtintable_entry *) a;
235         bte2 = (builtintable_entry *) b;
236
237         return (bte1->opcode < bte2->opcode) ? -1 : (bte1->opcode > bte2->opcode);
238 }
239
240
241 /* builtintable_sort_automatic *************************************************
242
243    Sorts the automatic builtin table.
244
245 *******************************************************************************/
246
247 static void builtintable_sort_automatic(void)
248 {
249         s4 entries;
250
251         /* calculate table size statically (`- 1' comment see builtintable.inc) */
252
253         entries = sizeof(builtintable_automatic) / sizeof(builtintable_entry) - 1;
254
255         qsort(builtintable_automatic, entries, sizeof(builtintable_entry),
256                   builtintable_comparator);
257 }
258
259
260 /* builtin_init ****************************************************************
261
262    Initialize the global table of builtin functions.
263
264 *******************************************************************************/
265
266 bool builtin_init(void)
267 {
268         TRACESUBSYSTEMINITIALIZATION("builtin_init");
269
270         /* initialize the builtin tables */
271
272         if (!builtintable_init())
273                 return false;
274
275         /* sort builtin tables */
276
277         builtintable_sort_automatic();
278
279         return true;
280 }
281
282
283 /* builtintable_get_internal ***************************************************
284
285    Finds an entry in the builtintable for internal functions and
286    returns the a pointer to the structure.
287
288 *******************************************************************************/
289
290 builtintable_entry *builtintable_get_internal(functionptr fp)
291 {
292         builtintable_entry *bte;
293
294         for (bte = builtintable_internal; bte->fp != NULL; bte++) {
295                 if (bte->fp == fp)
296                         return bte;
297         }
298
299         return NULL;
300 }
301
302
303 /* builtintable_get_automatic **************************************************
304
305    Finds an entry in the builtintable for functions which are replaced
306    automatically and returns the a pointer to the structure.
307
308 *******************************************************************************/
309
310 builtintable_entry *builtintable_get_automatic(s4 opcode)
311 {
312         builtintable_entry *first;
313         builtintable_entry *last;
314         builtintable_entry *middle;
315         s4                  half;
316         s4                  entries;
317
318         /* calculate table size statically (`- 1' comment see builtintable.inc) */
319
320         entries = sizeof(builtintable_automatic) / sizeof(builtintable_entry) - 1;
321
322         first = builtintable_automatic;
323         last = builtintable_automatic + entries;
324
325         while (entries > 0) {
326                 half = entries / 2;
327                 middle = first + half;
328
329                 if (middle->opcode < opcode) {
330                         first = middle + 1;
331                         entries -= half + 1;
332                 }
333                 else
334                         entries = half;
335         }
336
337         return (first != last ? first : NULL);
338 }
339
340
341 /* builtintable_replace_function ***********************************************
342
343    XXX
344
345 *******************************************************************************/
346
347 #if defined(ENABLE_JIT)
348 bool builtintable_replace_function(void *iptr_)
349 {
350         constant_FMIref    *mr;
351         builtintable_entry *bte;
352         instruction        *iptr;
353
354         iptr = (instruction *) iptr_; /* twisti will kill me ;) */
355
356         /* get name and descriptor of the function */
357
358         switch (iptr->opc) {
359         case ICMD_INVOKESTATIC:
360                 /* The instruction MUST be resolved, otherwise we run into
361                    lazy loading troubles.  Anyway, we should/can only replace
362                    very VM-close functions. */
363
364                 if (INSTRUCTION_IS_UNRESOLVED(iptr))
365                         return false;
366
367                 mr = iptr->sx.s23.s3.fmiref;
368                 break;  
369
370         default:
371                 return false;
372         }
373
374         /* search the function table */
375
376         for (bte = builtintable_function; bte->fp != NULL; bte++) {
377                 if ((METHODREF_CLASSNAME(mr) == bte->classname) &&
378                         (mr->name                == bte->name) &&
379                         (mr->descriptor          == bte->descriptor)) {
380
381                         /* set the values in the instruction */
382
383                         iptr->opc           = bte->opcode;
384                         iptr->sx.s23.s3.bte = bte;
385
386                         if (bte->flags & BUILTINTABLE_FLAG_EXCEPTION)
387                                 iptr->flags.bits |= INS_FLAG_CHECK;
388                         else
389                                 iptr->flags.bits &= ~INS_FLAG_CHECK;
390
391                         return true;
392                 }
393         }
394
395         return false;
396 }
397 #endif /* defined(ENABLE_JIT) */
398
399
400 /*============================================================================*/
401 /* INTERNAL BUILTIN FUNCTIONS                                                 */
402 /*============================================================================*/
403
404 /* builtin_instanceof **********************************************************
405
406    Checks if an object is an instance of some given class (or subclass
407    of that class). If class is an interface, checks if the interface
408    is implemented.
409
410    RETURN VALUE:
411      1......o is an instance of class or implements the interface
412      0......otherwise or if o == NULL
413
414    NOTE: This builtin can be called from NATIVE code only.
415
416 *******************************************************************************/
417
418 bool builtin_instanceof(java_handle_t *o, classinfo *c)
419 {
420         classinfo *oc;
421
422         if (o == NULL)
423                 return 0;
424
425         LLNI_class_get(o, oc);
426
427         return class_isanysubclass(oc, c);
428 }
429
430
431
432 /* builtin_checkcast ***********************************************************
433
434    The same as builtin_instanceof but with the exception
435    that 1 is returned when (o == NULL).
436
437    NOTE: This builtin can be called from NATIVE code only.
438
439 *******************************************************************************/
440
441 bool builtin_checkcast(java_handle_t *o, classinfo *c)
442 {
443         classinfo *oc;
444
445         if (o == NULL)
446                 return 1;
447
448         LLNI_class_get(o, oc);
449
450         if (class_isanysubclass(oc, c))
451                 return 1;
452
453         return 0;
454 }
455
456
457 /* builtin_descriptorscompatible ***********************************************
458
459    Checks if two array type descriptors are assignment compatible.
460
461    RETURN VALUE:
462       1......target = desc is possible
463       0......otherwise
464                         
465 *******************************************************************************/
466
467 static bool builtin_descriptorscompatible(arraydescriptor *desc, arraydescriptor *target)
468 {
469         if (desc == target)
470                 return 1;
471
472         if (desc->arraytype != target->arraytype)
473                 return 0;
474
475         if (desc->arraytype != ARRAYTYPE_OBJECT)
476                 return 1;
477         
478         /* {both arrays are arrays of references} */
479
480         if (desc->dimension == target->dimension) {
481                 if (!desc->elementvftbl)
482                         return 0;
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->clazz,
491                                                                    target->elementvftbl->clazz);
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->clazz);
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 bool 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 bool 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 bool builtin_arrayinstanceof(java_handle_t *h, classinfo *targetclass)
557 {
558         bool 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_retrieve_exception **************************************************
601
602    Gets and clears the exception pointer of the current thread.
603
604    RETURN VALUE:
605       the exception object, or NULL if no exception was thrown.
606
607    NOTE: This is a FAST builtin and can be called from JIT code,
608    or from the signal handlers.
609
610 *******************************************************************************/
611
612 java_object_t *builtin_retrieve_exception(void)
613 {
614         java_handle_t *h;
615         java_object_t *o;
616
617         /* actually get and clear the exception */
618
619         h = exceptions_get_and_clear_exception();
620         o = LLNI_UNWRAP(h);
621
622         return o;
623 }
624
625
626 /* builtin_canstore ************************************************************
627
628    Checks, if an object can be stored in an array.
629
630    RETURN VALUE:
631       1......possible
632       0......otherwise (throws an ArrayStoreException)
633
634    NOTE: This is a SLOW builtin and can be called from JIT & NATIVE code.
635
636 *******************************************************************************/
637
638 bool builtin_canstore(java_handle_objectarray_t *oa, java_handle_t *o)
639 {
640         bool result;
641
642         LLNI_CRITICAL_START;
643
644         result = builtin_fast_canstore(LLNI_DIRECT(oa), LLNI_UNWRAP(o));
645
646         LLNI_CRITICAL_END;
647
648         /* if not possible, throw an exception */
649
650         if (result == 0)
651                 exceptions_throw_arraystoreexception();
652
653         return result;
654 }
655
656
657 /* builtin_fast_canstore *******************************************************
658
659    Checks, if an object can be stored in an array.
660
661    RETURN VALUE:
662       1......possible
663       0......otherwise (no exception thrown!)
664
665    NOTE: This is a FAST builtin and can be called from JIT code only.
666
667 *******************************************************************************/
668
669 bool builtin_fast_canstore(java_objectarray_t *oa, java_object_t *o)
670 {
671         arraydescriptor *desc;
672         arraydescriptor *valuedesc;
673         vftbl_t         *componentvftbl;
674         vftbl_t         *valuevftbl;
675         int32_t          baseval;
676         uint32_t         diffval;
677         bool             result;
678
679         if (o == NULL)
680                 return 1;
681
682         /* The following is guaranteed (by verifier checks):
683          *
684          *     *) oa->...vftbl->arraydesc != NULL
685          *     *) oa->...vftbl->arraydesc->componentvftbl != NULL
686          *     *) o->vftbl is not an interface vftbl
687          */
688
689         desc           = oa->header.objheader.vftbl->arraydesc;
690         componentvftbl = desc->componentvftbl;
691         valuevftbl     = o->vftbl;
692         valuedesc      = valuevftbl->arraydesc;
693
694         if ((desc->dimension - 1) == 0) {
695                 /* {oa is a one-dimensional array} */
696                 /* {oa is an array of references} */
697                 
698                 if (valuevftbl == componentvftbl)
699                         return 1;
700
701                 LOCK_MONITOR_ENTER(linker_classrenumber_lock);
702
703                 baseval = componentvftbl->baseval;
704
705                 if (baseval <= 0) {
706                         /* an array of interface references */
707
708                         result = ((valuevftbl->interfacetablelength > -baseval) &&
709                                           (valuevftbl->interfacetable[baseval] != NULL));
710                 }
711                 else {
712                         diffval = valuevftbl->baseval - componentvftbl->baseval;
713                         result  = diffval <= (uint32_t) componentvftbl->diffval;
714                 }
715
716                 LOCK_MONITOR_EXIT(linker_classrenumber_lock);
717         }
718         else if (valuedesc == NULL) {
719                 /* {oa has dimension > 1} */
720                 /* {componentvftbl->arraydesc != NULL} */
721
722                 /* check if o is an array */
723
724                 return 0;
725         }
726         else {
727                 /* {o is an array} */
728
729                 result = builtin_descriptorscompatible(valuedesc, componentvftbl->arraydesc);
730         }
731
732         /* return result */
733
734         return result;
735 }
736
737
738 /* This is an optimized version where a is guaranteed to be one-dimensional */
739 bool builtin_fast_canstore_onedim(java_objectarray_t *a, java_object_t *o)
740 {
741         arraydescriptor *desc;
742         vftbl_t         *elementvftbl;
743         vftbl_t         *valuevftbl;
744         int32_t          baseval;
745         uint32_t         diffval;
746         bool             result;
747         
748         if (o == NULL)
749                 return 1;
750
751         /* The following is guaranteed (by verifier checks):
752          *
753          *     *) a->...vftbl->arraydesc != NULL
754          *     *) a->...vftbl->arraydesc->elementvftbl != NULL
755          *     *) a->...vftbl->arraydesc->dimension == 1
756          *     *) o->vftbl is not an interface vftbl
757          */
758
759         desc = a->header.objheader.vftbl->arraydesc;
760     elementvftbl = desc->elementvftbl;
761         valuevftbl = o->vftbl;
762
763         /* {a is a one-dimensional array} */
764         
765         if (valuevftbl == elementvftbl)
766                 return 1;
767
768         LOCK_MONITOR_ENTER(linker_classrenumber_lock);
769
770         baseval = elementvftbl->baseval;
771
772         if (baseval <= 0) {
773                 /* an array of interface references */
774                 result = ((valuevftbl->interfacetablelength > -baseval) &&
775                                   (valuevftbl->interfacetable[baseval] != NULL));
776         }
777         else {
778                 diffval = valuevftbl->baseval - elementvftbl->baseval;
779                 result  = diffval <= (uint32_t) elementvftbl->diffval;
780         }
781
782         LOCK_MONITOR_EXIT(linker_classrenumber_lock);
783
784         return result;
785 }
786
787
788 /* This is an optimized version where a is guaranteed to be a
789  * one-dimensional array of a class type */
790 bool builtin_fast_canstore_onedim_class(java_objectarray_t *a, java_object_t *o)
791 {
792         vftbl_t  *elementvftbl;
793         vftbl_t  *valuevftbl;
794         uint32_t  diffval;
795         bool      result;
796         
797         if (o == NULL)
798                 return 1;
799
800         /* The following is guaranteed (by verifier checks):
801          *
802          *     *) a->...vftbl->arraydesc != NULL
803          *     *) a->...vftbl->arraydesc->elementvftbl != NULL
804          *     *) a->...vftbl->arraydesc->elementvftbl is not an interface vftbl
805          *     *) a->...vftbl->arraydesc->dimension == 1
806          *     *) o->vftbl is not an interface vftbl
807          */
808
809     elementvftbl = a->header.objheader.vftbl->arraydesc->elementvftbl;
810         valuevftbl = o->vftbl;
811
812         /* {a is a one-dimensional array} */
813         
814         if (valuevftbl == elementvftbl)
815                 return 1;
816
817         LOCK_MONITOR_ENTER(linker_classrenumber_lock);
818
819         diffval = valuevftbl->baseval - elementvftbl->baseval;
820         result  = diffval <= (uint32_t) elementvftbl->diffval;
821
822         LOCK_MONITOR_EXIT(linker_classrenumber_lock);
823
824         return result;
825 }
826
827
828 /* builtin_new *****************************************************************
829
830    Creates a new instance of class c on the heap.
831
832    RETURN VALUE:
833       pointer to the object, or NULL if no memory is available
834
835    NOTE: This builtin can be called from NATIVE code only.
836
837 *******************************************************************************/
838
839 java_handle_t *builtin_new(classinfo *c)
840 {
841         java_handle_t *o;
842 #if defined(ENABLE_RT_TIMING)
843         struct timespec time_start, time_end;
844 #endif
845 #if defined(ENABLE_CYCLES_STATS)
846         u8 cycles_start, cycles_end;
847 #endif
848
849         RT_TIMING_GET_TIME(time_start);
850         CYCLES_STATS_GET(cycles_start);
851
852         /* is the class loaded */
853
854         assert(c->state & CLASS_LOADED);
855
856         /* check if we can instantiate this class */
857
858         if (c->flags & ACC_ABSTRACT) {
859                 exceptions_throw_instantiationerror(c);
860                 return NULL;
861         }
862
863         /* is the class linked */
864
865         if (!(c->state & CLASS_LINKED))
866                 if (!link_class(c))
867                         return NULL;
868
869         if (!(c->state & CLASS_INITIALIZED)) {
870 #if !defined(NDEBUG)
871                 if (initverbose)
872                         log_message_class("Initialize class (from builtin_new): ", c);
873 #endif
874
875                 if (!initialize_class(c))
876                         return NULL;
877         }
878
879         o = heap_alloc(c->instancesize, c->flags & ACC_CLASS_HAS_POINTERS,
880                                    c->finalizer, true);
881
882         if (!o)
883                 return NULL;
884
885 #if !defined(ENABLE_GC_CACAO) && defined(ENABLE_HANDLES)
886         /* XXX this is only a dirty hack to make Boehm work with handles */
887
888         o = LLNI_WRAP((java_object_t *) o);
889 #endif
890
891         LLNI_vftbl_direct(o) = c->vftbl;
892
893 #if defined(ENABLE_THREADS)
894         lock_init_object_lock(LLNI_DIRECT(o));
895 #endif
896
897         CYCLES_STATS_GET(cycles_end);
898         RT_TIMING_GET_TIME(time_end);
899
900         CYCLES_STATS_COUNT(builtin_new,cycles_end - cycles_start);
901         RT_TIMING_TIME_DIFF(time_start, time_end, RT_TIMING_NEW_OBJECT);
902
903         return o;
904 }
905
906 #if defined(ENABLE_ESCAPE_REASON)
907 java_handle_t *builtin_escape_reason_new(classinfo *c) {
908         print_escape_reasons();
909         return builtin_java_new(c);
910 }
911 #endif
912
913 #if defined(ENABLE_TLH)
914 java_handle_t *builtin_tlh_new(classinfo *c)
915 {
916         java_handle_t *o;
917 # if defined(ENABLE_RT_TIMING)
918         struct timespec time_start, time_end;
919 # endif
920 # if defined(ENABLE_CYCLES_STATS)
921         u8 cycles_start, cycles_end;
922 # endif
923
924         RT_TIMING_GET_TIME(time_start);
925         CYCLES_STATS_GET(cycles_start);
926
927         /* is the class loaded */
928
929         assert(c->state & CLASS_LOADED);
930
931         /* check if we can instantiate this class */
932
933         if (c->flags & ACC_ABSTRACT) {
934                 exceptions_throw_instantiationerror(c);
935                 return NULL;
936         }
937
938         /* is the class linked */
939
940         if (!(c->state & CLASS_LINKED))
941                 if (!link_class(c))
942                         return NULL;
943
944         if (!(c->state & CLASS_INITIALIZED)) {
945 # if !defined(NDEBUG)
946                 if (initverbose)
947                         log_message_class("Initialize class (from builtin_new): ", c);
948 # endif
949
950                 if (!initialize_class(c))
951                         return NULL;
952         }
953
954         /*
955         o = tlh_alloc(&(THREADOBJECT->tlh), c->instancesize);
956         */
957         o = NULL;
958
959         if (o == NULL) {
960                 o = heap_alloc(c->instancesize, c->flags & ACC_CLASS_HAS_POINTERS,
961                                            c->finalizer, true);
962         }
963
964         if (!o)
965                 return NULL;
966
967 # if !defined(ENABLE_GC_CACAO) && defined(ENABLE_HANDLES)
968         /* XXX this is only a dirty hack to make Boehm work with handles */
969
970         o = LLNI_WRAP((java_object_t *) o);
971 # endif
972
973         LLNI_vftbl_direct(o) = c->vftbl;
974
975 # if defined(ENABLE_THREADS)
976         lock_init_object_lock(LLNI_DIRECT(o));
977 # endif
978
979         CYCLES_STATS_GET(cycles_end);
980         RT_TIMING_GET_TIME(time_end);
981
982 /*
983         CYCLES_STATS_COUNT(builtin_new,cycles_end - cycles_start);
984         RT_TIMING_TIME_DIFF(time_start, time_end, RT_TIMING_NEW_OBJECT);
985 */
986
987         return o;
988 }
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  */