36 #include "metaprogramming/isPointer.hpp" |
36 #include "metaprogramming/isPointer.hpp" |
37 #include "metaprogramming/isSame.hpp" |
37 #include "metaprogramming/isSame.hpp" |
38 #include "metaprogramming/isVolatile.hpp" |
38 #include "metaprogramming/isVolatile.hpp" |
39 #include "oops/accessDecorators.hpp" |
39 #include "oops/accessDecorators.hpp" |
40 #include "oops/oopsHierarchy.hpp" |
40 #include "oops/oopsHierarchy.hpp" |
|
41 #include "runtime/globals.hpp" |
41 #include "utilities/debug.hpp" |
42 #include "utilities/debug.hpp" |
42 #include "utilities/globalDefinitions.hpp" |
43 #include "utilities/globalDefinitions.hpp" |
43 |
44 |
44 |
45 |
45 // This metafunction returns either oop or narrowOop depending on whether |
46 // This metafunction returns either oop or narrowOop depending on whether |
61 BARRIER_ATOMIC_CMPXCHG_AT, |
62 BARRIER_ATOMIC_CMPXCHG_AT, |
62 BARRIER_ATOMIC_XCHG, |
63 BARRIER_ATOMIC_XCHG, |
63 BARRIER_ATOMIC_XCHG_AT, |
64 BARRIER_ATOMIC_XCHG_AT, |
64 BARRIER_ARRAYCOPY, |
65 BARRIER_ARRAYCOPY, |
65 BARRIER_CLONE, |
66 BARRIER_CLONE, |
66 BARRIER_RESOLVE, |
67 BARRIER_RESOLVE |
67 BARRIER_EQUALS |
|
68 }; |
68 }; |
69 |
69 |
70 template <DecoratorSet decorators, typename T> |
70 template <DecoratorSet decorators, typename T> |
71 struct MustConvertCompressedOop: public IntegralConstant<bool, |
71 struct MustConvertCompressedOop: public IntegralConstant<bool, |
72 HasDecorator<decorators, INTERNAL_VALUE_IS_OOP>::value && |
72 HasDecorator<decorators, INTERNAL_VALUE_IS_OOP>::value && |
113 typedef bool (*arraycopy_func_t)(arrayOop src_obj, size_t src_offset_in_bytes, T* src_raw, |
113 typedef bool (*arraycopy_func_t)(arrayOop src_obj, size_t src_offset_in_bytes, T* src_raw, |
114 arrayOop dst_obj, size_t dst_offset_in_bytes, T* dst_raw, |
114 arrayOop dst_obj, size_t dst_offset_in_bytes, T* dst_raw, |
115 size_t length); |
115 size_t length); |
116 typedef void (*clone_func_t)(oop src, oop dst, size_t size); |
116 typedef void (*clone_func_t)(oop src, oop dst, size_t size); |
117 typedef oop (*resolve_func_t)(oop obj); |
117 typedef oop (*resolve_func_t)(oop obj); |
118 typedef bool (*equals_func_t)(oop o1, oop o2); |
|
119 }; |
118 }; |
120 |
119 |
121 template <DecoratorSet decorators> |
120 template <DecoratorSet decorators> |
122 struct AccessFunctionTypes<decorators, void> { |
121 struct AccessFunctionTypes<decorators, void> { |
123 typedef bool (*arraycopy_func_t)(arrayOop src_obj, size_t src_offset_in_bytes, void* src, |
122 typedef bool (*arraycopy_func_t)(arrayOop src_obj, size_t src_offset_in_bytes, void* src, |
141 ACCESS_GENERATE_ACCESS_FUNCTION(BARRIER_ATOMIC_XCHG, atomic_xchg_func_t); |
140 ACCESS_GENERATE_ACCESS_FUNCTION(BARRIER_ATOMIC_XCHG, atomic_xchg_func_t); |
142 ACCESS_GENERATE_ACCESS_FUNCTION(BARRIER_ATOMIC_XCHG_AT, atomic_xchg_at_func_t); |
141 ACCESS_GENERATE_ACCESS_FUNCTION(BARRIER_ATOMIC_XCHG_AT, atomic_xchg_at_func_t); |
143 ACCESS_GENERATE_ACCESS_FUNCTION(BARRIER_ARRAYCOPY, arraycopy_func_t); |
142 ACCESS_GENERATE_ACCESS_FUNCTION(BARRIER_ARRAYCOPY, arraycopy_func_t); |
144 ACCESS_GENERATE_ACCESS_FUNCTION(BARRIER_CLONE, clone_func_t); |
143 ACCESS_GENERATE_ACCESS_FUNCTION(BARRIER_CLONE, clone_func_t); |
145 ACCESS_GENERATE_ACCESS_FUNCTION(BARRIER_RESOLVE, resolve_func_t); |
144 ACCESS_GENERATE_ACCESS_FUNCTION(BARRIER_RESOLVE, resolve_func_t); |
146 ACCESS_GENERATE_ACCESS_FUNCTION(BARRIER_EQUALS, equals_func_t); |
|
147 #undef ACCESS_GENERATE_ACCESS_FUNCTION |
145 #undef ACCESS_GENERATE_ACCESS_FUNCTION |
148 |
146 |
149 template <DecoratorSet decorators, typename T, BarrierType barrier_type> |
147 template <DecoratorSet decorators, typename T, BarrierType barrier_type> |
150 typename AccessFunction<decorators, T, barrier_type>::type resolve_barrier(); |
148 typename AccessFunction<decorators, T, barrier_type>::type resolve_barrier(); |
151 |
149 |
407 size_t length); |
405 size_t length); |
408 |
406 |
409 static void clone(oop src, oop dst, size_t size); |
407 static void clone(oop src, oop dst, size_t size); |
410 |
408 |
411 static oop resolve(oop obj) { return obj; } |
409 static oop resolve(oop obj) { return obj; } |
412 |
|
413 static bool equals(oop o1, oop o2) { return (void*)o1 == (void*)o2; } |
|
414 }; |
410 }; |
415 |
411 |
416 // Below is the implementation of the first 4 steps of the template pipeline: |
412 // Below is the implementation of the first 4 steps of the template pipeline: |
417 // * Step 1: Set default decorators and decay types. This step gets rid of CV qualifiers |
413 // * Step 1: Set default decorators and decay types. This step gets rid of CV qualifiers |
418 // and sets default decorators to sensible values. |
414 // and sets default decorators to sensible values. |
602 static inline oop resolve(oop obj) { |
598 static inline oop resolve(oop obj) { |
603 return _resolve_func(obj); |
599 return _resolve_func(obj); |
604 } |
600 } |
605 }; |
601 }; |
606 |
602 |
607 template <DecoratorSet decorators, typename T> |
|
608 struct RuntimeDispatch<decorators, T, BARRIER_EQUALS>: AllStatic { |
|
609 typedef typename AccessFunction<decorators, T, BARRIER_EQUALS>::type func_t; |
|
610 static func_t _equals_func; |
|
611 |
|
612 static bool equals_init(oop o1, oop o2); |
|
613 |
|
614 static inline bool equals(oop o1, oop o2) { |
|
615 return _equals_func(o1, o2); |
|
616 } |
|
617 }; |
|
618 |
|
619 // Initialize the function pointers to point to the resolving function. |
603 // Initialize the function pointers to point to the resolving function. |
620 template <DecoratorSet decorators, typename T> |
604 template <DecoratorSet decorators, typename T> |
621 typename AccessFunction<decorators, T, BARRIER_STORE>::type |
605 typename AccessFunction<decorators, T, BARRIER_STORE>::type |
622 RuntimeDispatch<decorators, T, BARRIER_STORE>::_store_func = &store_init; |
606 RuntimeDispatch<decorators, T, BARRIER_STORE>::_store_func = &store_init; |
623 |
607 |
658 RuntimeDispatch<decorators, T, BARRIER_CLONE>::_clone_func = &clone_init; |
642 RuntimeDispatch<decorators, T, BARRIER_CLONE>::_clone_func = &clone_init; |
659 |
643 |
660 template <DecoratorSet decorators, typename T> |
644 template <DecoratorSet decorators, typename T> |
661 typename AccessFunction<decorators, T, BARRIER_RESOLVE>::type |
645 typename AccessFunction<decorators, T, BARRIER_RESOLVE>::type |
662 RuntimeDispatch<decorators, T, BARRIER_RESOLVE>::_resolve_func = &resolve_init; |
646 RuntimeDispatch<decorators, T, BARRIER_RESOLVE>::_resolve_func = &resolve_init; |
663 |
|
664 template <DecoratorSet decorators, typename T> |
|
665 typename AccessFunction<decorators, T, BARRIER_EQUALS>::type |
|
666 RuntimeDispatch<decorators, T, BARRIER_EQUALS>::_equals_func = &equals_init; |
|
667 |
647 |
668 // Step 3: Pre-runtime dispatching. |
648 // Step 3: Pre-runtime dispatching. |
669 // The PreRuntimeDispatch class is responsible for filtering the barrier strength |
649 // The PreRuntimeDispatch class is responsible for filtering the barrier strength |
670 // decorators. That is, for AS_RAW, it hardwires the accesses without a runtime |
650 // decorators. That is, for AS_RAW, it hardwires the accesses without a runtime |
671 // dispatch point. Otherwise it goes through a runtime check if hardwiring was |
651 // dispatch point. Otherwise it goes through a runtime check if hardwiring was |
992 template <DecoratorSet decorators> |
972 template <DecoratorSet decorators> |
993 inline static typename EnableIf< |
973 inline static typename EnableIf< |
994 !HasDecorator<decorators, INTERNAL_BT_TO_SPACE_INVARIANT>::value, oop>::type |
974 !HasDecorator<decorators, INTERNAL_BT_TO_SPACE_INVARIANT>::value, oop>::type |
995 resolve(oop obj) { |
975 resolve(oop obj) { |
996 return RuntimeDispatch<decorators, oop, BARRIER_RESOLVE>::resolve(obj); |
976 return RuntimeDispatch<decorators, oop, BARRIER_RESOLVE>::resolve(obj); |
997 } |
|
998 |
|
999 template <DecoratorSet decorators> |
|
1000 inline static typename EnableIf< |
|
1001 HasDecorator<decorators, AS_RAW>::value || HasDecorator<decorators, INTERNAL_BT_TO_SPACE_INVARIANT>::value, bool>::type |
|
1002 equals(oop o1, oop o2) { |
|
1003 typedef RawAccessBarrier<decorators & RAW_DECORATOR_MASK> Raw; |
|
1004 return Raw::equals(o1, o2); |
|
1005 } |
|
1006 |
|
1007 template <DecoratorSet decorators> |
|
1008 inline static typename EnableIf< |
|
1009 !HasDecorator<decorators, AS_RAW>::value && !HasDecorator<decorators, INTERNAL_BT_TO_SPACE_INVARIANT>::value, bool>::type |
|
1010 equals(oop o1, oop o2) { |
|
1011 return RuntimeDispatch<decorators, oop, BARRIER_EQUALS>::equals(o1, o2); |
|
1012 } |
977 } |
1013 }; |
978 }; |
1014 |
979 |
1015 // Step 2: Reduce types. |
980 // Step 2: Reduce types. |
1016 // Enforce that for non-oop types, T and P have to be strictly the same. |
981 // Enforce that for non-oop types, T and P have to be strictly the same. |
1306 inline oop resolve(oop obj) { |
1271 inline oop resolve(oop obj) { |
1307 const DecoratorSet expanded_decorators = DecoratorFixup<decorators>::value; |
1272 const DecoratorSet expanded_decorators = DecoratorFixup<decorators>::value; |
1308 return PreRuntimeDispatch::resolve<expanded_decorators>(obj); |
1273 return PreRuntimeDispatch::resolve<expanded_decorators>(obj); |
1309 } |
1274 } |
1310 |
1275 |
1311 template <DecoratorSet decorators> |
|
1312 inline bool equals(oop o1, oop o2) { |
|
1313 const DecoratorSet expanded_decorators = DecoratorFixup<decorators>::value; |
|
1314 return PreRuntimeDispatch::equals<expanded_decorators>(o1, o2); |
|
1315 } |
|
1316 |
|
1317 // Infer the type that should be returned from an Access::oop_load. |
1276 // Infer the type that should be returned from an Access::oop_load. |
1318 template <typename P, DecoratorSet decorators> |
1277 template <typename P, DecoratorSet decorators> |
1319 class OopLoadProxy: public StackObj { |
1278 class OopLoadProxy: public StackObj { |
1320 private: |
1279 private: |
1321 P *const _addr; |
1280 P *const _addr; |