Skip to content

Commit 3267b09

Browse files
committed
8254883: ZGC: Make the ZArrayIterator reusable for ZRelocationSetIterators
Reviewed-by: eosterlund
1 parent cb6167b commit 3267b09

File tree

7 files changed

+75
-121
lines changed

7 files changed

+75
-121
lines changed

src/hotspot/share/gc/z/zArray.hpp

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -29,23 +29,23 @@
2929

3030
template <typename T> using ZArray = GrowableArrayCHeap<T, mtGC>;
3131

32-
template <typename T, bool parallel>
32+
template <typename T, bool Parallel>
3333
class ZArrayIteratorImpl : public StackObj {
3434
private:
35-
ZArray<T>* const _array;
36-
int _next;
35+
const T* _next;
36+
const T* const _end;
37+
38+
bool next_serial(T* elem);
39+
bool next_parallel(T* elem);
3740

3841
public:
39-
ZArrayIteratorImpl(ZArray<T>* array);
42+
ZArrayIteratorImpl(const T* array, size_t length);
43+
ZArrayIteratorImpl(const ZArray<T>* array);
4044

4145
bool next(T* elem);
4246
};
4347

44-
// Iterator types
45-
#define ZARRAY_SERIAL false
46-
#define ZARRAY_PARALLEL true
47-
48-
template <typename T> using ZArrayIterator = ZArrayIteratorImpl<T, ZARRAY_SERIAL>;
49-
template <typename T> using ZArrayParallelIterator = ZArrayIteratorImpl<T, ZARRAY_PARALLEL>;
48+
template <typename T> using ZArrayIterator = ZArrayIteratorImpl<T, false /* Parallel */>;
49+
template <typename T> using ZArrayParallelIterator = ZArrayIteratorImpl<T, true /* Parallel */>;
5050

5151
#endif // SHARE_GC_Z_ZARRAY_HPP

src/hotspot/share/gc/z/zArray.inline.hpp

Lines changed: 44 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -27,28 +27,54 @@
2727
#include "gc/z/zArray.hpp"
2828
#include "runtime/atomic.hpp"
2929

