hotspot/test/native/utilities/test_align.cpp
changeset 46617 0330c5fc49ce
child 46618 d503911aa948
equal deleted inserted replaced
46616:66d452cca30f 46617:0330c5fc49ce
       
     1 /*
       
     2  * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
       
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       
     4  *
       
     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
       
     7  * published by the Free Software Foundation.
       
     8  *
       
     9  * This code is distributed in the hope that it will be useful, but WITHOUT
       
    10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
       
    11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
       
    12  * version 2 for more details (a copy is included in the LICENSE file that
       
    13  * accompanied this code).
       
    14  *
       
    15  * You should have received a copy of the GNU General Public License version
       
    16  * 2 along with this work; if not, write to the Free Software Foundation,
       
    17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
       
    18  *
       
    19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
       
    20  * or visit www.oracle.com if you need additional information or have any
       
    21  * questions.
       
    22  */
       
    23 
       
    24 #include "precompiled.hpp"
       
    25 #include "utilities/formatBuffer.hpp"
       
    26 #include "utilities/globalDefinitions.hpp"
       
    27 #include "unittest.hpp"
       
    28 
       
    29 #include <limits>
       
    30 
       
    31 // A few arbitrarily chosen values to test the align functions on.
       
    32 static uint64_t values[] = {1, 3, 10, 345, 1023, 1024, 1025, 23909034, INT_MAX, uint64_t(-1) / 2, uint64_t(-1) / 2 + 100, -1 };
       
    33 
       
    34 template <typename T>
       
    35 static T max_alignment() {
       
    36   T max = std::numeric_limits<T>::max();
       
    37   return max ^ (max >> 1);
       
    38 }
       
    39 
       
    40 #define log(...) SCOPED_TRACE(err_msg(__VA_ARGS__).buffer())
       
    41 
       
    42 template <typename T, typename A>
       
    43 static void test_alignments() {
       
    44   log("### Test: %c" SIZE_FORMAT " " UINT64_FORMAT " : %c" SIZE_FORMAT " " UINT64_FORMAT " ###\n",
       
    45       std::numeric_limits<T>::is_signed ? 's' : 'u', sizeof(T), (uint64_t)std::numeric_limits<T>::max(),
       
    46       std::numeric_limits<A>::is_signed ? 's' : 'u', sizeof(A), (uint64_t)std::numeric_limits<A>::max());
       
    47 
       
    48   ASSERT_LE((uint64_t)std::numeric_limits<T>::max(), (uint64_t)std::numeric_limits<intptr_t>::max()) << "The test assumes that casting to intptr_t will not truncate bits";
       
    49 
       
    50   // Test all possible alignment values that fit in type A.
       
    51   for (A alignment = max_alignment<A>(); alignment > 0; alignment >>= 1) {
       
    52     log("=== Alignment: " UINT64_FORMAT " ===\n", (uint64_t)alignment);
       
    53 
       
    54     for (size_t i = 0; i < ARRAY_SIZE(values); i++) {
       
    55       log("--- Value: " UINT64_FORMAT "\n", values[i]);
       
    56 
       
    57       // Test align up
       
    58       const uint64_t up = align_size_up_(values[i], (uint64_t)alignment);
       
    59       if (0 < up && up <= (uint64_t)std::numeric_limits<T>::max()) {
       
    60         log("Testing align_up:   alignment: 0x" UINT64_FORMAT_X " value: 0x" UINT64_FORMAT_X " expected: 0x" UINT64_FORMAT_X "\n", (uint64_t)alignment, values[i], up);
       
    61 
       
    62         T value = T(values[i]);
       
    63 
       
    64         // Check against uint64_t version
       
    65         ASSERT_EQ(align_size_up(value, alignment), (intptr_t)up);
       
    66         // Check inline function vs macro
       
    67         ASSERT_EQ(align_size_up(value, alignment), (intptr_t)align_size_up_(value, alignment));
       
    68         // Sanity check
       
    69         ASSERT_GE(align_size_up(value, alignment), (intptr_t)value);
       
    70       }
       
    71 
       
    72       // Test align down
       
    73       const uint64_t down = align_size_down_(values[i], (uint64_t)alignment);
       
    74       if (down <= (uint64_t)std::numeric_limits<T>::max()) {
       
    75         log("Testing align_size_down: alignment: 0x" UINT64_FORMAT_X " value: 0x" UINT64_FORMAT_X " expected: 0x" UINT64_FORMAT_X "\n", (uint64_t)alignment, values[i], down);
       
    76 
       
    77         T value = T(values[i]);
       
    78 
       
    79         // Check against uint64_t version
       
    80         ASSERT_EQ(align_size_down(value, alignment), (intptr_t)down);
       
    81         // Check inline function vs macro
       
    82         ASSERT_EQ(align_size_down(value, alignment), (intptr_t)align_size_down_(value, alignment));
       
    83         // Sanity check
       
    84         ASSERT_LE(align_size_down(value, alignment), (intptr_t)value);
       
    85       }
       
    86 
       
    87       // Test is aligned
       
    88       const bool is = is_size_aligned_(values[i], (uint64_t)alignment);
       
    89       if (values[i] <= (uint64_t)std::numeric_limits<T>::max()) {
       
    90         log("Testing is_aligned: alignment: 0x" UINT64_FORMAT_X " value: 0x" UINT64_FORMAT_X " expected: %s\n", (uint64_t)alignment, values[i], is ? "true" : "false");
       
    91 
       
    92         T value = T(values[i]);
       
    93 
       
    94         // Check against uint64_t version
       
    95         ASSERT_EQ(is_size_aligned(value, alignment), is);
       
    96         // Check inline function vs macro
       
    97         ASSERT_EQ(is_size_aligned(value, alignment), is_size_aligned_(value, alignment));
       
    98       }
       
    99     }
       
   100   }
       
   101 }
       
   102 
       
   103 TEST(Align, functions_and_macros) {
       
   104   // Test the alignment functions with different type combinations.
       
   105 
       
   106   // The current implementation of the alignment functions use intptr_t
       
   107   // as return and input parameter type. Therefore, we restrict the tested
       
   108   // types on 32-bit platforms.
       
   109 #ifdef _LP64
       
   110   test_alignments<int64_t, uint8_t>();
       
   111   test_alignments<int64_t, uint16_t>();
       
   112   test_alignments<int64_t, uint32_t>();
       
   113   test_alignments<int64_t, int8_t>();
       
   114   test_alignments<int64_t, int16_t>();
       
   115   test_alignments<int64_t, int32_t>();
       
   116   test_alignments<int64_t, int64_t>();
       
   117 
       
   118   test_alignments<uint32_t, uint8_t>();
       
   119   test_alignments<uint32_t, uint16_t>();
       
   120   test_alignments<uint32_t, uint32_t>();
       
   121   test_alignments<uint32_t, int8_t>();
       
   122   test_alignments<uint32_t, int16_t>();
       
   123   test_alignments<uint32_t, int32_t>();
       
   124 #endif
       
   125 
       
   126   test_alignments<int32_t, uint8_t>();
       
   127   test_alignments<int32_t, uint16_t>();
       
   128   test_alignments<int32_t, int8_t>();
       
   129   test_alignments<int32_t, int16_t>();
       
   130   test_alignments<int32_t, int32_t>();
       
   131 
       
   132   test_alignments<uint16_t, uint8_t>();
       
   133   test_alignments<uint16_t, uint16_t>();
       
   134   test_alignments<uint16_t, int8_t>();
       
   135   test_alignments<uint16_t, int16_t>();
       
   136 
       
   137   test_alignments<int16_t, uint8_t>();
       
   138   test_alignments<int16_t, int8_t>();
       
   139   test_alignments<int16_t, int16_t>();
       
   140 
       
   141   test_alignments<uint8_t, int8_t>();
       
   142   test_alignments<uint8_t, uint8_t>();
       
   143 
       
   144   test_alignments<int8_t, int8_t>();
       
   145 }