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