1 /*
   2  * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved.
   3  * Copyright (c) 2018, 2020 SAP SE. All rights reserved.
   4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   5  *
   6  * This code is free software; you can redistribute it and/or modify it
   7  * under the terms of the GNU General Public License version 2 only, as
   8  * published by the Free Software Foundation.
   9  *
  10  * This code is distributed in the hope that it will be useful, but WITHOUT
  11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  12  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  13  * version 2 for more details (a copy is included in the LICENSE file that
  14  * accompanied this code).
  15  *
  16  * You should have received a copy of the GNU General Public License version
  17  * 2 along with this work; if not, write to the Free Software Foundation,
  18  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  19  *
  20  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  21  * or visit www.oracle.com if you need additional information or have any
  22  * questions.
  23  *
  24  */
  25 
  26 #include "precompiled.hpp"
  27 
  28 #include "metaspaceTestsCommon.hpp"
  29 #include "metaspace/metaspace_rangehelpers.hpp"
  30 
  31 #include "utilities/debug.hpp"
  32 #include "utilities/globalDefinitions.hpp"
  33 
  34 
  35 void zap_range(MetaWord* p, size_t word_size) {
  36   for (MetaWord* pzap = p; pzap < p + word_size; pzap += os::vm_page_size() / BytesPerWord) {
  37     *pzap = (MetaWord)NOT_LP64(0xFEFEFEFE) LP64_ONLY(0xFEFEFEFEEFEFEFEFULL);
  38   }
  39 }
  40 
  41 // Writes a uniqe pattern to p
  42 void mark_address(MetaWord* p, uintx pattern) {
  43   MetaWord x = (MetaWord)((uintx) p ^ pattern);
  44   *p = x;
  45 }
  46 
  47 // checks pattern at address
  48 void check_marked_address(const MetaWord* p, uintx pattern) {
  49   MetaWord x = (MetaWord)((uintx) p ^ pattern);
  50   EXPECT_EQ(*p, x);
  51 }
  52 
  53 // "fill_range_with_pattern" fills a range of heap words with pointers to itself.
  54 //
  55 // The idea is to fill a memory range with a pattern which is both marked clearly to the caller
  56 // and cannot be moved without becoming invalid.
  57 //
  58 // The filled range can be checked with check_range_for_pattern. One also can only check
  59 // a sub range of the original range.
  60 void fill_range_with_pattern(MetaWord* p, size_t word_size, uintx pattern) {
  61   assert(word_size > 0 && p != NULL, "sanity");
  62   for (MetaWord* p2 = p; p2 < p + word_size; p2 ++) {
  63     mark_address(p2, pattern);
  64   }
  65 }
  66 
  67 void check_range_for_pattern(const MetaWord* p, size_t word_size, uintx pattern) {
  68   assert(p != NULL, "sanity");
  69   const MetaWord* p2 = p;
  70   while (p2 < p + word_size) {
  71     check_marked_address(p2, pattern);
  72     p2 ++;
  73   }
  74 }
  75 
  76 
  77 // Similar to fill_range_with_pattern, but only marks start and end. This is optimized for cases
  78 // where fill_range_with_pattern just is too slow.
  79 // Use check_marked_range to check the range. In contrast to check_range_for_pattern, only the original
  80 // range can be checked.
  81 void mark_range(MetaWord* p, size_t word_size, uintx pattern) {
  82   assert(word_size > 0 && p != NULL, "sanity");
  83   mark_address(p, pattern);
  84   mark_address(p + word_size - 1, pattern);
  85 }
  86 
  87 void check_marked_range(const MetaWord* p, size_t word_size, uintx pattern) {
  88   assert(word_size > 0 && p != NULL, "sanity");
  89   check_marked_address(p, pattern);
  90   check_marked_address(p + word_size - 1, pattern);
  91 }
  92 
  93 void mark_range(MetaWord* p, size_t word_size) {
  94   assert(word_size > 0 && p != NULL, "sanity");
  95   uintx pattern = (uintx)p2i(p);
  96   mark_range(p, word_size, pattern);
  97 }
  98 
  99 void check_marked_range(const MetaWord* p, size_t word_size) {
 100   uintx pattern = (uintx)p2i(p);
 101   check_marked_range(p, word_size, pattern);
 102 }
 103