jdk

Форк
0
/
test_virtualspace.cpp 
682 строки · 27.3 Кб
1
/*
2
 * Copyright (c) 2018, 2024, 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 "memory/virtualspace.hpp"
26
#include "oops/oop.hpp"
27
#include "runtime/os.hpp"
28
#include "utilities/align.hpp"
29
#include "concurrentTestRunner.inline.hpp"
30
#include "unittest.hpp"
31

32
namespace {
33
  class MemoryReleaser {
34
    ReservedSpace* const _rs;
35
   public:
36
    MemoryReleaser(ReservedSpace* rs) : _rs(rs) { }
37
    ~MemoryReleaser() {
38
      if (_rs->special()) {
39
        EXPECT_TRUE(os::release_memory_special(_rs->base(), _rs->size()));
40
      } else {
41
        EXPECT_TRUE(os::release_memory(_rs->base(), _rs->size()));
42
      }
43
    }
44
  };
45

46
  static void small_page_write(void* addr, size_t size) {
47
    size_t page_size = os::vm_page_size();
48

49
    char* end = (char*) addr + size;
50
    for (char* p = (char*) addr; p < end; p += page_size) {
51
      *p = 1;
52
    }
53
  }
54

55
  // have to use these functions, as gtest's _PRED macros don't like is_aligned
56
  // nor (is_aligned<size_t, size_t>)
57
  static bool is_size_aligned(size_t size, size_t alignment) {
58
    return is_aligned(size, alignment);
59
  }
60
  static bool is_ptr_aligned(void* ptr, size_t alignment) {
61
    return is_aligned(ptr, alignment);
62
  }
63

64
  static void test_reserved_size(size_t size) {
65
    ASSERT_PRED2(is_size_aligned, size, os::vm_allocation_granularity());
66

67
    ReservedSpace rs(size);
68
    MemoryReleaser releaser(&rs);
69

70
    EXPECT_TRUE(rs.base() != nullptr) << "rs.special: " << rs.special();
71
    EXPECT_EQ(size, rs.size()) << "rs.special: " << rs.special();
72

73
    if (rs.special()) {
74
      small_page_write(rs.base(), size);
75
    }
76
  }
77

78
  static void test_reserved_size_alignment(size_t size, size_t alignment) {
79
    ASSERT_PRED2(is_size_aligned, size, alignment) << "Incorrect input parameters";
80
    size_t page_size = UseLargePages ? os::large_page_size() : os::vm_page_size();
81
    ReservedSpace rs(size, alignment, page_size, (char *) nullptr);
82

83
    ASSERT_TRUE(rs.base() != nullptr) << "rs.special = " << rs.special();
84
    ASSERT_EQ(size, rs.size()) << "rs.special = " << rs.special();
85

86
    EXPECT_PRED2(is_ptr_aligned, rs.base(), alignment)
87
            << "aligned sizes should always give aligned addresses";
88
    EXPECT_PRED2(is_ptr_aligned, (void*) rs.size(), alignment)
89
            << "aligned sizes should always give aligned addresses";
90

91
    if (rs.special()) {
92
      small_page_write(rs.base(), size);
93
    }
94
  }
95

96
  static void test_reserved_size_alignment_page_type(size_t size, size_t alignment, bool maybe_large) {
97
    if (size < alignment) {
98
      // Tests might set -XX:LargePageSizeInBytes=<small pages> and cause unexpected input arguments for this test.
99
      ASSERT_EQ(os::vm_page_size(), os::large_page_size()) << "Test needs further refinement";
100
      return;
101
    }
102

103
    ASSERT_PRED2(is_size_aligned, size, os::vm_allocation_granularity()) << "Must be at least AG aligned";
104
    ASSERT_PRED2(is_size_aligned, size, alignment) << "Must be at least AG aligned";
105

106
    bool large = maybe_large && UseLargePages && size >= os::large_page_size();
107
    size_t page_size = large ? os::large_page_size() : os::vm_page_size();
108

109
    ReservedSpace rs(size, alignment, page_size);
110
    MemoryReleaser releaser(&rs);
111

112
    EXPECT_TRUE(rs.base() != nullptr) << "rs.special: " << rs.special();
113
    EXPECT_EQ(size, rs.size()) << "rs.special: " << rs.special();
114

115
    if (rs.special()) {
116
      small_page_write(rs.base(), size);
117
    }
118
  }
119
}
120

121
TEST_VM(ReservedSpace, size_alignment) {
122
  size_t size = 2 * 1024 * 1024;
123
  size_t ag   = os::vm_allocation_granularity();
124

125
  EXPECT_NO_FATAL_FAILURE(test_reserved_size_alignment(size,      ag));
126
  EXPECT_NO_FATAL_FAILURE(test_reserved_size_alignment(size * 2,  ag));
127
  EXPECT_NO_FATAL_FAILURE(test_reserved_size_alignment(size * 10, ag));
128
}
129

130
TEST_VM(ReservedSpace, size) {
131
  size_t size = 2 * 1024 * 1024;
132
  size_t ag = os::vm_allocation_granularity();
133

134
  EXPECT_NO_FATAL_FAILURE(test_reserved_size(size * 1));
135
  EXPECT_NO_FATAL_FAILURE(test_reserved_size(size * 2));
136
  EXPECT_NO_FATAL_FAILURE(test_reserved_size(size * 10));
137
  EXPECT_NO_FATAL_FAILURE(test_reserved_size(ag));
138
  EXPECT_NO_FATAL_FAILURE(test_reserved_size(size - ag));
139
  EXPECT_NO_FATAL_FAILURE(test_reserved_size(size));
140
  EXPECT_NO_FATAL_FAILURE(test_reserved_size(size + ag));
141
  EXPECT_NO_FATAL_FAILURE(test_reserved_size(size * 2));
142
  EXPECT_NO_FATAL_FAILURE(test_reserved_size(size * 2 - ag));
143
  EXPECT_NO_FATAL_FAILURE(test_reserved_size(size * 2 + ag));
144
  EXPECT_NO_FATAL_FAILURE(test_reserved_size(size * 3));
145
  EXPECT_NO_FATAL_FAILURE(test_reserved_size(size * 3 - ag));
146
  EXPECT_NO_FATAL_FAILURE(test_reserved_size(size * 3 + ag));
147
  EXPECT_NO_FATAL_FAILURE(test_reserved_size(size * 10));
148
  EXPECT_NO_FATAL_FAILURE(test_reserved_size(size * 10 + size / 2));
149
}
150

151
TEST_VM(ReservedSpace, size_alignment_page_type) {
152
  size_t ag = os::vm_allocation_granularity();
153

154
  EXPECT_NO_FATAL_FAILURE(test_reserved_size_alignment_page_type(ag,      ag    , false));
155
  EXPECT_NO_FATAL_FAILURE(test_reserved_size_alignment_page_type(ag * 2,  ag    , false));
156
  EXPECT_NO_FATAL_FAILURE(test_reserved_size_alignment_page_type(ag * 3,  ag    , false));
157
  EXPECT_NO_FATAL_FAILURE(test_reserved_size_alignment_page_type(ag * 2,  ag * 2, false));
158
  EXPECT_NO_FATAL_FAILURE(test_reserved_size_alignment_page_type(ag * 4,  ag * 2, false));
159
  EXPECT_NO_FATAL_FAILURE(test_reserved_size_alignment_page_type(ag * 8,  ag * 2, false));
160
  EXPECT_NO_FATAL_FAILURE(test_reserved_size_alignment_page_type(ag * 4,  ag * 4, false));
161
  EXPECT_NO_FATAL_FAILURE(test_reserved_size_alignment_page_type(ag * 8,  ag * 4, false));
162
  EXPECT_NO_FATAL_FAILURE(test_reserved_size_alignment_page_type(ag * 16, ag * 4, false));
163
}
164

165
TEST_VM(ReservedSpace, size_alignment_page_type_large_page) {
166
  if (!UseLargePages) {
167
    return;
168
  }
169

170
  size_t ag = os::vm_allocation_granularity();
171
  size_t lp = os::large_page_size();
172

173
  // Without large pages
174
  EXPECT_NO_FATAL_FAILURE(test_reserved_size_alignment_page_type(lp,     ag * 4, false));
175
  EXPECT_NO_FATAL_FAILURE(test_reserved_size_alignment_page_type(lp * 2, ag * 4, false));
176
  EXPECT_NO_FATAL_FAILURE(test_reserved_size_alignment_page_type(lp * 4, ag * 4, false));
177
  EXPECT_NO_FATAL_FAILURE(test_reserved_size_alignment_page_type(lp,     lp    , false));
178
  EXPECT_NO_FATAL_FAILURE(test_reserved_size_alignment_page_type(lp * 2, lp    , false));
179
  EXPECT_NO_FATAL_FAILURE(test_reserved_size_alignment_page_type(lp * 3, lp    , false));
180
  EXPECT_NO_FATAL_FAILURE(test_reserved_size_alignment_page_type(lp * 2, lp * 2, false));
181
  EXPECT_NO_FATAL_FAILURE(test_reserved_size_alignment_page_type(lp * 4, lp * 2, false));
182
  EXPECT_NO_FATAL_FAILURE(test_reserved_size_alignment_page_type(lp * 8, lp * 2, false));
183

184
  // With large pages
185
  EXPECT_NO_FATAL_FAILURE(test_reserved_size_alignment_page_type(lp, ag * 4    , true));
186
  EXPECT_NO_FATAL_FAILURE(test_reserved_size_alignment_page_type(lp * 2, ag * 4, true));
187
  EXPECT_NO_FATAL_FAILURE(test_reserved_size_alignment_page_type(lp * 4, ag * 4, true));
188
  EXPECT_NO_FATAL_FAILURE(test_reserved_size_alignment_page_type(lp, lp        , true));
189
  EXPECT_NO_FATAL_FAILURE(test_reserved_size_alignment_page_type(lp * 2, lp    , true));
190
  EXPECT_NO_FATAL_FAILURE(test_reserved_size_alignment_page_type(lp * 3, lp    , true));
191
  EXPECT_NO_FATAL_FAILURE(test_reserved_size_alignment_page_type(lp * 2, lp * 2, true));
192
  EXPECT_NO_FATAL_FAILURE(test_reserved_size_alignment_page_type(lp * 4, lp * 2, true));
193
  EXPECT_NO_FATAL_FAILURE(test_reserved_size_alignment_page_type(lp * 8, lp * 2, true));
194
}
195

196
namespace {
197
  enum TestLargePages {
198
    Default,
199
    Disable,
200
    Reserve,
201
    Commit
202
  };
203

204
  class ReservedSpaceReleaser {
205
    ReservedSpace* const _rs;
206
   public:
207
    ReservedSpaceReleaser(ReservedSpace* rs) : _rs(rs) { }
208
    ~ReservedSpaceReleaser() {
209
      _rs->release();
210
    }
211
  };
212

213
  ReservedSpace reserve_memory(size_t reserve_size_aligned, TestLargePages mode) {
214
    switch(mode) {
215
      default:
216
      case Default:
217
      case Reserve:
218
        return ReservedSpace(reserve_size_aligned);
219
      case Disable:
220
      case Commit:
221
        return ReservedSpace(reserve_size_aligned,
222
                             os::vm_allocation_granularity(),
223
                             os::vm_page_size());
224
    }
225
  }
226

227
  bool initialize_virtual_space(VirtualSpace& vs, ReservedSpace rs, TestLargePages mode) {
228
    switch(mode) {
229
      default:
230
      case Default:
231
      case Reserve:
232
        return vs.initialize(rs, 0);
233
      case Disable:
234
        return vs.initialize_with_granularity(rs, 0, os::vm_page_size());
235
      case Commit:
236
        return vs.initialize_with_granularity(rs, 0, os::page_size_for_region_unaligned(rs.size(), 1));
237
    }
238
  }
239

240
 void test_virtual_space_actual_committed_space(size_t reserve_size, size_t commit_size,
241
                                                TestLargePages mode = Default) {
242
    size_t granularity = os::vm_allocation_granularity();
243
    size_t reserve_size_aligned = align_up(reserve_size, granularity);
244

245
    ReservedSpace reserved = reserve_memory(reserve_size_aligned, mode);
246
    ReservedSpaceReleaser releaser(&reserved);
247

248
    ASSERT_TRUE(reserved.is_reserved());
249

250
    VirtualSpace vs;
251
    ASSERT_TRUE(initialize_virtual_space(vs, reserved, mode)) << "Failed to initialize VirtualSpace";
252
    vs.expand_by(commit_size, false);
253

254
    if (vs.special()) {
255
      EXPECT_EQ(reserve_size_aligned, vs.actual_committed_size());
256
    } else {
257
      EXPECT_GE(vs.actual_committed_size(), commit_size);
258
      // Approximate the commit granularity.
259
      // Make sure that we don't commit using large pages
260
      // if large pages has been disabled for this VirtualSpace.
261
      size_t commit_granularity = (mode == Disable || !UseLargePages) ?
262
                                   os::vm_page_size() : os::large_page_size();
263
      EXPECT_LT(vs.actual_committed_size(), commit_size + commit_granularity);
264
    }
265
  }
266
}
267

268
TEST_VM(VirtualSpace, actual_committed_space) {
269
  EXPECT_NO_FATAL_FAILURE(test_virtual_space_actual_committed_space(4 * K,  0));
270
  EXPECT_NO_FATAL_FAILURE(test_virtual_space_actual_committed_space(4 * K,  4 * K));
271
  EXPECT_NO_FATAL_FAILURE(test_virtual_space_actual_committed_space(8 * K,  0));
272
  EXPECT_NO_FATAL_FAILURE(test_virtual_space_actual_committed_space(8 * K,  4 * K));
273
  EXPECT_NO_FATAL_FAILURE(test_virtual_space_actual_committed_space(8 * K,  8 * K));
274
  EXPECT_NO_FATAL_FAILURE(test_virtual_space_actual_committed_space(12 * K, 0));
275
  EXPECT_NO_FATAL_FAILURE(test_virtual_space_actual_committed_space(12 * K, 4 * K));
276
  EXPECT_NO_FATAL_FAILURE(test_virtual_space_actual_committed_space(12 * K, 8 * K));
277
  EXPECT_NO_FATAL_FAILURE(test_virtual_space_actual_committed_space(12 * K, 12 * K));
278
  EXPECT_NO_FATAL_FAILURE(test_virtual_space_actual_committed_space(64 * K, 0));
279
  EXPECT_NO_FATAL_FAILURE(test_virtual_space_actual_committed_space(64 * K, 32 * K));
280
  EXPECT_NO_FATAL_FAILURE(test_virtual_space_actual_committed_space(64 * K, 64 * K));
281
  EXPECT_NO_FATAL_FAILURE(test_virtual_space_actual_committed_space(2 * M,  0));
282
  EXPECT_NO_FATAL_FAILURE(test_virtual_space_actual_committed_space(2 * M,  4 * K));
283
  EXPECT_NO_FATAL_FAILURE(test_virtual_space_actual_committed_space(2 * M,  64 * K));
284
  EXPECT_NO_FATAL_FAILURE(test_virtual_space_actual_committed_space(2 * M,  1 * M));
285
  EXPECT_NO_FATAL_FAILURE(test_virtual_space_actual_committed_space(2 * M,  2 * M));
286
  EXPECT_NO_FATAL_FAILURE(test_virtual_space_actual_committed_space(10 * M, 0));
287
  EXPECT_NO_FATAL_FAILURE(test_virtual_space_actual_committed_space(10 * M, 4 * K));
288
  EXPECT_NO_FATAL_FAILURE(test_virtual_space_actual_committed_space(10 * M, 8 * K));
289
  EXPECT_NO_FATAL_FAILURE(test_virtual_space_actual_committed_space(10 * M, 1 * M));
290
  EXPECT_NO_FATAL_FAILURE(test_virtual_space_actual_committed_space(10 * M, 2 * M));
291
  EXPECT_NO_FATAL_FAILURE(test_virtual_space_actual_committed_space(10 * M, 5 * M));
292
  EXPECT_NO_FATAL_FAILURE(test_virtual_space_actual_committed_space(10 * M, 10 * M));
293
}
294

295
TEST_VM(VirtualSpace, actual_committed_space_one_large_page) {
296
  if (!UseLargePages) {
297
    return;
298
  }
299

300
  size_t large_page_size = os::large_page_size();
301

302
  ReservedSpace reserved(large_page_size, large_page_size, large_page_size);
303
  ReservedSpaceReleaser releaser(&reserved);
304
  ASSERT_TRUE(reserved.is_reserved());
305

306
  VirtualSpace vs;
307
  ASSERT_TRUE(vs.initialize(reserved, 0)) << "Failed to initialize VirtualSpace";
308
  vs.expand_by(large_page_size, false);
309

310
  EXPECT_EQ(large_page_size, vs.actual_committed_size());
311
}
312

313
TEST_VM(VirtualSpace, disable_large_pages) {
314
  if (!UseLargePages) {
315
    return;
316
  }
317
  // These test cases verify that if we force VirtualSpace to disable large pages
318
  EXPECT_NO_FATAL_FAILURE(test_virtual_space_actual_committed_space(10 * M, 0,      Disable));
319
  EXPECT_NO_FATAL_FAILURE(test_virtual_space_actual_committed_space(10 * M, 4 * K,  Disable));
320
  EXPECT_NO_FATAL_FAILURE(test_virtual_space_actual_committed_space(10 * M, 8 * K,  Disable));
321
  EXPECT_NO_FATAL_FAILURE(test_virtual_space_actual_committed_space(10 * M, 1 * M,  Disable));
322
  EXPECT_NO_FATAL_FAILURE(test_virtual_space_actual_committed_space(10 * M, 2 * M,  Disable));
323
  EXPECT_NO_FATAL_FAILURE(test_virtual_space_actual_committed_space(10 * M, 5 * M,  Disable));
324
  EXPECT_NO_FATAL_FAILURE(test_virtual_space_actual_committed_space(10 * M, 10 * M, Disable));
325

326
  EXPECT_NO_FATAL_FAILURE(test_virtual_space_actual_committed_space(10 * M, 0,      Reserve));
327
  EXPECT_NO_FATAL_FAILURE(test_virtual_space_actual_committed_space(10 * M, 4 * K,  Reserve));
328
  EXPECT_NO_FATAL_FAILURE(test_virtual_space_actual_committed_space(10 * M, 8 * K,  Reserve));
329
  EXPECT_NO_FATAL_FAILURE(test_virtual_space_actual_committed_space(10 * M, 1 * M,  Reserve));
330
  EXPECT_NO_FATAL_FAILURE(test_virtual_space_actual_committed_space(10 * M, 2 * M,  Reserve));
331
  EXPECT_NO_FATAL_FAILURE(test_virtual_space_actual_committed_space(10 * M, 5 * M,  Reserve));
332
  EXPECT_NO_FATAL_FAILURE(test_virtual_space_actual_committed_space(10 * M, 10 * M, Reserve));
333

334
  EXPECT_NO_FATAL_FAILURE(test_virtual_space_actual_committed_space(10 * M, 0,      Commit));
335
  EXPECT_NO_FATAL_FAILURE(test_virtual_space_actual_committed_space(10 * M, 4 * K,  Commit));
336
  EXPECT_NO_FATAL_FAILURE(test_virtual_space_actual_committed_space(10 * M, 8 * K,  Commit));
337
  EXPECT_NO_FATAL_FAILURE(test_virtual_space_actual_committed_space(10 * M, 1 * M,  Commit));
338
  EXPECT_NO_FATAL_FAILURE(test_virtual_space_actual_committed_space(10 * M, 2 * M,  Commit));
339
  EXPECT_NO_FATAL_FAILURE(test_virtual_space_actual_committed_space(10 * M, 5 * M,  Commit));
340
  EXPECT_NO_FATAL_FAILURE(test_virtual_space_actual_committed_space(10 * M, 10 * M, Commit));
341
}
342

343

344
// ========================= concurrent virtual space memory tests
345
// This class have been imported from the original "internal VM test" with minor modification,
346
// specifically using GTest asserts instead of native HotSpot asserts.
347
class TestReservedSpace : AllStatic {
348
 public:
349
  static void small_page_write(void* addr, size_t size) {
350
    size_t page_size = os::vm_page_size();
351

352
    char* end = (char*)addr + size;
353
    for (char* p = (char*)addr; p < end; p += page_size) {
354
      *p = 1;
355
    }
356
  }
357

358
  static void release_memory_for_test(ReservedSpace rs) {
359
    if (rs.special()) {
360
      EXPECT_TRUE(os::release_memory_special(rs.base(), rs.size()));
361
    } else {
362
      EXPECT_TRUE(os::release_memory(rs.base(), rs.size()));
363
    }
364
  }
365

366
  static void test_reserved_space1(size_t size, size_t alignment) {
367
    ASSERT_TRUE(is_aligned(size, alignment)) << "Incorrect input parameters";
368
    size_t page_size = UseLargePages ? os::large_page_size() : os::vm_page_size();
369
    ReservedSpace rs(size,          // size
370
                     alignment,     // alignment
371
                     page_size, // page size
372
                     (char *)nullptr); // requested_address
373

374
    EXPECT_TRUE(rs.base() != nullptr);
375
    EXPECT_EQ(rs.size(), size) <<  "rs.size: " << rs.size();
376

377
    EXPECT_TRUE(is_aligned(rs.base(), alignment)) << "aligned sizes should always give aligned addresses";
378
    EXPECT_TRUE(is_aligned(rs.size(), alignment)) <<  "aligned sizes should always give aligned addresses";
379

380
    if (rs.special()) {
381
      small_page_write(rs.base(), size);
382
    }
383

384
    release_memory_for_test(rs);
385
  }
386

387
  static void test_reserved_space2(size_t size) {
388
    ASSERT_TRUE(is_aligned(size, os::vm_allocation_granularity())) << "Must be at least AG aligned";
389

390
    ReservedSpace rs(size);
391

392
    EXPECT_TRUE(rs.base() != nullptr);
393
    EXPECT_EQ(rs.size(), size) <<  "rs.size: " << rs.size();
394

395
    if (rs.special()) {
396
      small_page_write(rs.base(), size);
397
    }
398

399
    release_memory_for_test(rs);
400
  }
401

402
  static void test_reserved_space3(size_t size, size_t alignment, bool maybe_large) {
403
    if (size < alignment) {
404
      // Tests might set -XX:LargePageSizeInBytes=<small pages> and cause unexpected input arguments for this test.
405
      ASSERT_EQ(os::vm_page_size(), os::large_page_size()) << "Test needs further refinement";
406
      return;
407
    }
408

409
    EXPECT_TRUE(is_aligned(size, os::vm_allocation_granularity())) << "Must be at least AG aligned";
410
    EXPECT_TRUE(is_aligned(size, alignment)) << "Must be at least aligned against alignment";
411

412
    bool large = maybe_large && UseLargePages && size >= os::large_page_size();
413
    size_t page_size = large ? os::large_page_size() : os::vm_page_size();
414

415
    ReservedSpace rs(size, alignment, page_size);
416

417
    EXPECT_TRUE(rs.base() != nullptr);
418
    EXPECT_EQ(rs.size(), size) <<  "rs.size: " << rs.size();
419

420
    if (rs.special()) {
421
      small_page_write(rs.base(), size);
422
    }
423

424
    release_memory_for_test(rs);
425
  }
426

427

428
  static void test_reserved_space1() {
429
    size_t size = 2 * 1024 * 1024;
430
    size_t ag   = os::vm_allocation_granularity();
431

432
    test_reserved_space1(size,      ag);
433
    test_reserved_space1(size * 2,  ag);
434
    test_reserved_space1(size * 10, ag);
435
  }
436

437
  static void test_reserved_space2() {
438
    size_t size = 2 * 1024 * 1024;
439
    size_t ag = os::vm_allocation_granularity();
440

441
    test_reserved_space2(size * 1);
442
    test_reserved_space2(size * 2);
443
    test_reserved_space2(size * 10);
444
    test_reserved_space2(ag);
445
    test_reserved_space2(size - ag);
446
    test_reserved_space2(size);
447
    test_reserved_space2(size + ag);
448
    test_reserved_space2(size * 2);
449
    test_reserved_space2(size * 2 - ag);
450
    test_reserved_space2(size * 2 + ag);
451
    test_reserved_space2(size * 3);
452
    test_reserved_space2(size * 3 - ag);
453
    test_reserved_space2(size * 3 + ag);
454
    test_reserved_space2(size * 10);
455
    test_reserved_space2(size * 10 + size / 2);
456
  }
457

458
  static void test_reserved_space3() {
459
    size_t ag = os::vm_allocation_granularity();
460

461
    test_reserved_space3(ag,      ag    , false);
462
    test_reserved_space3(ag * 2,  ag    , false);
463
    test_reserved_space3(ag * 3,  ag    , false);
464
    test_reserved_space3(ag * 2,  ag * 2, false);
465
    test_reserved_space3(ag * 4,  ag * 2, false);
466
    test_reserved_space3(ag * 8,  ag * 2, false);
467
    test_reserved_space3(ag * 4,  ag * 4, false);
468
    test_reserved_space3(ag * 8,  ag * 4, false);
469
    test_reserved_space3(ag * 16, ag * 4, false);
470

471
    if (UseLargePages) {
472
      size_t lp = os::large_page_size();
473

474
      // Without large pages
475
      test_reserved_space3(lp,     ag * 4, false);
476
      test_reserved_space3(lp * 2, ag * 4, false);
477
      test_reserved_space3(lp * 4, ag * 4, false);
478
      test_reserved_space3(lp,     lp    , false);
479
      test_reserved_space3(lp * 2, lp    , false);
480
      test_reserved_space3(lp * 3, lp    , false);
481
      test_reserved_space3(lp * 2, lp * 2, false);
482
      test_reserved_space3(lp * 4, lp * 2, false);
483
      test_reserved_space3(lp * 8, lp * 2, false);
484

485
      // With large pages
486
      test_reserved_space3(lp, ag * 4    , true);
487
      test_reserved_space3(lp * 2, ag * 4, true);
488
      test_reserved_space3(lp * 4, ag * 4, true);
489
      test_reserved_space3(lp, lp        , true);
490
      test_reserved_space3(lp * 2, lp    , true);
491
      test_reserved_space3(lp * 3, lp    , true);
492
      test_reserved_space3(lp * 2, lp * 2, true);
493
      test_reserved_space3(lp * 4, lp * 2, true);
494
      test_reserved_space3(lp * 8, lp * 2, true);
495
    }
496
  }
497

498
  static void test_reserved_space() {
499
    test_reserved_space1();
500
    test_reserved_space2();
501
    test_reserved_space3();
502
  }
503
};
504

505

506
class TestVirtualSpace : AllStatic {
507
  enum TestLargePages {
508
    Default,
509
    Disable,
510
    Reserve,
511
    Commit
512
  };
513

514
  static ReservedSpace reserve_memory(size_t reserve_size_aligned, TestLargePages mode) {
515
    switch(mode) {
516
    default:
517
    case Default:
518
    case Reserve:
519
      return ReservedSpace(reserve_size_aligned);
520
    case Disable:
521
    case Commit:
522
      return ReservedSpace(reserve_size_aligned,
523
                           os::vm_allocation_granularity(),
524
                           os::vm_page_size());
525
    }
526
  }
527

528
  static bool initialize_virtual_space(VirtualSpace& vs, ReservedSpace rs, TestLargePages mode) {
529
    switch(mode) {
530
    default:
531
    case Default:
532
    case Reserve:
533
      return vs.initialize(rs, 0);
534
    case Disable:
535
      return vs.initialize_with_granularity(rs, 0, os::vm_page_size());
536
    case Commit:
537
      return vs.initialize_with_granularity(rs, 0, os::page_size_for_region_unaligned(rs.size(), 1));
538
    }
539
  }
540

541
 public:
542
  static void test_virtual_space_actual_committed_space(size_t reserve_size, size_t commit_size,
543
                                                        TestLargePages mode = Default) {
544
    size_t granularity = os::vm_allocation_granularity();
545
    size_t reserve_size_aligned = align_up(reserve_size, granularity);
546

547
    ReservedSpace reserved = reserve_memory(reserve_size_aligned, mode);
548

549
    EXPECT_TRUE(reserved.is_reserved());
550

551
    VirtualSpace vs;
552
    bool initialized = initialize_virtual_space(vs, reserved, mode);
553
    EXPECT_TRUE(initialized) << "Failed to initialize VirtualSpace";
554

555
    vs.expand_by(commit_size, false);
556

557
    if (vs.special()) {
558
      EXPECT_EQ(vs.actual_committed_size(), reserve_size_aligned);
559
    } else {
560
      EXPECT_GE(vs.actual_committed_size(), commit_size);
561
      // Approximate the commit granularity.
562
      // Make sure that we don't commit using large pages
563
      // if large pages has been disabled for this VirtualSpace.
564
      size_t commit_granularity = (mode == Disable || !UseLargePages) ?
565
                                   os::vm_page_size() : os::large_page_size();
566
      EXPECT_LT(vs.actual_committed_size(), commit_size + commit_granularity);
567
    }
568

569
    reserved.release();
570
  }
571

572
  static void test_virtual_space_actual_committed_space_one_large_page() {
573
    if (!UseLargePages) {
574
      return;
575
    }
576

577
    size_t large_page_size = os::large_page_size();
578

579
    ReservedSpace reserved(large_page_size, large_page_size, large_page_size);
580

581
    EXPECT_TRUE(reserved.is_reserved());
582

583
    VirtualSpace vs;
584
    bool initialized = vs.initialize(reserved, 0);
585
    EXPECT_TRUE(initialized) << "Failed to initialize VirtualSpace";
586

587
    vs.expand_by(large_page_size, false);
588

589
    EXPECT_EQ(vs.actual_committed_size(), large_page_size);
590

591
    reserved.release();
592
  }
593

594
  static void test_virtual_space_actual_committed_space() {
595
    test_virtual_space_actual_committed_space(4 * K, 0);
596
    test_virtual_space_actual_committed_space(4 * K, 4 * K);
597
    test_virtual_space_actual_committed_space(8 * K, 0);
598
    test_virtual_space_actual_committed_space(8 * K, 4 * K);
599
    test_virtual_space_actual_committed_space(8 * K, 8 * K);
600
    test_virtual_space_actual_committed_space(12 * K, 0);
601
    test_virtual_space_actual_committed_space(12 * K, 4 * K);
602
    test_virtual_space_actual_committed_space(12 * K, 8 * K);
603
    test_virtual_space_actual_committed_space(12 * K, 12 * K);
604
    test_virtual_space_actual_committed_space(64 * K, 0);
605
    test_virtual_space_actual_committed_space(64 * K, 32 * K);
606
    test_virtual_space_actual_committed_space(64 * K, 64 * K);
607
    test_virtual_space_actual_committed_space(2 * M, 0);
608
    test_virtual_space_actual_committed_space(2 * M, 4 * K);
609
    test_virtual_space_actual_committed_space(2 * M, 64 * K);
610
    test_virtual_space_actual_committed_space(2 * M, 1 * M);
611
    test_virtual_space_actual_committed_space(2 * M, 2 * M);
612
    test_virtual_space_actual_committed_space(10 * M, 0);
613
    test_virtual_space_actual_committed_space(10 * M, 4 * K);
614
    test_virtual_space_actual_committed_space(10 * M, 8 * K);
615
    test_virtual_space_actual_committed_space(10 * M, 1 * M);
616
    test_virtual_space_actual_committed_space(10 * M, 2 * M);
617
    test_virtual_space_actual_committed_space(10 * M, 5 * M);
618
    test_virtual_space_actual_committed_space(10 * M, 10 * M);
619
  }
620

621
  static void test_virtual_space_disable_large_pages() {
622
    if (!UseLargePages) {
623
      return;
624
    }
625
    // These test cases verify that if we force VirtualSpace to disable large pages
626
    test_virtual_space_actual_committed_space(10 * M, 0, Disable);
627
    test_virtual_space_actual_committed_space(10 * M, 4 * K, Disable);
628
    test_virtual_space_actual_committed_space(10 * M, 8 * K, Disable);
629
    test_virtual_space_actual_committed_space(10 * M, 1 * M, Disable);
630
    test_virtual_space_actual_committed_space(10 * M, 2 * M, Disable);
631
    test_virtual_space_actual_committed_space(10 * M, 5 * M, Disable);
632
    test_virtual_space_actual_committed_space(10 * M, 10 * M, Disable);
633

634
    test_virtual_space_actual_committed_space(10 * M, 0, Reserve);
635
    test_virtual_space_actual_committed_space(10 * M, 4 * K, Reserve);
636
    test_virtual_space_actual_committed_space(10 * M, 8 * K, Reserve);
637
    test_virtual_space_actual_committed_space(10 * M, 1 * M, Reserve);
638
    test_virtual_space_actual_committed_space(10 * M, 2 * M, Reserve);
639
    test_virtual_space_actual_committed_space(10 * M, 5 * M, Reserve);
640
    test_virtual_space_actual_committed_space(10 * M, 10 * M, Reserve);
641

642
    test_virtual_space_actual_committed_space(10 * M, 0, Commit);
643
    test_virtual_space_actual_committed_space(10 * M, 4 * K, Commit);
644
    test_virtual_space_actual_committed_space(10 * M, 8 * K, Commit);
645
    test_virtual_space_actual_committed_space(10 * M, 1 * M, Commit);
646
    test_virtual_space_actual_committed_space(10 * M, 2 * M, Commit);
647
    test_virtual_space_actual_committed_space(10 * M, 5 * M, Commit);
648
    test_virtual_space_actual_committed_space(10 * M, 10 * M, Commit);
649
  }
650

651
  static void test_virtual_space() {
652
    test_virtual_space_actual_committed_space();
653
    test_virtual_space_actual_committed_space_one_large_page();
654
    test_virtual_space_disable_large_pages();
655
  }
656
};
657

658
class ReservedSpaceRunnable : public TestRunnable {
659
public:
660
  void runUnitTest() const {
661
    TestReservedSpace::test_reserved_space();
662
  }
663
};
664

665
TEST_VM(VirtualSpace, os_reserve_space_concurrent) {
666
  ReservedSpaceRunnable runnable;
667
  ConcurrentTestRunner testRunner(&runnable, 5, 3000);
668
  testRunner.run();
669
}
670

671
class VirtualSpaceRunnable : public TestRunnable {
672
public:
673
  void runUnitTest() const {
674
    TestVirtualSpace::test_virtual_space();
675
  }
676
};
677

678
TEST_VM(VirtualSpace, os_virtual_space_concurrent) {
679
  VirtualSpaceRunnable runnable;
680
  ConcurrentTestRunner testRunner(&runnable, 5, 3000);
681
  testRunner.run();
682
}
683

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.