|
1 /* |
|
2 * Copyright (c) 2019, SAP SE. All rights reserved. |
|
3 * Copyright (c) 2019, Oracle and/or its affiliates. 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 |
|
30 #include "utilities/globalDefinitions.hpp" |
|
31 |
|
32 |
|
33 void calc_random_range(size_t outer_range_len, range_t* out, size_t alignment) { |
|
34 |
|
35 assert(is_aligned(outer_range_len, alignment), "bad input range"); |
|
36 assert(outer_range_len > 0, "no zero range"); |
|
37 |
|
38 size_t l1 = os::random() % outer_range_len; |
|
39 size_t l2 = os::random() % outer_range_len; |
|
40 if (l1 > l2) { |
|
41 size_t l = l1; |
|
42 l1 = l2; |
|
43 l2 = l; |
|
44 } |
|
45 l1 = align_down(l1, alignment); |
|
46 l2 = align_up(l2, alignment); |
|
47 |
|
48 // disallow zero range |
|
49 if (l2 == l1) { |
|
50 if (l1 >= alignment) { |
|
51 l1 -= alignment; |
|
52 } else { |
|
53 assert(l2 <= outer_range_len - alignment, "Sanity"); |
|
54 l2 += alignment; |
|
55 } |
|
56 } |
|
57 |
|
58 assert(l2 - l1 > 0 && l2 - l1 <= outer_range_len, "Sanity " SIZE_FORMAT "-" SIZE_FORMAT ".", l1, l2); |
|
59 assert(is_aligned(l1, alignment), "Sanity"); |
|
60 assert(is_aligned(l2, alignment), "Sanity"); |
|
61 |
|
62 out->from = l1; out->to = l2; |
|
63 |
|
64 } |
|
65 |
|
66 void calc_random_address_range(const address_range_t* outer_range, address_range_t* out, size_t alignment) { |
|
67 range_t r; |
|
68 calc_random_range(outer_range->word_size, &r, alignment); |
|
69 |
|
70 out->p = outer_range->p + r.from; |
|
71 out->word_size = r.from - r.to; |
|
72 } |
|
73 |
|
74 size_t get_workingset_size() { |
|
75 #if defined(_WIN32) |
|
76 PROCESS_MEMORY_COUNTERS info; |
|
77 GetProcessMemoryInfo(GetCurrentProcess(), &info, sizeof(info)); |
|
78 return (size_t)info.WorkingSetSize; |
|
79 #elif defined(LINUX) |
|
80 long result = 0L; |
|
81 FILE* f = fopen("/proc/self/statm", "r"); |
|
82 if (f == NULL) { |
|
83 return 0; |
|
84 } |
|
85 // Second number in statm, in num of pages |
|
86 if (fscanf(f, "%*s%ld", &result) != 1 ) { |
|
87 fclose(f); |
|
88 return 0; |
|
89 } |
|
90 fclose(f); |
|
91 return (size_t)result * (size_t)os::vm_page_size(); |
|
92 #else |
|
93 return 0L; |
|
94 #endif |
|
95 } |
|
96 |
|
97 |
|
98 |
|
99 void zap_range(MetaWord* p, size_t word_size) { |
|
100 for (MetaWord* pzap = p; pzap < p + word_size; pzap += os::vm_page_size()) { |
|
101 *pzap = 0; |
|
102 } |
|
103 } |
|
104 |
|
105 |
|
106 |
|
107 // Writes a uniqe pattern to p |
|
108 void mark_address(MetaWord* p, uintx pattern) { |
|
109 MetaWord x = (MetaWord)((uintx) p ^ pattern); |
|
110 *p = x; |
|
111 } |
|
112 |
|
113 // checks pattern at address |
|
114 bool check_marked_address(const MetaWord* p, uintx pattern) { |
|
115 MetaWord x = (MetaWord)((uintx) p ^ pattern); |
|
116 EXPECT_EQ(*p, x); |
|
117 return *p == x; |
|
118 } |
|
119 |
|
120 // "fill_range_with_pattern" fills a range of heap words with pointers to itself. |
|
121 // |
|
122 // The idea is to fill a memory range with a pattern which is both marked clearly to the caller |
|
123 // and cannot be moved without becoming invalid. |
|
124 // |
|
125 // The filled range can be checked with check_range_for_pattern. One also can only check |
|
126 // a sub range of the original range. |
|
127 void fill_range_with_pattern(MetaWord* p, uintx pattern, size_t word_size) { |
|
128 assert(word_size > 0 && p != NULL, "sanity"); |
|
129 for (MetaWord* p2 = p; p2 < p + word_size; p2 ++) { |
|
130 mark_address(p2, pattern); |
|
131 } |
|
132 } |
|
133 |
|
134 bool check_range_for_pattern(const MetaWord* p, uintx pattern, size_t word_size) { |
|
135 assert(word_size > 0 && p != NULL, "sanity"); |
|
136 const MetaWord* p2 = p; |
|
137 while (p2 < p + word_size && check_marked_address(p2, pattern)) { |
|
138 p2 ++; |
|
139 } |
|
140 return p2 < p + word_size; |
|
141 } |
|
142 |
|
143 |
|
144 // Similar to fill_range_with_pattern, but only marks start and end. This is optimized for cases |
|
145 // where fill_range_with_pattern just is too slow. |
|
146 // Use check_marked_range to check the range. In contrast to check_range_for_pattern, only the original |
|
147 // range can be checked. |
|
148 void mark_range(MetaWord* p, uintx pattern, size_t word_size) { |
|
149 assert(word_size > 0 && p != NULL, "sanity"); |
|
150 mark_address(p, pattern); |
|
151 mark_address(p + word_size - 1, pattern); |
|
152 } |
|
153 |
|
154 bool check_marked_range(const MetaWord* p, uintx pattern, size_t word_size) { |
|
155 assert(word_size > 0 && p != NULL, "sanity"); |
|
156 return check_marked_address(p, pattern) && check_marked_address(p + word_size - 1, pattern); |
|
157 } |
|
158 |