261 default:
262 fatal("BarrierSet AccessBarrier resolving not implemented");
263 return NULL;
264 };
265 }
266
267 static FunctionPointerT resolve_barrier_rt() {
268 if (UseCompressedOops) {
269 const DecoratorSet expanded_decorators = decorators | INTERNAL_RT_USE_COMPRESSED_OOPS;
270 return resolve_barrier_gc<expanded_decorators>();
271 } else {
272 return resolve_barrier_gc<decorators>();
273 }
274 }
275
276 static FunctionPointerT resolve_barrier() {
277 return resolve_barrier_rt();
278 }
279 };
280
281 // Step 4: Runtime dispatch
282 // The RuntimeDispatch class is responsible for performing a runtime dispatch of the
283 // accessor. This is required when the access either depends on whether compressed oops
284 // is being used, or it depends on which GC implementation was chosen (e.g. requires GC
285 // barriers). The way it works is that a function pointer initially pointing to an
286 // accessor resolution function gets called for each access. Upon first invocation,
287 // it resolves which accessor to be used in future invocations and patches the
288 // function pointer to this new accessor.
289
290 template <DecoratorSet decorators, typename T, BarrierType type>
291 struct RuntimeDispatch: AllStatic {};
292
293 template <DecoratorSet decorators, typename T>
294 struct RuntimeDispatch<decorators, T, BARRIER_STORE>: AllStatic {
295 typedef typename AccessFunction<decorators, T, BARRIER_STORE>::type func_t;
296 static func_t _store_func;
297
298 static void store_init(void* addr, T value) {
299 func_t function = BarrierResolver<decorators, func_t, BARRIER_STORE>::resolve_barrier();
300 _store_func = function;
301 function(addr, value);
302 }
303
304 static inline void store(void* addr, T value) {
305 _store_func(addr, value);
306 }
307 };
308
309 template <DecoratorSet decorators, typename T>
310 struct RuntimeDispatch<decorators, T, BARRIER_STORE_AT>: AllStatic {
311 typedef typename AccessFunction<decorators, T, BARRIER_STORE_AT>::type func_t;
312 static func_t _store_at_func;
313
314 static void store_at_init(oop base, ptrdiff_t offset, T value) {
315 func_t function = BarrierResolver<decorators, func_t, BARRIER_STORE_AT>::resolve_barrier();
316 _store_at_func = function;
317 function(base, offset, value);
318 }
319
320 static inline void store_at(oop base, ptrdiff_t offset, T value) {
321 _store_at_func(base, offset, value);
322 }
323 };
324
325 template <DecoratorSet decorators, typename T>
326 struct RuntimeDispatch<decorators, T, BARRIER_LOAD>: AllStatic {
327 typedef typename AccessFunction<decorators, T, BARRIER_LOAD>::type func_t;
328 static func_t _load_func;
329
330 static T load_init(void* addr) {
331 func_t function = BarrierResolver<decorators, func_t, BARRIER_LOAD>::resolve_barrier();
332 _load_func = function;
333 return function(addr);
334 }
335
336 static inline T load(void* addr) {
337 return _load_func(addr);
338 }
339 };
340
341 template <DecoratorSet decorators, typename T>
342 struct RuntimeDispatch<decorators, T, BARRIER_LOAD_AT>: AllStatic {
343 typedef typename AccessFunction<decorators, T, BARRIER_LOAD_AT>::type func_t;
344 static func_t _load_at_func;
345
346 static T load_at_init(oop base, ptrdiff_t offset) {
347 func_t function = BarrierResolver<decorators, func_t, BARRIER_LOAD_AT>::resolve_barrier();
348 _load_at_func = function;
349 return function(base, offset);
350 }
351
352 static inline T load_at(oop base, ptrdiff_t offset) {
353 return _load_at_func(base, offset);
354 }
355 };
356
357 template <DecoratorSet decorators, typename T>
358 struct RuntimeDispatch<decorators, T, BARRIER_ATOMIC_CMPXCHG>: AllStatic {
359 typedef typename AccessFunction<decorators, T, BARRIER_ATOMIC_CMPXCHG>::type func_t;
360 static func_t _atomic_cmpxchg_func;
361
362 static T atomic_cmpxchg_init(T new_value, void* addr, T compare_value) {
363 func_t function = BarrierResolver<decorators, func_t, BARRIER_ATOMIC_CMPXCHG>::resolve_barrier();
364 _atomic_cmpxchg_func = function;
365 return function(new_value, addr, compare_value);
366 }
367
368 static inline T atomic_cmpxchg(T new_value, void* addr, T compare_value) {
369 return _atomic_cmpxchg_func(new_value, addr, compare_value);
370 }
371 };
372
373 template <DecoratorSet decorators, typename T>
374 struct RuntimeDispatch<decorators, T, BARRIER_ATOMIC_CMPXCHG_AT>: AllStatic {
375 typedef typename AccessFunction<decorators, T, BARRIER_ATOMIC_CMPXCHG_AT>::type func_t;
376 static func_t _atomic_cmpxchg_at_func;
377
378 static T atomic_cmpxchg_at_init(T new_value, oop base, ptrdiff_t offset, T compare_value) {
379 func_t function = BarrierResolver<decorators, func_t, BARRIER_ATOMIC_CMPXCHG_AT>::resolve_barrier();
380 _atomic_cmpxchg_at_func = function;
381 return function(new_value, base, offset, compare_value);
382 }
383
384 static inline T atomic_cmpxchg_at(T new_value, oop base, ptrdiff_t offset, T compare_value) {
385 return _atomic_cmpxchg_at_func(new_value, base, offset, compare_value);
386 }
387 };
388
389 template <DecoratorSet decorators, typename T>
390 struct RuntimeDispatch<decorators, T, BARRIER_ATOMIC_XCHG>: AllStatic {
391 typedef typename AccessFunction<decorators, T, BARRIER_ATOMIC_XCHG>::type func_t;
392 static func_t _atomic_xchg_func;
393
394 static T atomic_xchg_init(T new_value, void* addr) {
395 func_t function = BarrierResolver<decorators, func_t, BARRIER_ATOMIC_XCHG>::resolve_barrier();
396 _atomic_xchg_func = function;
397 return function(new_value, addr);
398 }
399
400 static inline T atomic_xchg(T new_value, void* addr) {
401 return _atomic_xchg_func(new_value, addr);
402 }
403 };
404
405 template <DecoratorSet decorators, typename T>
406 struct RuntimeDispatch<decorators, T, BARRIER_ATOMIC_XCHG_AT>: AllStatic {
407 typedef typename AccessFunction<decorators, T, BARRIER_ATOMIC_XCHG_AT>::type func_t;
408 static func_t _atomic_xchg_at_func;
409
410 static T atomic_xchg_at_init(T new_value, oop base, ptrdiff_t offset) {
411 func_t function = BarrierResolver<decorators, func_t, BARRIER_ATOMIC_XCHG_AT>::resolve_barrier();
412 _atomic_xchg_at_func = function;
413 return function(new_value, base, offset);
414 }
415
416 static inline T atomic_xchg_at(T new_value, oop base, ptrdiff_t offset) {
417 return _atomic_xchg_at_func(new_value, base, offset);
418 }
419 };
420
421 template <DecoratorSet decorators, typename T>
422 struct RuntimeDispatch<decorators, T, BARRIER_ARRAYCOPY>: AllStatic {
423 typedef typename AccessFunction<decorators, T, BARRIER_ARRAYCOPY>::type func_t;
424 static func_t _arraycopy_func;
425
426 static bool arraycopy_init(arrayOop src_obj, arrayOop dst_obj, T *src, T* dst, size_t length) {
427 func_t function = BarrierResolver<decorators, func_t, BARRIER_ARRAYCOPY>::resolve_barrier();
428 _arraycopy_func = function;
429 return function(src_obj, dst_obj, src, dst, length);
430 }
431
432 static inline bool arraycopy(arrayOop src_obj, arrayOop dst_obj, T *src, T* dst, size_t length) {
433 return _arraycopy_func(src_obj, dst_obj, src, dst, length);
434 }
435 };
436
437 template <DecoratorSet decorators, typename T>
438 struct RuntimeDispatch<decorators, T, BARRIER_CLONE>: AllStatic {
439 typedef typename AccessFunction<decorators, T, BARRIER_CLONE>::type func_t;
440 static func_t _clone_func;
441
442 static void clone_init(oop src, oop dst, size_t size) {
443 func_t function = BarrierResolver<decorators, func_t, BARRIER_CLONE>::resolve_barrier();
444 _clone_func = function;
445 function(src, dst, size);
446 }
447
448 static inline void clone(oop src, oop dst, size_t size) {
449 _clone_func(src, dst, size);
450 }
451 };
452
453 template <DecoratorSet decorators, typename T>
454 struct RuntimeDispatch<decorators, T, BARRIER_RESOLVE>: AllStatic {
455 typedef typename AccessFunction<decorators, T, BARRIER_RESOLVE>::type func_t;
456 static func_t _resolve_func;
457
458 static oop resolve_init(oop obj) {
459 func_t function = BarrierResolver<decorators, func_t, BARRIER_RESOLVE>::resolve_barrier();
460 _resolve_func = function;
461 return function(obj);
462 }
463
464 static inline oop resolve(oop obj) {
465 return _resolve_func(obj);
466 }
467 };
468
469 // Initialize the function pointers to point to the resolving function.
470 template <DecoratorSet decorators, typename T>
471 typename AccessFunction<decorators, T, BARRIER_STORE>::type
472 RuntimeDispatch<decorators, T, BARRIER_STORE>::_store_func = &store_init;
473
474 template <DecoratorSet decorators, typename T>
475 typename AccessFunction<decorators, T, BARRIER_STORE_AT>::type
476 RuntimeDispatch<decorators, T, BARRIER_STORE_AT>::_store_at_func = &store_at_init;
477
478 template <DecoratorSet decorators, typename T>
479 typename AccessFunction<decorators, T, BARRIER_LOAD>::type
480 RuntimeDispatch<decorators, T, BARRIER_LOAD>::_load_func = &load_init;
481
482 template <DecoratorSet decorators, typename T>
483 typename AccessFunction<decorators, T, BARRIER_LOAD_AT>::type
484 RuntimeDispatch<decorators, T, BARRIER_LOAD_AT>::_load_at_func = &load_at_init;
485
486 template <DecoratorSet decorators, typename T>
487 typename AccessFunction<decorators, T, BARRIER_ATOMIC_CMPXCHG>::type
488 RuntimeDispatch<decorators, T, BARRIER_ATOMIC_CMPXCHG>::_atomic_cmpxchg_func = &atomic_cmpxchg_init;
489
490 template <DecoratorSet decorators, typename T>
491 typename AccessFunction<decorators, T, BARRIER_ATOMIC_CMPXCHG_AT>::type
492 RuntimeDispatch<decorators, T, BARRIER_ATOMIC_CMPXCHG_AT>::_atomic_cmpxchg_at_func = &atomic_cmpxchg_at_init;
493
494 template <DecoratorSet decorators, typename T>
495 typename AccessFunction<decorators, T, BARRIER_ATOMIC_XCHG>::type
496 RuntimeDispatch<decorators, T, BARRIER_ATOMIC_XCHG>::_atomic_xchg_func = &atomic_xchg_init;
497
498 template <DecoratorSet decorators, typename T>
499 typename AccessFunction<decorators, T, BARRIER_ATOMIC_XCHG_AT>::type
500 RuntimeDispatch<decorators, T, BARRIER_ATOMIC_XCHG_AT>::_atomic_xchg_at_func = &atomic_xchg_at_init;
501
502 template <DecoratorSet decorators, typename T>
503 typename AccessFunction<decorators, T, BARRIER_ARRAYCOPY>::type
504 RuntimeDispatch<decorators, T, BARRIER_ARRAYCOPY>::_arraycopy_func = &arraycopy_init;
505
506 template <DecoratorSet decorators, typename T>
507 typename AccessFunction<decorators, T, BARRIER_CLONE>::type
508 RuntimeDispatch<decorators, T, BARRIER_CLONE>::_clone_func = &clone_init;
509
510 template <DecoratorSet decorators, typename T>
511 typename AccessFunction<decorators, T, BARRIER_RESOLVE>::type
512 RuntimeDispatch<decorators, T, BARRIER_RESOLVE>::_resolve_func = &resolve_init;
513
514 // Step 3: Pre-runtime dispatching.
515 // The PreRuntimeDispatch class is responsible for filtering the barrier strength
516 // decorators. That is, for AS_RAW, it hardwires the accesses without a runtime
517 // dispatch point. Otherwise it goes through a runtime check if hardwiring was
518 // not possible.
519 struct PreRuntimeDispatch: AllStatic {
520 template<DecoratorSet decorators>
521 struct CanHardwireRaw: public IntegralConstant<
522 bool,
523 !HasDecorator<decorators, INTERNAL_VALUE_IS_OOP>::value || // primitive access
524 !HasDecorator<decorators, INTERNAL_CONVERT_COMPRESSED_OOP>::value || // don't care about compressed oops (oop* address)
525 HasDecorator<decorators, INTERNAL_RT_USE_COMPRESSED_OOPS>::value> // we can infer we use compressed oops (narrowOop* address)
526 {};
527
528 static const DecoratorSet convert_compressed_oops = INTERNAL_RT_USE_COMPRESSED_OOPS | INTERNAL_CONVERT_COMPRESSED_OOP;
529
530 template<DecoratorSet decorators>
531 static bool is_hardwired_primitive() {
532 return !HasDecorator<decorators, INTERNAL_BT_BARRIER_ON_PRIMITIVES>::value &&
533 !HasDecorator<decorators, INTERNAL_VALUE_IS_OOP>::value;
534 }
535
536 template <DecoratorSet decorators, typename T>
537 inline static typename EnableIf<
538 HasDecorator<decorators, AS_RAW>::value && CanHardwireRaw<decorators>::value>::type
539 store(void* addr, T value) {
540 typedef RawAccessBarrier<decorators & RAW_DECORATOR_MASK> Raw;
541 if (HasDecorator<decorators, INTERNAL_VALUE_IS_OOP>::value) {
542 Raw::oop_store(addr, value);
543 } else {
544 Raw::store(addr, value);
545 }
546 }
547
548 template <DecoratorSet decorators, typename T>
549 inline static typename EnableIf<
550 HasDecorator<decorators, AS_RAW>::value && !CanHardwireRaw<decorators>::value>::type
551 store(void* addr, T value) {
552 if (UseCompressedOops) {
553 const DecoratorSet expanded_decorators = decorators | convert_compressed_oops;
554 PreRuntimeDispatch::store<expanded_decorators>(addr, value);
555 } else {
556 const DecoratorSet expanded_decorators = decorators & ~convert_compressed_oops;
557 PreRuntimeDispatch::store<expanded_decorators>(addr, value);
558 }
559 }
560
561 template <DecoratorSet decorators, typename T>
562 inline static typename EnableIf<
563 !HasDecorator<decorators, AS_RAW>::value>::type
564 store(void* addr, T value) {
565 if (is_hardwired_primitive<decorators>()) {
566 const DecoratorSet expanded_decorators = decorators | AS_RAW;
567 PreRuntimeDispatch::store<expanded_decorators>(addr, value);
568 } else {
569 RuntimeDispatch<decorators, T, BARRIER_STORE>::store(addr, value);
570 }
571 }
572
573 template <DecoratorSet decorators, typename T>
574 inline static typename EnableIf<
575 HasDecorator<decorators, AS_RAW>::value>::type
576 store_at(oop base, ptrdiff_t offset, T value) {
577 store<decorators>(field_addr(base, offset), value);
578 }
579
580 template <DecoratorSet decorators, typename T>
581 inline static typename EnableIf<
582 !HasDecorator<decorators, AS_RAW>::value>::type
583 store_at(oop base, ptrdiff_t offset, T value) {
584 if (is_hardwired_primitive<decorators>()) {
585 const DecoratorSet expanded_decorators = decorators | AS_RAW;
586 PreRuntimeDispatch::store_at<expanded_decorators>(base, offset, value);
587 } else {
588 RuntimeDispatch<decorators, T, BARRIER_STORE_AT>::store_at(base, offset, value);
589 }
590 }
591
592 template <DecoratorSet decorators, typename T>
593 inline static typename EnableIf<
594 HasDecorator<decorators, AS_RAW>::value && CanHardwireRaw<decorators>::value, T>::type
595 load(void* addr) {
596 typedef RawAccessBarrier<decorators & RAW_DECORATOR_MASK> Raw;
597 if (HasDecorator<decorators, INTERNAL_VALUE_IS_OOP>::value) {
598 return Raw::template oop_load<T>(addr);
599 } else {
600 return Raw::template load<T>(addr);
601 }
602 }
603
604 template <DecoratorSet decorators, typename T>
605 inline static typename EnableIf<
606 HasDecorator<decorators, AS_RAW>::value && !CanHardwireRaw<decorators>::value, T>::type
607 load(void* addr) {
608 if (UseCompressedOops) {
609 const DecoratorSet expanded_decorators = decorators | convert_compressed_oops;
610 return PreRuntimeDispatch::load<expanded_decorators, T>(addr);
611 } else {
612 const DecoratorSet expanded_decorators = decorators & ~convert_compressed_oops;
613 return PreRuntimeDispatch::load<expanded_decorators, T>(addr);
614 }
615 }
616
617 template <DecoratorSet decorators, typename T>
618 inline static typename EnableIf<
619 !HasDecorator<decorators, AS_RAW>::value, T>::type
620 load(void* addr) {
621 if (is_hardwired_primitive<decorators>()) {
622 const DecoratorSet expanded_decorators = decorators | AS_RAW;
623 return PreRuntimeDispatch::load<expanded_decorators, T>(addr);
624 } else {
625 return RuntimeDispatch<decorators, T, BARRIER_LOAD>::load(addr);
626 }
627 }
628
629 template <DecoratorSet decorators, typename T>
630 inline static typename EnableIf<
631 HasDecorator<decorators, AS_RAW>::value, T>::type
632 load_at(oop base, ptrdiff_t offset) {
633 return load<decorators, T>(field_addr(base, offset));
634 }
635
636 template <DecoratorSet decorators, typename T>
637 inline static typename EnableIf<
638 !HasDecorator<decorators, AS_RAW>::value, T>::type
639 load_at(oop base, ptrdiff_t offset) {
640 if (is_hardwired_primitive<decorators>()) {
641 const DecoratorSet expanded_decorators = decorators | AS_RAW;
642 return PreRuntimeDispatch::load_at<expanded_decorators, T>(base, offset);
643 } else {
644 return RuntimeDispatch<decorators, T, BARRIER_LOAD_AT>::load_at(base, offset);
645 }
646 }
647
648 template <DecoratorSet decorators, typename T>
649 inline static typename EnableIf<
650 HasDecorator<decorators, AS_RAW>::value && CanHardwireRaw<decorators>::value, T>::type
651 atomic_cmpxchg(T new_value, void* addr, T compare_value) {
652 typedef RawAccessBarrier<decorators & RAW_DECORATOR_MASK> Raw;
653 if (HasDecorator<decorators, INTERNAL_VALUE_IS_OOP>::value) {
654 return Raw::oop_atomic_cmpxchg(new_value, addr, compare_value);
655 } else {
656 return Raw::atomic_cmpxchg(new_value, addr, compare_value);
657 }
658 }
659
660 template <DecoratorSet decorators, typename T>
661 inline static typename EnableIf<
662 HasDecorator<decorators, AS_RAW>::value && !CanHardwireRaw<decorators>::value, T>::type
663 atomic_cmpxchg(T new_value, void* addr, T compare_value) {
664 if (UseCompressedOops) {
665 const DecoratorSet expanded_decorators = decorators | convert_compressed_oops;
666 return PreRuntimeDispatch::atomic_cmpxchg<expanded_decorators>(new_value, addr, compare_value);
667 } else {
668 const DecoratorSet expanded_decorators = decorators & ~convert_compressed_oops;
669 return PreRuntimeDispatch::atomic_cmpxchg<expanded_decorators>(new_value, addr, compare_value);
670 }
671 }
672
673 template <DecoratorSet decorators, typename T>
674 inline static typename EnableIf<
675 !HasDecorator<decorators, AS_RAW>::value, T>::type
676 atomic_cmpxchg(T new_value, void* addr, T compare_value) {
677 if (is_hardwired_primitive<decorators>()) {
678 const DecoratorSet expanded_decorators = decorators | AS_RAW;
679 return PreRuntimeDispatch::atomic_cmpxchg<expanded_decorators>(new_value, addr, compare_value);
680 } else {
681 return RuntimeDispatch<decorators, T, BARRIER_ATOMIC_CMPXCHG>::atomic_cmpxchg(new_value, addr, compare_value);
682 }
683 }
684
685 template <DecoratorSet decorators, typename T>
686 inline static typename EnableIf<
687 HasDecorator<decorators, AS_RAW>::value, T>::type
688 atomic_cmpxchg_at(T new_value, oop base, ptrdiff_t offset, T compare_value) {
689 return atomic_cmpxchg<decorators>(new_value, field_addr(base, offset), compare_value);
690 }
691
692 template <DecoratorSet decorators, typename T>
693 inline static typename EnableIf<
694 !HasDecorator<decorators, AS_RAW>::value, T>::type
695 atomic_cmpxchg_at(T new_value, oop base, ptrdiff_t offset, T compare_value) {
696 if (is_hardwired_primitive<decorators>()) {
697 const DecoratorSet expanded_decorators = decorators | AS_RAW;
698 return PreRuntimeDispatch::atomic_cmpxchg_at<expanded_decorators>(new_value, base, offset, compare_value);
699 } else {
700 return RuntimeDispatch<decorators, T, BARRIER_ATOMIC_CMPXCHG_AT>::atomic_cmpxchg_at(new_value, base, offset, compare_value);
701 }
702 }
703
704 template <DecoratorSet decorators, typename T>
705 inline static typename EnableIf<
706 HasDecorator<decorators, AS_RAW>::value && CanHardwireRaw<decorators>::value, T>::type
707 atomic_xchg(T new_value, void* addr) {
708 typedef RawAccessBarrier<decorators & RAW_DECORATOR_MASK> Raw;
709 if (HasDecorator<decorators, INTERNAL_VALUE_IS_OOP>::value) {
710 return Raw::oop_atomic_xchg(new_value, addr);
711 } else {
712 return Raw::atomic_xchg(new_value, addr);
713 }
714 }
715
716 template <DecoratorSet decorators, typename T>
717 inline static typename EnableIf<
718 HasDecorator<decorators, AS_RAW>::value && !CanHardwireRaw<decorators>::value, T>::type
719 atomic_xchg(T new_value, void* addr) {
720 if (UseCompressedOops) {
721 const DecoratorSet expanded_decorators = decorators | convert_compressed_oops;
722 return PreRuntimeDispatch::atomic_xchg<expanded_decorators>(new_value, addr);
723 } else {
724 const DecoratorSet expanded_decorators = decorators & ~convert_compressed_oops;
725 return PreRuntimeDispatch::atomic_xchg<expanded_decorators>(new_value, addr);
726 }
727 }
728
729 template <DecoratorSet decorators, typename T>
730 inline static typename EnableIf<
731 !HasDecorator<decorators, AS_RAW>::value, T>::type
732 atomic_xchg(T new_value, void* addr) {
733 if (is_hardwired_primitive<decorators>()) {
734 const DecoratorSet expanded_decorators = decorators | AS_RAW;
735 return PreRuntimeDispatch::atomic_xchg<expanded_decorators>(new_value, addr);
736 } else {
737 return RuntimeDispatch<decorators, T, BARRIER_ATOMIC_XCHG>::atomic_xchg(new_value, addr);
738 }
739 }
740
741 template <DecoratorSet decorators, typename T>
742 inline static typename EnableIf<
743 HasDecorator<decorators, AS_RAW>::value, T>::type
744 atomic_xchg_at(T new_value, oop base, ptrdiff_t offset) {
745 return atomic_xchg<decorators>(new_value, field_addr(base, offset));
746 }
747
748 template <DecoratorSet decorators, typename T>
749 inline static typename EnableIf<
750 !HasDecorator<decorators, AS_RAW>::value, T>::type
751 atomic_xchg_at(T new_value, oop base, ptrdiff_t offset) {
752 if (is_hardwired_primitive<decorators>()) {
753 const DecoratorSet expanded_decorators = decorators | AS_RAW;
754 return PreRuntimeDispatch::atomic_xchg<expanded_decorators>(new_value, base, offset);
755 } else {
756 return RuntimeDispatch<decorators, T, BARRIER_ATOMIC_XCHG_AT>::atomic_xchg_at(new_value, base, offset);
757 }
758 }
759
760 template <DecoratorSet decorators, typename T>
761 inline static typename EnableIf<
762 HasDecorator<decorators, AS_RAW>::value && CanHardwireRaw<decorators>::value, bool>::type
763 arraycopy(arrayOop src_obj, arrayOop dst_obj, T* src, T* dst, size_t length) {
764 typedef RawAccessBarrier<decorators & RAW_DECORATOR_MASK> Raw;
765 if (HasDecorator<decorators, INTERNAL_VALUE_IS_OOP>::value) {
766 return Raw::oop_arraycopy(src_obj, dst_obj, src, dst, length);
767 } else {
768 return Raw::arraycopy(src_obj, dst_obj, src, dst, length);
769 }
770 }
771
772 template <DecoratorSet decorators, typename T>
773 inline static typename EnableIf<
774 HasDecorator<decorators, AS_RAW>::value && !CanHardwireRaw<decorators>::value, bool>::type
775 arraycopy(arrayOop src_obj, arrayOop dst_obj, T* src, T* dst, size_t length) {
776 if (UseCompressedOops) {
777 const DecoratorSet expanded_decorators = decorators | convert_compressed_oops;
778 return PreRuntimeDispatch::arraycopy<expanded_decorators>(src_obj, dst_obj, src, dst, length);
779 } else {
780 const DecoratorSet expanded_decorators = decorators & ~convert_compressed_oops;
781 return PreRuntimeDispatch::arraycopy<expanded_decorators>(src_obj, dst_obj, src, dst, length);
782 }
783 }
784
785 template <DecoratorSet decorators, typename T>
786 inline static typename EnableIf<
787 !HasDecorator<decorators, AS_RAW>::value, bool>::type
788 arraycopy(arrayOop src_obj, arrayOop dst_obj, T* src, T* dst, size_t length) {
789 if (is_hardwired_primitive<decorators>()) {
790 const DecoratorSet expanded_decorators = decorators | AS_RAW;
791 return PreRuntimeDispatch::arraycopy<expanded_decorators>(src_obj, dst_obj, src, dst, length);
792 } else {
793 return RuntimeDispatch<decorators, T, BARRIER_ARRAYCOPY>::arraycopy(src_obj, dst_obj, src, dst, length);
794 }
795 }
796
797 template <DecoratorSet decorators>
798 inline static typename EnableIf<
799 HasDecorator<decorators, AS_RAW>::value>::type
800 clone(oop src, oop dst, size_t size) {
801 typedef RawAccessBarrier<decorators & RAW_DECORATOR_MASK> Raw;
802 Raw::clone(src, dst, size);
803 }
804
805 template <DecoratorSet decorators>
806 inline static typename EnableIf<
807 !HasDecorator<decorators, AS_RAW>::value>::type
808 clone(oop src, oop dst, size_t size) {
809 RuntimeDispatch<decorators, oop, BARRIER_CLONE>::clone(src, dst, size);
810 }
811
812 template <DecoratorSet decorators>
813 inline static typename EnableIf<
814 HasDecorator<decorators, INTERNAL_BT_TO_SPACE_INVARIANT>::value, oop>::type
815 resolve(oop obj) {
816 typedef RawAccessBarrier<decorators & RAW_DECORATOR_MASK> Raw;
817 return Raw::resolve(obj);
818 }
819
820 template <DecoratorSet decorators>
821 inline static typename EnableIf<
822 !HasDecorator<decorators, INTERNAL_BT_TO_SPACE_INVARIANT>::value, oop>::type
823 resolve(oop obj) {
824 return RuntimeDispatch<decorators, oop, BARRIER_RESOLVE>::resolve(obj);
825 }
826 };
827
828 // This class adds implied decorators that follow according to decorator rules.
829 // For example adding default reference strength and default memory ordering
830 // semantics.
831 template <DecoratorSet input_decorators>
832 struct DecoratorFixup: AllStatic {
833 // If no reference strength has been picked, then strong will be picked
834 static const DecoratorSet ref_strength_default = input_decorators |
835 (((ON_DECORATOR_MASK & input_decorators) == 0 && (INTERNAL_VALUE_IS_OOP & input_decorators) != 0) ?
836 ON_STRONG_OOP_REF : INTERNAL_EMPTY);
837 // If no memory ordering has been picked, unordered will be picked
838 static const DecoratorSet memory_ordering_default = ref_strength_default |
839 ((MO_DECORATOR_MASK & ref_strength_default) == 0 ? MO_UNORDERED : INTERNAL_EMPTY);
840 // If no barrier strength has been picked, normal will be used
841 static const DecoratorSet barrier_strength_default = memory_ordering_default |
842 ((AS_DECORATOR_MASK & memory_ordering_default) == 0 ? AS_NORMAL : INTERNAL_EMPTY);
843 // Heap array accesses imply it is a heap access
844 static const DecoratorSet heap_array_is_in_heap = barrier_strength_default |
845 ((IN_HEAP_ARRAY & barrier_strength_default) != 0 ? IN_HEAP : INTERNAL_EMPTY);
846 static const DecoratorSet conc_root_is_root = heap_array_is_in_heap |
847 ((IN_CONCURRENT_ROOT & heap_array_is_in_heap) != 0 ? IN_ROOT : INTERNAL_EMPTY);
848 static const DecoratorSet archive_root_is_root = conc_root_is_root |
849 ((IN_ARCHIVE_ROOT & conc_root_is_root) != 0 ? IN_ROOT : INTERNAL_EMPTY);
850 static const DecoratorSet value = archive_root_is_root | BT_BUILDTIME_DECORATORS;
851 };
852
853 // Step 2: Reduce types.
854 // Enforce that for non-oop types, T and P have to be strictly the same.
855 // P is the type of the address and T is the type of the values.
856 // As for oop types, it is allow to send T in {narrowOop, oop} and
857 // P in {narrowOop, oop, HeapWord*}. The following rules apply according to
858 // the subsequent table. (columns are P, rows are T)
859 // | | HeapWord | oop | narrowOop |
860 // | oop | rt-comp | hw-none | hw-comp |
861 // | narrowOop | x | x | hw-none |
862 //
863 // x means not allowed
864 // rt-comp means it must be checked at runtime whether the oop is compressed.
865 // hw-none means it is statically known the oop will not be compressed.
866 // hw-comp means it is statically known the oop will be compressed.
867
868 template <DecoratorSet decorators, typename T>
869 inline void store_reduce_types(T* addr, T value) {
870 PreRuntimeDispatch::store<decorators>(addr, value);
871 }
872
873 template <DecoratorSet decorators>
874 inline void store_reduce_types(narrowOop* addr, oop value) {
875 const DecoratorSet expanded_decorators = decorators | INTERNAL_CONVERT_COMPRESSED_OOP |
876 INTERNAL_RT_USE_COMPRESSED_OOPS;
877 PreRuntimeDispatch::store<expanded_decorators>(addr, value);
878 }
879
880 template <DecoratorSet decorators>
881 inline void store_reduce_types(narrowOop* addr, narrowOop value) {
882 const DecoratorSet expanded_decorators = decorators | INTERNAL_CONVERT_COMPRESSED_OOP |
883 INTERNAL_RT_USE_COMPRESSED_OOPS;
884 PreRuntimeDispatch::store<expanded_decorators>(addr, value);
885 }
886
887 template <DecoratorSet decorators>
888 inline void store_reduce_types(HeapWord* addr, oop value) {
889 const DecoratorSet expanded_decorators = decorators | INTERNAL_CONVERT_COMPRESSED_OOP;
890 PreRuntimeDispatch::store<expanded_decorators>(addr, value);
891 }
892
893 template <DecoratorSet decorators, typename T>
894 inline T atomic_cmpxchg_reduce_types(T new_value, T* addr, T compare_value) {
895 return PreRuntimeDispatch::atomic_cmpxchg<decorators>(new_value, addr, compare_value);
896 }
897
898 template <DecoratorSet decorators>
899 inline oop atomic_cmpxchg_reduce_types(oop new_value, narrowOop* addr, oop compare_value) {
900 const DecoratorSet expanded_decorators = decorators | INTERNAL_CONVERT_COMPRESSED_OOP |
901 INTERNAL_RT_USE_COMPRESSED_OOPS;
902 return PreRuntimeDispatch::atomic_cmpxchg<expanded_decorators>(new_value, addr, compare_value);
903 }
904
905 template <DecoratorSet decorators>
906 inline narrowOop atomic_cmpxchg_reduce_types(narrowOop new_value, narrowOop* addr, narrowOop compare_value) {
907 const DecoratorSet expanded_decorators = decorators | INTERNAL_CONVERT_COMPRESSED_OOP |
908 INTERNAL_RT_USE_COMPRESSED_OOPS;
909 return PreRuntimeDispatch::atomic_cmpxchg<expanded_decorators>(new_value, addr, compare_value);
910 }
911
912 template <DecoratorSet decorators>
913 inline oop atomic_cmpxchg_reduce_types(oop new_value,
914 HeapWord* addr,
915 oop compare_value) {
916 const DecoratorSet expanded_decorators = decorators | INTERNAL_CONVERT_COMPRESSED_OOP;
917 return PreRuntimeDispatch::atomic_cmpxchg<expanded_decorators>(new_value, addr, compare_value);
918 }
919
920 template <DecoratorSet decorators, typename T>
921 inline T atomic_xchg_reduce_types(T new_value, T* addr) {
922 const DecoratorSet expanded_decorators = decorators;
923 return PreRuntimeDispatch::atomic_xchg<expanded_decorators>(new_value, addr);
924 }
925
926 template <DecoratorSet decorators>
927 inline oop atomic_xchg_reduce_types(oop new_value, narrowOop* addr) {
928 const DecoratorSet expanded_decorators = decorators | INTERNAL_CONVERT_COMPRESSED_OOP |
929 INTERNAL_RT_USE_COMPRESSED_OOPS;
930 return PreRuntimeDispatch::atomic_xchg<expanded_decorators>(new_value, addr);
931 }
932
933 template <DecoratorSet decorators>
934 inline narrowOop atomic_xchg_reduce_types(narrowOop new_value, narrowOop* addr) {
935 const DecoratorSet expanded_decorators = decorators | INTERNAL_CONVERT_COMPRESSED_OOP |
936 INTERNAL_RT_USE_COMPRESSED_OOPS;
937 return PreRuntimeDispatch::atomic_xchg<expanded_decorators>(new_value, addr);
938 }
939
940 template <DecoratorSet decorators>
941 inline oop atomic_xchg_reduce_types(oop new_value, HeapWord* addr) {
942 const DecoratorSet expanded_decorators = decorators | INTERNAL_CONVERT_COMPRESSED_OOP;
943 return PreRuntimeDispatch::atomic_xchg<expanded_decorators>(new_value, addr);
944 }
945
946 template <DecoratorSet decorators, typename T>
947 inline T load_reduce_types(T* addr) {
948 return PreRuntimeDispatch::load<decorators, T>(addr);
949 }
950
951 template <DecoratorSet decorators, typename T>
952 inline typename OopOrNarrowOop<T>::type load_reduce_types(narrowOop* addr) {
953 const DecoratorSet expanded_decorators = decorators | INTERNAL_CONVERT_COMPRESSED_OOP |
954 INTERNAL_RT_USE_COMPRESSED_OOPS;
955 return PreRuntimeDispatch::load<expanded_decorators, typename OopOrNarrowOop<T>::type>(addr);
956 }
957
958 template <DecoratorSet decorators, typename T>
959 inline oop load_reduce_types(HeapWord* addr) {
960 const DecoratorSet expanded_decorators = decorators | INTERNAL_CONVERT_COMPRESSED_OOP;
961 return PreRuntimeDispatch::load<expanded_decorators, oop>(addr);
962 }
963
964 template <DecoratorSet decorators, typename T>
965 inline bool arraycopy_reduce_types(arrayOop src_obj, arrayOop dst_obj, T* src, T* dst, size_t length) {
966 return PreRuntimeDispatch::arraycopy<decorators>(src_obj, dst_obj, src, dst, length);
967 }
968
969 template <DecoratorSet decorators>
970 inline bool arraycopy_reduce_types(arrayOop src_obj, arrayOop dst_obj, HeapWord* src, HeapWord* dst, size_t length) {
971 const DecoratorSet expanded_decorators = decorators | INTERNAL_CONVERT_COMPRESSED_OOP;
972 return PreRuntimeDispatch::arraycopy<expanded_decorators>(src_obj, dst_obj, src, dst, length);
973 }
974
975 template <DecoratorSet decorators>
976 inline bool arraycopy_reduce_types(arrayOop src_obj, arrayOop dst_obj, narrowOop* src, narrowOop* dst, size_t length) {
977 const DecoratorSet expanded_decorators = decorators | INTERNAL_CONVERT_COMPRESSED_OOP |
978 INTERNAL_RT_USE_COMPRESSED_OOPS;
979 return PreRuntimeDispatch::arraycopy<expanded_decorators>(src_obj, dst_obj, src, dst, length);
980 }
981
982 // Step 1: Set default decorators. This step remembers if a type was volatile
983 // and then sets the MO_VOLATILE decorator by default. Otherwise, a default
984 // memory ordering is set for the access, and the implied decorator rules
985 // are applied to select sensible defaults for decorators that have not been
986 // explicitly set. For example, default object referent strength is set to strong.
987 // This step also decays the types passed in (e.g. getting rid of CV qualifiers
988 // and references from the types). This step also perform some type verification
989 // that the passed in types make sense.
990
991 template <DecoratorSet decorators, typename T>
992 static void verify_types(){
993 // If this fails to compile, then you have sent in something that is
994 // not recognized as a valid primitive type to a primitive Access function.
995 STATIC_ASSERT((HasDecorator<decorators, INTERNAL_VALUE_IS_OOP>::value || // oops have already been validated
996 (IsPointer<T>::value || IsIntegral<T>::value) ||
997 IsFloatingPoint<T>::value)); // not allowed primitive type
998 }
999
1000 template <DecoratorSet decorators, typename P, typename T>
1001 inline void store(P* addr, T value) {
1002 verify_types<decorators, T>();
1003 typedef typename Decay<P>::type DecayedP;
1004 typedef typename Decay<T>::type DecayedT;
1005 DecayedT decayed_value = value;
1006 // If a volatile address is passed in but no memory ordering decorator,
1007 // set the memory ordering to MO_VOLATILE by default.
1008 const DecoratorSet expanded_decorators = DecoratorFixup<
1009 (IsVolatile<P>::value && !HasDecorator<decorators, MO_DECORATOR_MASK>::value) ?
1010 (MO_VOLATILE | decorators) : decorators>::value;
1011 store_reduce_types<expanded_decorators>(const_cast<DecayedP*>(addr), decayed_value);
1012 }
1013
1014 template <DecoratorSet decorators, typename T>
1015 inline void store_at(oop base, ptrdiff_t offset, T value) {
1016 verify_types<decorators, T>();
1017 typedef typename Decay<T>::type DecayedT;
1018 DecayedT decayed_value = value;
1019 const DecoratorSet expanded_decorators = DecoratorFixup<decorators |
1020 (HasDecorator<decorators, INTERNAL_VALUE_IS_OOP>::value ?
1021 INTERNAL_CONVERT_COMPRESSED_OOP : INTERNAL_EMPTY)>::value;
1022 PreRuntimeDispatch::store_at<expanded_decorators>(base, offset, decayed_value);
1023 }
1024
1025 template <DecoratorSet decorators, typename P, typename T>
1026 inline T load(P* addr) {
1027 verify_types<decorators, T>();
1028 typedef typename Decay<P>::type DecayedP;
1029 typedef typename Conditional<HasDecorator<decorators, INTERNAL_VALUE_IS_OOP>::value,
1030 typename OopOrNarrowOop<T>::type,
1031 typename Decay<T>::type>::type DecayedT;
1032 // If a volatile address is passed in but no memory ordering decorator,
1033 // set the memory ordering to MO_VOLATILE by default.
1034 const DecoratorSet expanded_decorators = DecoratorFixup<
1035 (IsVolatile<P>::value && !HasDecorator<decorators, MO_DECORATOR_MASK>::value) ?
1036 (MO_VOLATILE | decorators) : decorators>::value;
1037 return load_reduce_types<expanded_decorators, DecayedT>(const_cast<DecayedP*>(addr));
1038 }
1039
1040 template <DecoratorSet decorators, typename T>
1041 inline T load_at(oop base, ptrdiff_t offset) {
1042 verify_types<decorators, T>();
1043 typedef typename Conditional<HasDecorator<decorators, INTERNAL_VALUE_IS_OOP>::value,
1044 typename OopOrNarrowOop<T>::type,
1045 typename Decay<T>::type>::type DecayedT;
1046 // Expand the decorators (figure out sensible defaults)
1047 // Potentially remember if we need compressed oop awareness
1048 const DecoratorSet expanded_decorators = DecoratorFixup<decorators |
1049 (HasDecorator<decorators, INTERNAL_VALUE_IS_OOP>::value ?
1050 INTERNAL_CONVERT_COMPRESSED_OOP : INTERNAL_EMPTY)>::value;
1051 return PreRuntimeDispatch::load_at<expanded_decorators, DecayedT>(base, offset);
1052 }
1053
1054 template <DecoratorSet decorators, typename P, typename T>
1055 inline T atomic_cmpxchg(T new_value, P* addr, T compare_value) {
1056 verify_types<decorators, T>();
1057 typedef typename Decay<P>::type DecayedP;
1058 typedef typename Decay<T>::type DecayedT;
1059 DecayedT new_decayed_value = new_value;
1060 DecayedT compare_decayed_value = compare_value;
1061 const DecoratorSet expanded_decorators = DecoratorFixup<
1062 (!HasDecorator<decorators, MO_DECORATOR_MASK>::value) ?
1063 (MO_SEQ_CST | decorators) : decorators>::value;
1064 return atomic_cmpxchg_reduce_types<expanded_decorators>(new_decayed_value,
1065 const_cast<DecayedP*>(addr),
1066 compare_decayed_value);
1067 }
1068
1069 template <DecoratorSet decorators, typename T>
1070 inline T atomic_cmpxchg_at(T new_value, oop base, ptrdiff_t offset, T compare_value) {
1071 verify_types<decorators, T>();
1072 typedef typename Decay<T>::type DecayedT;
1073 DecayedT new_decayed_value = new_value;
1074 DecayedT compare_decayed_value = compare_value;
1075 // Determine default memory ordering
1076 const DecoratorSet expanded_decorators = DecoratorFixup<
1077 (!HasDecorator<decorators, MO_DECORATOR_MASK>::value) ?
1078 (MO_SEQ_CST | decorators) : decorators>::value;
1079 // Potentially remember that we need compressed oop awareness
1080 const DecoratorSet final_decorators = expanded_decorators |
1081 (HasDecorator<decorators, INTERNAL_VALUE_IS_OOP>::value ?
1082 INTERNAL_CONVERT_COMPRESSED_OOP : INTERNAL_EMPTY);
1083 return PreRuntimeDispatch::atomic_cmpxchg_at<final_decorators>(new_decayed_value, base,
1084 offset, compare_decayed_value);
1085 }
1086
1087 template <DecoratorSet decorators, typename P, typename T>
1088 inline T atomic_xchg(T new_value, P* addr) {
1089 verify_types<decorators, T>();
1090 typedef typename Decay<P>::type DecayedP;
1091 typedef typename Decay<T>::type DecayedT;
1092 DecayedT new_decayed_value = new_value;
1093 // atomic_xchg is only available in SEQ_CST flavour.
1094 const DecoratorSet expanded_decorators = DecoratorFixup<decorators | MO_SEQ_CST>::value;
1095 return atomic_xchg_reduce_types<expanded_decorators>(new_decayed_value,
1096 const_cast<DecayedP*>(addr));
1097 }
1098
1099 template <DecoratorSet decorators, typename T>
1100 inline T atomic_xchg_at(T new_value, oop base, ptrdiff_t offset) {
1101 verify_types<decorators, T>();
1102 typedef typename Decay<T>::type DecayedT;
1103 DecayedT new_decayed_value = new_value;
1104 // atomic_xchg is only available in SEQ_CST flavour.
1105 const DecoratorSet expanded_decorators = DecoratorFixup<decorators | MO_SEQ_CST |
1106 (HasDecorator<decorators, INTERNAL_VALUE_IS_OOP>::value ?
1107 INTERNAL_CONVERT_COMPRESSED_OOP : INTERNAL_EMPTY)>::value;
1108 return PreRuntimeDispatch::atomic_xchg_at<expanded_decorators>(new_decayed_value, base, offset);
1109 }
1110
1111 template <DecoratorSet decorators, typename T>
1112 inline bool arraycopy(arrayOop src_obj, arrayOop dst_obj, T* src, T* dst, size_t length) {
1113 STATIC_ASSERT((HasDecorator<decorators, INTERNAL_VALUE_IS_OOP>::value ||
1114 (IsSame<T, void>::value || IsIntegral<T>::value) ||
1115 IsFloatingPoint<T>::value)); // arraycopy allows type erased void elements
1116 typedef typename Decay<T>::type DecayedT;
1117 const DecoratorSet expanded_decorators = DecoratorFixup<decorators | IN_HEAP_ARRAY | IN_HEAP>::value;
1118 return arraycopy_reduce_types<expanded_decorators>(src_obj, dst_obj,
1119 const_cast<DecayedT*>(src),
1120 const_cast<DecayedT*>(dst),
1121 length);
1122 }
1123
1124 template <DecoratorSet decorators>
1125 inline void clone(oop src, oop dst, size_t size) {
1126 const DecoratorSet expanded_decorators = DecoratorFixup<decorators>::value;
1127 PreRuntimeDispatch::clone<expanded_decorators>(src, dst, size);
1128 }
1129
1130 template <DecoratorSet decorators>
1131 inline oop resolve(oop obj) {
1132 const DecoratorSet expanded_decorators = DecoratorFixup<decorators>::value;
1133 return PreRuntimeDispatch::resolve<expanded_decorators>(obj);
1134 }
1135 }
1136
1137 template <DecoratorSet decorators>
1138 template <DecoratorSet expected_decorators>
1139 void Access<decorators>::verify_decorators() {
1140 STATIC_ASSERT((~expected_decorators & decorators) == 0); // unexpected decorator used
1141 const DecoratorSet barrier_strength_decorators = decorators & AS_DECORATOR_MASK;
1142 STATIC_ASSERT(barrier_strength_decorators == 0 || ( // make sure barrier strength decorators are disjoint if set
1143 (barrier_strength_decorators ^ AS_NO_KEEPALIVE) == 0 ||
1144 (barrier_strength_decorators ^ AS_DEST_NOT_INITIALIZED) == 0 ||
1145 (barrier_strength_decorators ^ AS_RAW) == 0 ||
1146 (barrier_strength_decorators ^ AS_NORMAL) == 0
1147 ));
1148 const DecoratorSet ref_strength_decorators = decorators & ON_DECORATOR_MASK;
1149 STATIC_ASSERT(ref_strength_decorators == 0 || ( // make sure ref strength decorators are disjoint if set
1150 (ref_strength_decorators ^ ON_STRONG_OOP_REF) == 0 ||
1151 (ref_strength_decorators ^ ON_WEAK_OOP_REF) == 0 ||
1152 (ref_strength_decorators ^ ON_PHANTOM_OOP_REF) == 0 ||
1153 (ref_strength_decorators ^ ON_UNKNOWN_OOP_REF) == 0
1154 ));
1155 const DecoratorSet memory_ordering_decorators = decorators & MO_DECORATOR_MASK;
1156 STATIC_ASSERT(memory_ordering_decorators == 0 || ( // make sure memory ordering decorators are disjoint if set
1157 (memory_ordering_decorators ^ MO_UNORDERED) == 0 ||
1158 (memory_ordering_decorators ^ MO_VOLATILE) == 0 ||
1159 (memory_ordering_decorators ^ MO_RELAXED) == 0 ||
1160 (memory_ordering_decorators ^ MO_ACQUIRE) == 0 ||
1161 (memory_ordering_decorators ^ MO_RELEASE) == 0 ||
1162 (memory_ordering_decorators ^ MO_SEQ_CST) == 0
1163 ));
1164 const DecoratorSet location_decorators = decorators & IN_DECORATOR_MASK;
1165 STATIC_ASSERT(location_decorators == 0 || ( // make sure location decorators are disjoint if set
1166 (location_decorators ^ IN_ROOT) == 0 ||
1167 (location_decorators ^ IN_HEAP) == 0 ||
1168 (location_decorators ^ (IN_HEAP | IN_HEAP_ARRAY)) == 0 ||
1169 (location_decorators ^ (IN_ROOT | IN_CONCURRENT_ROOT)) == 0 ||
1170 (location_decorators ^ (IN_ROOT | IN_ARCHIVE_ROOT)) == 0
1171 ));
1172 }
1173
1174 #endif // SHARE_VM_RUNTIME_ACCESS_INLINE_HPP
|
253 default:
254 fatal("BarrierSet AccessBarrier resolving not implemented");
255 return NULL;
256 };
257 }
258
259 static FunctionPointerT resolve_barrier_rt() {
260 if (UseCompressedOops) {
261 const DecoratorSet expanded_decorators = decorators | INTERNAL_RT_USE_COMPRESSED_OOPS;
262 return resolve_barrier_gc<expanded_decorators>();
263 } else {
264 return resolve_barrier_gc<decorators>();
265 }
266 }
267
268 static FunctionPointerT resolve_barrier() {
269 return resolve_barrier_rt();
270 }
271 };
272
273 // Step 5.a: Barrier resolution
274 // The RuntimeDispatch class is responsible for performing a runtime dispatch of the
275 // accessor. This is required when the access either depends on whether compressed oops
276 // is being used, or it depends on which GC implementation was chosen (e.g. requires GC
277 // barriers). The way it works is that a function pointer initially pointing to an
278 // accessor resolution function gets called for each access. Upon first invocation,
279 // it resolves which accessor to be used in future invocations and patches the
280 // function pointer to this new accessor.
281
282 template <DecoratorSet decorators, typename T>
283 void RuntimeDispatch<decorators, T, BARRIER_STORE>::store_init(void* addr, T value) {
284 func_t function = BarrierResolver<decorators, func_t, BARRIER_STORE>::resolve_barrier();
285 _store_func = function;
286 function(addr, value);
287 }
288
289 template <DecoratorSet decorators, typename T>
290 void RuntimeDispatch<decorators, T, BARRIER_STORE_AT>::store_at_init(oop base, ptrdiff_t offset, T value) {
291 func_t function = BarrierResolver<decorators, func_t, BARRIER_STORE_AT>::resolve_barrier();
292 _store_at_func = function;
293 function(base, offset, value);
294 }
295
296 template <DecoratorSet decorators, typename T>
297 T RuntimeDispatch<decorators, T, BARRIER_LOAD>::load_init(void* addr) {
298 func_t function = BarrierResolver<decorators, func_t, BARRIER_LOAD>::resolve_barrier();
299 _load_func = function;
300 return function(addr);
301 }
302
303 template <DecoratorSet decorators, typename T>
304 T RuntimeDispatch<decorators, T, BARRIER_LOAD_AT>::load_at_init(oop base, ptrdiff_t offset) {
305 func_t function = BarrierResolver<decorators, func_t, BARRIER_LOAD_AT>::resolve_barrier();
306 _load_at_func = function;
307 return function(base, offset);
308 }
309
310 template <DecoratorSet decorators, typename T>
311 T RuntimeDispatch<decorators, T, BARRIER_ATOMIC_CMPXCHG>::atomic_cmpxchg_init(T new_value, void* addr, T compare_value) {
312 func_t function = BarrierResolver<decorators, func_t, BARRIER_ATOMIC_CMPXCHG>::resolve_barrier();
313 _atomic_cmpxchg_func = function;
314 return function(new_value, addr, compare_value);
315 }
316
317 template <DecoratorSet decorators, typename T>
318 T RuntimeDispatch<decorators, T, BARRIER_ATOMIC_CMPXCHG_AT>::atomic_cmpxchg_at_init(T new_value, oop base, ptrdiff_t offset, T comp
319 func_t function = BarrierResolver<decorators, func_t, BARRIER_ATOMIC_CMPXCHG_AT>::resolve_barrier();
320 _atomic_cmpxchg_at_func = function;
321 return function(new_value, base, offset, compare_value);
322 }
323
324 template <DecoratorSet decorators, typename T>
325 T RuntimeDispatch<decorators, T, BARRIER_ATOMIC_XCHG>::atomic_xchg_init(T new_value, void* addr) {
326 func_t function = BarrierResolver<decorators, func_t, BARRIER_ATOMIC_XCHG>::resolve_barrier();
327 _atomic_xchg_func = function;
328 return function(new_value, addr);
329 }
330
331 template <DecoratorSet decorators, typename T>
332 T RuntimeDispatch<decorators, T, BARRIER_ATOMIC_XCHG_AT>::atomic_xchg_at_init(T new_value, oop base, ptrdiff_t offset) {
333 func_t function = BarrierResolver<decorators, func_t, BARRIER_ATOMIC_XCHG_AT>::resolve_barrier();
334 _atomic_xchg_at_func = function;
335 return function(new_value, base, offset);
336 }
337
338 template <DecoratorSet decorators, typename T>
339 bool RuntimeDispatch<decorators, T, BARRIER_ARRAYCOPY>::arraycopy_init(arrayOop src_obj, arrayOop dst_obj, T *src, T* dst, size_t l
340 func_t function = BarrierResolver<decorators, func_t, BARRIER_ARRAYCOPY>::resolve_barrier();
341 _arraycopy_func = function;
342 return function(src_obj, dst_obj, src, dst, length);
343 }
344
345 template <DecoratorSet decorators, typename T>
346 void RuntimeDispatch<decorators, T, BARRIER_CLONE>::clone_init(oop src, oop dst, size_t size) {
347 func_t function = BarrierResolver<decorators, func_t, BARRIER_CLONE>::resolve_barrier();
348 _clone_func = function;
349 function(src, dst, size);
350 }
351
352 template <DecoratorSet decorators, typename T>
353 oop RuntimeDispatch<decorators, T, BARRIER_RESOLVE>::resolve_init(oop obj) {
354 func_t function = BarrierResolver<decorators, func_t, BARRIER_RESOLVE>::resolve_barrier();
355 _resolve_func = function;
356 return function(obj);
357 }
358
359 template <DecoratorSet decorators, typename T>
360 bool RuntimeDispatch<decorators, T, BARRIER_EQUALS>::equals_init(oop o1, oop o2) {
361 func_t function = BarrierResolver<decorators, func_t, BARRIER_EQUALS>::resolve_barrier();
362 _equals_func = function;
363 return function(o1, o2);
364 }
365 }
366
367 #endif // SHARE_OOPS_ACCESS_INLINE_HPP
|