30-
template <typename T, bool parallel>
31-
inline ZArrayIteratorImpl<T, parallel>::ZArrayIteratorImpl(ZArray<T>* array) :
32-
_array(array),
33-
_next(0) {}
34-
35-
template <typename T, bool parallel>
36-
inline bool ZArrayIteratorImpl<T, parallel>::next(T* elem) {
37-
if (parallel) {
38-
const int next = Atomic::fetch_and_add(&_next, 1);
39-
if (next < _array->length()) {
40-
*elem = _array->at(next);
41-
return true;
30+
template <typename T, bool Parallel>
31+
inline bool ZArrayIteratorImpl<T, Parallel>::next_serial(T* elem) {
32+
if (_next == _end) {
33+
return false;
34+
}
35+
36+
*elem = *_next;
37+
_next++;
38+
39+
return true;
40+
}
41+
42+
template <typename T, bool Parallel>
43+
inline bool ZArrayIteratorImpl<T, Parallel>::next_parallel(T* elem) {
44+
const T* old_next = Atomic::load(&_next);
45+
46+
for (;;) {
47+
if (old_next == _end) {
48+
return false;
4249
}
43-
} else {
44-
if (_next < _array->length()) {
45-
*elem = _array->at(_next++);
50+
51+
const T* const new_next = old_next + 1;
52+
const T* const prev_next = Atomic::cmpxchg(&_next, old_next, new_next);
53+
if (prev_next == old_next) {
54+
*elem = *old_next;
4655
return true;
4756
}
57+
58+
old_next = prev_next;
4859
}
60+
}
61+
62+
template <typename T, bool Parallel>
63+
inline ZArrayIteratorImpl<T, Parallel>::ZArrayIteratorImpl(const T* array, size_t length) :
64+
_next(array),
65+
_end(array + length) {}
4966

50-
// No more elements
51-
return false;
67+
template <typename T, bool Parallel>
68+
inline ZArrayIteratorImpl<T, Parallel>::ZArrayIteratorImpl(const ZArray<T>* array) :
69+
ZArrayIteratorImpl<T, Parallel>(array->is_empty() ? NULL : array->adr_at(0), array->length()) {}
70+
71+
template <typename T, bool Parallel>
72+
inline bool ZArrayIteratorImpl<T, Parallel>::next(T* elem) {
73+
if (Parallel) {
74+
return next_parallel(elem);
75+
} else {
76+
return next_serial(elem);
77+
}
5278
}
5379

5480
#endif // SHARE_GC_Z_ZARRAY_INLINE_HPP

src/hotspot/share/gc/z/zGranuleMap.hpp

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -24,15 +24,13 @@
2424
#ifndef SHARE_GC_Z_ZGRANULEMAP_HPP
2525
#define SHARE_GC_Z_ZGRANULEMAP_HPP
2626

27+
#include "gc/z/zArray.hpp"
2728
#include "memory/allocation.hpp"
2829

29-
template<typename T>
30-
class ZGranuleMapIterator;
31-
3230
template <typename T>
3331
class ZGranuleMap {
3432
friend class VMStructs;
35-
friend class ZGranuleMapIterator<T>;
33+
template <typename> friend class ZGranuleMapIterator;
3634

3735
private:
3836
const size_t _size;
@@ -53,16 +51,9 @@ class ZGranuleMap {
5351
};
5452

5553
template <typename T>
56-
class ZGranuleMapIterator : public StackObj {
57-
public:
58-
const ZGranuleMap<T>* const _map;
59-
size_t _next;
60-
54+
class ZGranuleMapIterator : public ZArrayIteratorImpl<T, false /* Parallel */> {
6155
public:
62-
ZGranuleMapIterator(const ZGranuleMap<T>* map);
63-
64-
bool next(T* value);
65-
bool next(T** value);
56+
ZGranuleMapIterator(const ZGranuleMap<T>* granule_map);
6657
};
6758

6859
#endif // SHARE_GC_Z_ZGRANULEMAP_HPP

src/hotspot/share/gc/z/zGranuleMap.inline.hpp

Lines changed: 3 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#ifndef SHARE_GC_Z_ZGRANULEMAP_INLINE_HPP
2525
#define SHARE_GC_Z_ZGRANULEMAP_INLINE_HPP
2626

27+
#include "gc/z/zArray.inline.hpp"
2728
#include "gc/z/zGlobals.hpp"
2829
#include "gc/z/zGranuleMap.hpp"
2930
#include "memory/allocation.inline.hpp"
@@ -86,30 +87,7 @@ inline void ZGranuleMap<T>::release_put(uintptr_t offset, T value) {
8687
}
8788

8889
template <typename T>
89-
inline ZGranuleMapIterator<T>::ZGranuleMapIterator(const ZGranuleMap<T>* map) :
90-
_map(map),
91-
_next(0) {}
92-
93-
template <typename T>
94-
inline bool ZGranuleMapIterator<T>::next(T* value) {
95-
if (_next < _map->_size) {
96-
*value = _map->_map[_next++];
97-
return true;
98-
}
99-
100-
// End of map
101-
return false;
102-
}
103-
104-
template <typename T>
105-
inline bool ZGranuleMapIterator<T>::next(T** value) {
106-
if (_next < _map->_size) {
107-
*value = _map->_map + _next++;
108-
return true;
109-
}
110-
111-
// End of map
112-
return false;
113-
}
90+
inline ZGranuleMapIterator<T>::ZGranuleMapIterator(const ZGranuleMap<T>* granule_map) :
91+
ZArrayIteratorImpl<T, false /* Parallel */>(granule_map->_map, granule_map->_size) {}
11492

11593
#endif // SHARE_GC_Z_ZGRANULEMAP_INLINE_HPP

src/hotspot/share/gc/z/zRelocate.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,9 @@
2424
#ifndef SHARE_GC_Z_ZRELOCATE_HPP
2525
#define SHARE_GC_Z_ZRELOCATE_HPP
2626

27+
#include "gc/z/zRelocationSet.hpp"
28+
2729
class ZForwarding;
28-
class ZRelocationSet;
29-
class ZRelocationSetParallelIterator;
3030
class ZWorkers;
3131

3232
class ZRelocate {

src/hotspot/share/gc/z/zRelocationSet.hpp

Lines changed: 6 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -24,6 +24,7 @@
2424
#ifndef SHARE_GC_Z_ZRELOCATIONSET_HPP
2525
#define SHARE_GC_Z_ZRELOCATIONSET_HPP
2626

27+
#include "gc/z/zArray.hpp"
2728
#include "memory/allocation.hpp"
2829

2930
class ZForwarding;
@@ -44,32 +45,13 @@ class ZRelocationSet {
4445
void reset();
4546
};
4647

47-
template <bool parallel>
48-
class ZRelocationSetIteratorImpl : public StackObj {
49-
private:
50-
ZRelocationSet* const _relocation_set;
51-
size_t _next;
52-
48+
template <bool Parallel>
49+
class ZRelocationSetIteratorImpl : public ZArrayIteratorImpl<ZForwarding*, Parallel> {
5350
public:
5451
ZRelocationSetIteratorImpl(ZRelocationSet* relocation_set);
55-
56-
bool next(ZForwarding** forwarding);
5752
};
5853

59-
// Iterator types
60-
#define ZRELOCATIONSET_SERIAL false
61-
#define ZRELOCATIONSET_PARALLEL true
62-
63-
class ZRelocationSetIterator : public ZRelocationSetIteratorImpl<ZRELOCATIONSET_SERIAL> {
64-
public:
65-
ZRelocationSetIterator(ZRelocationSet* relocation_set) :
66-
ZRelocationSetIteratorImpl<ZRELOCATIONSET_SERIAL>(relocation_set) {}
67-
};
68-
69-
class ZRelocationSetParallelIterator : public ZRelocationSetIteratorImpl<ZRELOCATIONSET_PARALLEL> {
70-
public:
71-
ZRelocationSetParallelIterator(ZRelocationSet* relocation_set) :
72-
ZRelocationSetIteratorImpl<ZRELOCATIONSET_PARALLEL>(relocation_set) {}
73-
};
54+
using ZRelocationSetIterator = ZRelocationSetIteratorImpl<false /* Parallel */>;
55+
using ZRelocationSetParallelIterator = ZRelocationSetIteratorImpl<true /* Parallel */>;
7456

7557
#endif // SHARE_GC_Z_ZRELOCATIONSET_HPP
Lines changed: 5 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -24,34 +24,11 @@
2424
#ifndef SHARE_GC_Z_ZRELOCATIONSET_INLINE_HPP
2525
#define SHARE_GC_Z_ZRELOCATIONSET_INLINE_HPP
2626

27+
#include "gc/z/zArray.inline.hpp"
2728
#include "gc/z/zRelocationSet.hpp"
28-
#include "runtime/atomic.hpp"
2929

30-
template <bool parallel>
31-
inline ZRelocationSetIteratorImpl<parallel>::ZRelocationSetIteratorImpl(ZRelocationSet* relocation_set) :
32-
_relocation_set(relocation_set),
33-
_next(0) {}
34-
35-
template <bool parallel>
36-
inline bool ZRelocationSetIteratorImpl<parallel>::next(ZForwarding** forwarding) {
37-
const size_t nforwardings = _relocation_set->_nforwardings;
38-
39-
if (parallel) {
40-
if (_next < nforwardings) {
41-
const size_t next = Atomic::fetch_and_add(&_next, 1u);
42-
if (next < nforwardings) {
43-
*forwarding = _relocation_set->_forwardings[next];
44-
return true;
45-
}
46-
}
47-
} else {
48-
if (_next < nforwardings) {
49-
*forwarding = _relocation_set->_forwardings[_next++];
50-
return true;
51-
}
52-
}
53-
54-
return false;
55-
}
30+
template <bool Parallel>
31+
inline ZRelocationSetIteratorImpl<Parallel>::ZRelocationSetIteratorImpl(ZRelocationSet* relocation_set) :
32+
ZArrayIteratorImpl<ZForwarding*, Parallel>(relocation_set->_forwardings, relocation_set->_nforwardings) {}
5633

5734
#endif // SHARE_GC_Z_ZRELOCATIONSET_INLINE_HPP

0 commit comments

Comments
 (0)