230 // Helper for inline_unsafe_access. |
230 // Helper for inline_unsafe_access. |
231 // Generates the guards that check whether the result of |
231 // Generates the guards that check whether the result of |
232 // Unsafe.getObject should be recorded in an SATB log buffer. |
232 // Unsafe.getObject should be recorded in an SATB log buffer. |
233 void insert_pre_barrier(Node* base_oop, Node* offset, Node* pre_val, bool need_mem_bar); |
233 void insert_pre_barrier(Node* base_oop, Node* offset, Node* pre_val, bool need_mem_bar); |
234 bool inline_unsafe_access(bool is_native_ptr, bool is_store, BasicType type, bool is_volatile); |
234 bool inline_unsafe_access(bool is_native_ptr, bool is_store, BasicType type, bool is_volatile); |
235 bool inline_unsafe_prefetch(bool is_native_ptr, bool is_store, bool is_static); |
|
236 static bool klass_needs_init_guard(Node* kls); |
235 static bool klass_needs_init_guard(Node* kls); |
237 bool inline_unsafe_allocate(); |
236 bool inline_unsafe_allocate(); |
238 bool inline_unsafe_copyMemory(); |
237 bool inline_unsafe_copyMemory(); |
239 bool inline_native_currentThread(); |
238 bool inline_native_currentThread(); |
240 #ifdef TRACE_HAVE_INTRINSICS |
239 #ifdef TRACE_HAVE_INTRINSICS |
793 case vmIntrinsics::_putCharVolatile: return inline_unsafe_access(!is_native_ptr, is_store, T_CHAR, is_volatile); |
792 case vmIntrinsics::_putCharVolatile: return inline_unsafe_access(!is_native_ptr, is_store, T_CHAR, is_volatile); |
794 case vmIntrinsics::_putIntVolatile: return inline_unsafe_access(!is_native_ptr, is_store, T_INT, is_volatile); |
793 case vmIntrinsics::_putIntVolatile: return inline_unsafe_access(!is_native_ptr, is_store, T_INT, is_volatile); |
795 case vmIntrinsics::_putLongVolatile: return inline_unsafe_access(!is_native_ptr, is_store, T_LONG, is_volatile); |
794 case vmIntrinsics::_putLongVolatile: return inline_unsafe_access(!is_native_ptr, is_store, T_LONG, is_volatile); |
796 case vmIntrinsics::_putFloatVolatile: return inline_unsafe_access(!is_native_ptr, is_store, T_FLOAT, is_volatile); |
795 case vmIntrinsics::_putFloatVolatile: return inline_unsafe_access(!is_native_ptr, is_store, T_FLOAT, is_volatile); |
797 case vmIntrinsics::_putDoubleVolatile: return inline_unsafe_access(!is_native_ptr, is_store, T_DOUBLE, is_volatile); |
796 case vmIntrinsics::_putDoubleVolatile: return inline_unsafe_access(!is_native_ptr, is_store, T_DOUBLE, is_volatile); |
798 |
|
799 case vmIntrinsics::_prefetchRead: return inline_unsafe_prefetch(!is_native_ptr, !is_store, !is_static); |
|
800 case vmIntrinsics::_prefetchWrite: return inline_unsafe_prefetch(!is_native_ptr, is_store, !is_static); |
|
801 case vmIntrinsics::_prefetchReadStatic: return inline_unsafe_prefetch(!is_native_ptr, !is_store, is_static); |
|
802 case vmIntrinsics::_prefetchWriteStatic: return inline_unsafe_prefetch(!is_native_ptr, is_store, is_static); |
|
803 |
797 |
804 case vmIntrinsics::_compareAndSwapObject: return inline_unsafe_load_store(T_OBJECT, LS_cmpxchg); |
798 case vmIntrinsics::_compareAndSwapObject: return inline_unsafe_load_store(T_OBJECT, LS_cmpxchg); |
805 case vmIntrinsics::_compareAndSwapInt: return inline_unsafe_load_store(T_INT, LS_cmpxchg); |
799 case vmIntrinsics::_compareAndSwapInt: return inline_unsafe_load_store(T_INT, LS_cmpxchg); |
806 case vmIntrinsics::_compareAndSwapLong: return inline_unsafe_load_store(T_LONG, LS_cmpxchg); |
800 case vmIntrinsics::_compareAndSwapLong: return inline_unsafe_load_store(T_LONG, LS_cmpxchg); |
807 |
801 |
2689 } |
2683 } |
2690 } |
2684 } |
2691 } |
2685 } |
2692 |
2686 |
2693 if (need_mem_bar) insert_mem_bar(Op_MemBarCPUOrder); |
2687 if (need_mem_bar) insert_mem_bar(Op_MemBarCPUOrder); |
2694 |
|
2695 return true; |
|
2696 } |
|
2697 |
|
2698 //----------------------------inline_unsafe_prefetch---------------------------- |
|
2699 |
|
2700 bool LibraryCallKit::inline_unsafe_prefetch(bool is_native_ptr, bool is_store, bool is_static) { |
|
2701 #ifndef PRODUCT |
|
2702 { |
|
2703 ResourceMark rm; |
|
2704 // Check the signatures. |
|
2705 ciSignature* sig = callee()->signature(); |
|
2706 #ifdef ASSERT |
|
2707 // Object getObject(Object base, int/long offset), etc. |
|
2708 BasicType rtype = sig->return_type()->basic_type(); |
|
2709 if (!is_native_ptr) { |
|
2710 assert(sig->count() == 2, "oop prefetch has 2 arguments"); |
|
2711 assert(sig->type_at(0)->basic_type() == T_OBJECT, "prefetch base is object"); |
|
2712 assert(sig->type_at(1)->basic_type() == T_LONG, "prefetcha offset is correct"); |
|
2713 } else { |
|
2714 assert(sig->count() == 1, "native prefetch has 1 argument"); |
|
2715 assert(sig->type_at(0)->basic_type() == T_LONG, "prefetch base is long"); |
|
2716 } |
|
2717 #endif // ASSERT |
|
2718 } |
|
2719 #endif // !PRODUCT |
|
2720 |
|
2721 C->set_has_unsafe_access(true); // Mark eventual nmethod as "unsafe". |
|
2722 |
|
2723 const int idx = is_static ? 0 : 1; |
|
2724 if (!is_static) { |
|
2725 null_check_receiver(); |
|
2726 if (stopped()) { |
|
2727 return true; |
|
2728 } |
|
2729 } |
|
2730 |
|
2731 // Build address expression. See the code in inline_unsafe_access. |
|
2732 Node *adr; |
|
2733 if (!is_native_ptr) { |
|
2734 // The base is either a Java object or a value produced by Unsafe.staticFieldBase |
|
2735 Node* base = argument(idx + 0); // type: oop |
|
2736 // The offset is a value produced by Unsafe.staticFieldOffset or Unsafe.objectFieldOffset |
|
2737 Node* offset = argument(idx + 1); // type: long |
|
2738 // We currently rely on the cookies produced by Unsafe.xxxFieldOffset |
|
2739 // to be plain byte offsets, which are also the same as those accepted |
|
2740 // by oopDesc::field_base. |
|
2741 assert(Unsafe_field_offset_to_byte_offset(11) == 11, |
|
2742 "fieldOffset must be byte-scaled"); |
|
2743 // 32-bit machines ignore the high half! |
|
2744 offset = ConvL2X(offset); |
|
2745 adr = make_unsafe_address(base, offset); |
|
2746 } else { |
|
2747 Node* ptr = argument(idx + 0); // type: long |
|
2748 ptr = ConvL2X(ptr); // adjust Java long to machine word |
|
2749 adr = make_unsafe_address(NULL, ptr); |
|
2750 } |
|
2751 |
|
2752 // Generate the read or write prefetch |
|
2753 Node *prefetch; |
|
2754 if (is_store) { |
|
2755 prefetch = new PrefetchWriteNode(i_o(), adr); |
|
2756 } else { |
|
2757 prefetch = new PrefetchReadNode(i_o(), adr); |
|
2758 } |
|
2759 prefetch->init_req(0, control()); |
|
2760 set_i_o(_gvn.transform(prefetch)); |
|
2761 |
2688 |
2762 return true; |
2689 return true; |
2763 } |
2690 } |
2764 |
2691 |
2765 //----------------------------inline_unsafe_load_store---------------------------- |
2692 //----------------------------inline_unsafe_load_store---------------------------- |