hotspot/src/share/vm/utilities/copy.cpp
changeset 36086 f70e100d3195
parent 7397 5b173b4ca846
child 43407 f6dc40ed6ce9
equal deleted inserted replaced
36085:222ab7d1a9bf 36086:f70e100d3195
     1 /*
     1 /*
     2  * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
     2  * Copyright (c) 2006, 2016, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     5  * This code is free software; you can redistribute it and/or modify it
     6  * under the terms of the GNU General Public License version 2 only, as
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.
     7  * published by the Free Software Foundation.
    51     // Not aligned, so no need to be atomic.
    51     // Not aligned, so no need to be atomic.
    52     Copy::conjoint_jbytes((void*) src, (void*) dst, size);
    52     Copy::conjoint_jbytes((void*) src, (void*) dst, size);
    53   }
    53   }
    54 }
    54 }
    55 
    55 
       
    56 class CopySwap : AllStatic {
       
    57 public:
       
    58   /**
       
    59    * Copy and byte swap elements
       
    60    *
       
    61    * @param src address of source
       
    62    * @param dst address of destination
       
    63    * @param byte_count number of bytes to copy
       
    64    * @param elem_size size of the elements to copy-swap
       
    65    */
       
    66   static void conjoint_swap(address src, address dst, size_t byte_count, size_t elem_size) {
       
    67     assert(src != NULL, "address must not be NULL");
       
    68     assert(dst != NULL, "address must not be NULL");
       
    69     assert(elem_size == 2 || elem_size == 4 || elem_size == 8,
       
    70            "incorrect element size: " SIZE_FORMAT, elem_size);
       
    71     assert(is_size_aligned(byte_count, elem_size),
       
    72            "byte_count " SIZE_FORMAT " must be multiple of element size " SIZE_FORMAT, byte_count, elem_size);
       
    73 
       
    74     address src_end = src + byte_count;
       
    75 
       
    76     if (dst <= src || dst >= src_end) {
       
    77       do_conjoint_swap<RIGHT>(src, dst, byte_count, elem_size);
       
    78     } else {
       
    79       do_conjoint_swap<LEFT>(src, dst, byte_count, elem_size);
       
    80     }
       
    81   }
       
    82 
       
    83 private:
       
    84   /**
       
    85    * Byte swap a 16-bit value
       
    86    */
       
    87   static uint16_t byte_swap(uint16_t x) {
       
    88     return (x << 8) | (x >> 8);
       
    89   }
       
    90 
       
    91   /**
       
    92    * Byte swap a 32-bit value
       
    93    */
       
    94   static uint32_t byte_swap(uint32_t x) {
       
    95     uint16_t lo = (uint16_t)x;
       
    96     uint16_t hi = (uint16_t)(x >> 16);
       
    97 
       
    98     return ((uint32_t)byte_swap(lo) << 16) | (uint32_t)byte_swap(hi);
       
    99   }
       
   100 
       
   101   /**
       
   102    * Byte swap a 64-bit value
       
   103    */
       
   104   static uint64_t byte_swap(uint64_t x) {
       
   105     uint32_t lo = (uint32_t)x;
       
   106     uint32_t hi = (uint32_t)(x >> 32);
       
   107 
       
   108     return ((uint64_t)byte_swap(lo) << 32) | (uint64_t)byte_swap(hi);
       
   109   }
       
   110 
       
   111   enum CopyDirection {
       
   112     RIGHT, // lower -> higher address
       
   113     LEFT   // higher -> lower address
       
   114   };
       
   115 
       
   116   /**
       
   117    * Copy and byte swap elements
       
   118    *
       
   119    * <T> - type of element to copy
       
   120    * <D> - copy direction
       
   121    * <is_src_aligned> - true if src argument is aligned to element size
       
   122    * <is_dst_aligned> - true if dst argument is aligned to element size
       
   123    *
       
   124    * @param src address of source
       
   125    * @param dst address of destination
       
   126    * @param byte_count number of bytes to copy
       
   127    */
       
   128   template <typename T, CopyDirection D, bool is_src_aligned, bool is_dst_aligned>
       
   129   static void do_conjoint_swap(address src, address dst, size_t byte_count) {
       
   130     address cur_src, cur_dst;
       
   131 
       
   132     switch (D) {
       
   133     case RIGHT:
       
   134       cur_src = src;
       
   135       cur_dst = dst;
       
   136       break;
       
   137     case LEFT:
       
   138       cur_src = src + byte_count - sizeof(T);
       
   139       cur_dst = dst + byte_count - sizeof(T);
       
   140       break;
       
   141     }
       
   142 
       
   143     for (size_t i = 0; i < byte_count / sizeof(T); i++) {
       
   144       T tmp;
       
   145 
       
   146       if (is_src_aligned) {
       
   147         tmp = *(T*)cur_src;
       
   148       } else {
       
   149         memcpy(&tmp, cur_src, sizeof(T));
       
   150       }
       
   151 
       
   152       tmp = byte_swap(tmp);
       
   153 
       
   154       if (is_dst_aligned) {
       
   155         *(T*)cur_dst = tmp;
       
   156       } else {
       
   157         memcpy(cur_dst, &tmp, sizeof(T));
       
   158       }
       
   159 
       
   160       switch (D) {
       
   161       case RIGHT:
       
   162         cur_src += sizeof(T);
       
   163         cur_dst += sizeof(T);
       
   164         break;
       
   165       case LEFT:
       
   166         cur_src -= sizeof(T);
       
   167         cur_dst -= sizeof(T);
       
   168         break;
       
   169       }
       
   170     }
       
   171   }
       
   172 
       
   173   /**
       
   174    * Copy and byte swap elements
       
   175    *
       
   176    * <T> - type of element to copy
       
   177    * <D> - copy direction
       
   178    *
       
   179    * @param src address of source
       
   180    * @param dst address of destination
       
   181    * @param byte_count number of bytes to copy
       
   182    */
       
   183   template <typename T, CopyDirection direction>
       
   184   static void do_conjoint_swap(address src, address dst, size_t byte_count) {
       
   185     if (is_ptr_aligned(src, sizeof(T))) {
       
   186       if (is_ptr_aligned(dst, sizeof(T))) {
       
   187         do_conjoint_swap<T,direction,true,true>(src, dst, byte_count);
       
   188       } else {
       
   189         do_conjoint_swap<T,direction,true,false>(src, dst, byte_count);
       
   190       }
       
   191     } else {
       
   192       if (is_ptr_aligned(dst, sizeof(T))) {
       
   193         do_conjoint_swap<T,direction,false,true>(src, dst, byte_count);
       
   194       } else {
       
   195         do_conjoint_swap<T,direction,false,false>(src, dst, byte_count);
       
   196       }
       
   197     }
       
   198   }
       
   199 
       
   200 
       
   201   /**
       
   202    * Copy and byte swap elements
       
   203    *
       
   204    * <D> - copy direction
       
   205    *
       
   206    * @param src address of source
       
   207    * @param dst address of destination
       
   208    * @param byte_count number of bytes to copy
       
   209    * @param elem_size size of the elements to copy-swap
       
   210    */
       
   211   template <CopyDirection D>
       
   212   static void do_conjoint_swap(address src, address dst, size_t byte_count, size_t elem_size) {
       
   213     switch (elem_size) {
       
   214     case 2: do_conjoint_swap<uint16_t,D>(src, dst, byte_count); break;
       
   215     case 4: do_conjoint_swap<uint32_t,D>(src, dst, byte_count); break;
       
   216     case 8: do_conjoint_swap<uint64_t,D>(src, dst, byte_count); break;
       
   217     default: guarantee(false, "do_conjoint_swap: Invalid elem_size %zd\n", elem_size);
       
   218     }
       
   219   }
       
   220 };
       
   221 
       
   222 void Copy::conjoint_swap(address src, address dst, size_t byte_count, size_t elem_size) {
       
   223   CopySwap::conjoint_swap(src, dst, byte_count, elem_size);
       
   224 }
    56 
   225 
    57 // Fill bytes; larger units are filled atomically if everything is aligned.
   226 // Fill bytes; larger units are filled atomically if everything is aligned.
    58 void Copy::fill_to_memory_atomic(void* to, size_t size, jubyte value) {
   227 void Copy::fill_to_memory_atomic(void* to, size_t size, jubyte value) {
    59   address dst = (address) to;
   228   address dst = (address) to;
    60   uintptr_t bits = (uintptr_t) to | (uintptr_t) size;
   229   uintptr_t bits = (uintptr_t) to | (uintptr_t) size;