src/hotspot/share/gc/z/zValue.hpp
changeset 58705 f5662bdbee4a
parent 57875 427b38332f20
equal deleted inserted replaced
58704:8b16701b4636 58705:f5662bdbee4a
     1 /*
     1 /*
     2  * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
     2  * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     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
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.
     7  * published by the Free Software Foundation.
    23 
    23 
    24 #ifndef SHARE_GC_Z_ZVALUE_HPP
    24 #ifndef SHARE_GC_Z_ZVALUE_HPP
    25 #define SHARE_GC_Z_ZVALUE_HPP
    25 #define SHARE_GC_Z_ZVALUE_HPP
    26 
    26 
    27 #include "memory/allocation.hpp"
    27 #include "memory/allocation.hpp"
    28 #include "gc/z/zCPU.hpp"
    28 #include "utilities/globalDefinitions.hpp"
    29 #include "gc/z/zGlobals.hpp"
    29 
    30 #include "gc/z/zNUMA.hpp"
    30 //
    31 #include "gc/z/zThread.hpp"
    31 // Storage
    32 #include "gc/z/zUtils.hpp"
    32 //
    33 #include "runtime/globals.hpp"
       
    34 #include "utilities/align.hpp"
       
    35 
    33 
    36 template <typename S>
    34 template <typename S>
    37 class ZValueStorage : public AllStatic {
    35 class ZValueStorage : public AllStatic {
    38 private:
    36 private:
    39   static uintptr_t _top;
    37   static uintptr_t _top;
    40   static uintptr_t _end;
    38   static uintptr_t _end;
    41 
    39 
    42 public:
    40 public:
    43   static const size_t offset = 4 * K;
    41   static const size_t offset = 4 * K;
    44 
    42 
    45   static uintptr_t alloc(size_t size) {
    43   static uintptr_t alloc(size_t size);
    46     guarantee(size <= offset, "Allocation too large");
       
    47 
       
    48     // Allocate entry in existing memory block
       
    49     const uintptr_t addr = align_up(_top, S::alignment());
       
    50     _top = addr + size;
       
    51 
       
    52     if (_top < _end) {
       
    53       // Success
       
    54       return addr;
       
    55     }
       
    56 
       
    57     // Allocate new block of memory
       
    58     const size_t block_alignment = offset;
       
    59     const size_t block_size = offset * S::count();
       
    60     _top = ZUtils::alloc_aligned(block_alignment, block_size);
       
    61     _end = _top + offset;
       
    62 
       
    63     // Retry allocation
       
    64     return alloc(size);
       
    65   }
       
    66 };
    44 };
    67 
       
    68 template <typename T> uintptr_t ZValueStorage<T>::_end = 0;
       
    69 template <typename T> uintptr_t ZValueStorage<T>::_top = 0;
       
    70 
    45 
    71 class ZContendedStorage : public ZValueStorage<ZContendedStorage> {
    46 class ZContendedStorage : public ZValueStorage<ZContendedStorage> {
    72 public:
    47 public:
    73   static size_t alignment() {
    48   static size_t alignment();
    74     return ZCacheLineSize;
    49   static uint32_t count();
    75   }
    50   static uint32_t id();
    76 
       
    77   static uint32_t count() {
       
    78     return 1;
       
    79   }
       
    80 
       
    81   static uint32_t id() {
       
    82     return 0;
       
    83   }
       
    84 };
    51 };
    85 
    52 
    86 class ZPerCPUStorage : public ZValueStorage<ZPerCPUStorage> {
    53 class ZPerCPUStorage : public ZValueStorage<ZPerCPUStorage> {
    87 public:
    54 public:
    88   static size_t alignment() {
    55   static size_t alignment();
    89     return sizeof(uintptr_t);
    56   static uint32_t count();
    90   }
    57   static uint32_t id();
    91 
       
    92   static uint32_t count() {
       
    93     return ZCPU::count();
       
    94   }
       
    95 
       
    96   static uint32_t id() {
       
    97     return ZCPU::id();
       
    98   }
       
    99 };
    58 };
   100 
    59 
   101 class ZPerNUMAStorage : public ZValueStorage<ZPerNUMAStorage> {
    60 class ZPerNUMAStorage : public ZValueStorage<ZPerNUMAStorage> {
   102 public:
    61 public:
   103   static size_t alignment() {
    62   static size_t alignment();
   104     return sizeof(uintptr_t);
    63   static uint32_t count();
   105   }
    64   static uint32_t id();
   106 
       
   107   static uint32_t count() {
       
   108     return ZNUMA::count();
       
   109   }
       
   110 
       
   111   static uint32_t id() {
       
   112     return ZNUMA::id();
       
   113   }
       
   114 };
    65 };
   115 
    66 
   116 class ZPerWorkerStorage : public ZValueStorage<ZPerWorkerStorage> {
    67 class ZPerWorkerStorage : public ZValueStorage<ZPerWorkerStorage> {
   117 public:
    68 public:
   118   static size_t alignment() {
    69   static size_t alignment();
   119     return sizeof(uintptr_t);
    70   static uint32_t count();
   120   }
    71   static uint32_t id();
   121 
       
   122   static uint32_t count() {
       
   123     return MAX2(ParallelGCThreads, ConcGCThreads);
       
   124   }
       
   125 
       
   126   static uint32_t id() {
       
   127     return ZThread::worker_id();
       
   128   }
       
   129 };
    72 };
   130 
    73 
   131 template <typename S, typename T>
    74 //
   132 class ZValueIterator;
    75 // Value
       
    76 //
   133 
    77 
   134 template <typename S, typename T>
    78 template <typename S, typename T>
   135 class ZValue : public CHeapObj<mtGC> {
    79 class ZValue : public CHeapObj<mtGC> {
   136 private:
    80 private:
   137   const uintptr_t _addr;
    81   const uintptr_t _addr;
   138 
    82 
   139   uintptr_t value_addr(uint32_t value_id) const {
    83   uintptr_t value_addr(uint32_t value_id) const;
   140     return _addr + (value_id * S::offset);
       
   141   }
       
   142 
    84 
   143 public:
    85 public:
   144   ZValue() :
    86   ZValue();
   145       _addr(S::alloc(sizeof(T))) {
    87   ZValue(const T& value);
   146     // Initialize all instances
       
   147     ZValueIterator<S, T> iter(this);
       
   148     for (T* addr; iter.next(&addr);) {
       
   149       ::new (addr) T;
       
   150     }
       
   151   }
       
   152 
    88 
   153   ZValue(const T& value) :
    89   const T* addr(uint32_t value_id = S::id()) const;
   154       _addr(S::alloc(sizeof(T))) {
    90   T* addr(uint32_t value_id = S::id());
   155     // Initialize all instances
       
   156     ZValueIterator<S, T> iter(this);
       
   157     for (T* addr; iter.next(&addr);) {
       
   158       ::new (addr) T(value);
       
   159     }
       
   160   }
       
   161 
    91 
   162   // Not implemented
    92   const T& get(uint32_t value_id = S::id()) const;
   163   ZValue(const ZValue<S, T>& value);
    93   T& get(uint32_t value_id = S::id());
   164   ZValue<S, T>& operator=(const ZValue<S, T>& value);
       
   165 
    94 
   166   const T* addr(uint32_t value_id = S::id()) const {
    95   void set(const T& value, uint32_t value_id = S::id());
   167     return reinterpret_cast<const T*>(value_addr(value_id));
    96   void set_all(const T& value);
   168   }
       
   169 
       
   170   T* addr(uint32_t value_id = S::id()) {
       
   171     return reinterpret_cast<T*>(value_addr(value_id));
       
   172   }
       
   173 
       
   174   const T& get(uint32_t value_id = S::id()) const {
       
   175     return *addr(value_id);
       
   176   }
       
   177 
       
   178   T& get(uint32_t value_id = S::id()) {
       
   179     return *addr(value_id);
       
   180   }
       
   181 
       
   182   void set(const T& value, uint32_t value_id = S::id()) {
       
   183     get(value_id) = value;
       
   184   }
       
   185 
       
   186   void set_all(const T& value) {
       
   187     ZValueIterator<S, T> iter(this);
       
   188     for (T* addr; iter.next(&addr);) {
       
   189       *addr = value;
       
   190     }
       
   191   }
       
   192 };
    97 };
   193 
    98 
   194 template <typename T>
    99 template <typename T>
   195 class ZContended : public ZValue<ZContendedStorage, T> {
   100 class ZContended : public ZValue<ZContendedStorage, T> {
   196 public:
   101 public:
   197   ZContended() :
   102   ZContended();
   198       ZValue<ZContendedStorage, T>() {}
   103   ZContended(const T& value);
   199 
       
   200   ZContended(const T& value) :
       
   201       ZValue<ZContendedStorage, T>(value) {}
       
   202 
       
   203   using ZValue<ZContendedStorage, T>::operator=;
       
   204 };
   104 };
   205 
   105 
   206 template <typename T>
   106 template <typename T>
   207 class ZPerCPU : public ZValue<ZPerCPUStorage, T> {
   107 class ZPerCPU : public ZValue<ZPerCPUStorage, T> {
   208 public:
   108 public:
   209   ZPerCPU() :
   109   ZPerCPU();
   210       ZValue<ZPerCPUStorage, T>() {}
   110   ZPerCPU(const T& value);
   211 
       
   212   ZPerCPU(const T& value) :
       
   213       ZValue<ZPerCPUStorage, T>(value) {}
       
   214 
       
   215   using ZValue<ZPerCPUStorage, T>::operator=;
       
   216 };
   111 };
   217 
   112 
   218 template <typename T>
   113 template <typename T>
   219 class ZPerNUMA : public ZValue<ZPerNUMAStorage, T> {
   114 class ZPerNUMA : public ZValue<ZPerNUMAStorage, T> {
   220 public:
   115 public:
   221   ZPerNUMA() :
   116   ZPerNUMA();
   222       ZValue<ZPerNUMAStorage, T>() {}
   117   ZPerNUMA(const T& value);
   223 
       
   224   ZPerNUMA(const T& value) :
       
   225       ZValue<ZPerNUMAStorage, T>(value) {}
       
   226 
       
   227   using ZValue<ZPerNUMAStorage, T>::operator=;
       
   228 };
   118 };
   229 
   119 
   230 template <typename T>
   120 template <typename T>
   231 class ZPerWorker : public ZValue<ZPerWorkerStorage, T> {
   121 class ZPerWorker : public ZValue<ZPerWorkerStorage, T> {
   232 public:
   122 public:
   233   ZPerWorker() :
   123   ZPerWorker();
   234       ZValue<ZPerWorkerStorage, T>() {}
   124   ZPerWorker(const T& value);
       
   125 };
   235 
   126 
   236   ZPerWorker(const T& value) :
   127 //
   237       ZValue<ZPerWorkerStorage, T>(value) {}
   128 // Iterator
   238 
   129 //
   239   using ZValue<ZPerWorkerStorage, T>::operator=;
       
   240 };
       
   241 
   130 
   242 template <typename S, typename T>
   131 template <typename S, typename T>
   243 class ZValueIterator {
   132 class ZValueIterator {
   244 private:
   133 private:
   245   ZValue<S, T>* const _value;
   134   ZValue<S, T>* const _value;
   246   uint32_t            _value_id;
   135   uint32_t            _value_id;
   247 
   136 
   248 public:
   137 public:
   249   ZValueIterator(ZValue<S, T>* value) :
   138   ZValueIterator(ZValue<S, T>* value);
   250       _value(value),
       
   251       _value_id(0) {}
       
   252 
   139 
   253   bool next(T** value) {
   140   bool next(T** value);
   254     if (_value_id < S::count()) {
       
   255       *value = _value->addr(_value_id++);
       
   256       return true;
       
   257     }
       
   258     return false;
       
   259   }
       
   260 };
   141 };
   261 
   142 
   262 template <typename T>
   143 template <typename T>
   263 class ZPerCPUIterator : public ZValueIterator<ZPerCPUStorage, T> {
   144 class ZPerCPUIterator : public ZValueIterator<ZPerCPUStorage, T> {
   264 public:
   145 public:
   265   ZPerCPUIterator(ZPerCPU<T>* value) :
   146   ZPerCPUIterator(ZPerCPU<T>* value);
   266       ZValueIterator<ZPerCPUStorage, T>(value) {}
       
   267 };
   147 };
   268 
   148 
   269 template <typename T>
   149 template <typename T>
   270 class ZPerNUMAIterator : public ZValueIterator<ZPerNUMAStorage, T> {
   150 class ZPerNUMAIterator : public ZValueIterator<ZPerNUMAStorage, T> {
   271 public:
   151 public:
   272   ZPerNUMAIterator(ZPerNUMA<T>* value) :
   152   ZPerNUMAIterator(ZPerNUMA<T>* value);
   273       ZValueIterator<ZPerNUMAStorage, T>(value) {}
       
   274 };
   153 };
   275 
   154 
   276 template <typename T>
   155 template <typename T>
   277 class ZPerWorkerIterator : public ZValueIterator<ZPerWorkerStorage, T> {
   156 class ZPerWorkerIterator : public ZValueIterator<ZPerWorkerStorage, T> {
   278 public:
   157 public:
   279   ZPerWorkerIterator(ZPerWorker<T>* value) :
   158   ZPerWorkerIterator(ZPerWorker<T>* value);
   280       ZValueIterator<ZPerWorkerStorage, T>(value) {}
       
   281 };
   159 };
   282 
   160 
   283 template <typename S, typename T>
   161 template <typename S, typename T>
   284 class ZValueConstIterator {
   162 class ZValueConstIterator {
   285 private:
   163 private:
   286   const ZValue<S, T>* const _value;
   164   const ZValue<S, T>* const _value;
   287   uint32_t                  _value_id;
   165   uint32_t                  _value_id;
   288 
   166 
   289 public:
   167 public:
   290   ZValueConstIterator(const ZValue<S, T>* value) :
   168   ZValueConstIterator(const ZValue<S, T>* value);
   291       _value(value),
       
   292       _value_id(0) {}
       
   293 
   169 
   294   bool next(const T** value) {
   170   bool next(const T** value);
   295     if (_value_id < S::count()) {
       
   296       *value = _value->addr(_value_id++);
       
   297       return true;
       
   298     }
       
   299     return false;
       
   300   }
       
   301 };
   171 };
   302 
   172 
   303 template <typename T>
   173 template <typename T>
   304 class ZPerCPUConstIterator : public ZValueConstIterator<ZPerCPUStorage, T> {
   174 class ZPerCPUConstIterator : public ZValueConstIterator<ZPerCPUStorage, T> {
   305 public:
   175 public:
   306   ZPerCPUConstIterator(const ZPerCPU<T>* value) :
   176   ZPerCPUConstIterator(const ZPerCPU<T>* value);
   307       ZValueConstIterator<ZPerCPUStorage, T>(value) {}
       
   308 };
   177 };
   309 
   178 
   310 template <typename T>
   179 template <typename T>
   311 class ZPerNUMAConstIterator : public ZValueConstIterator<ZPerNUMAStorage, T> {
   180 class ZPerNUMAConstIterator : public ZValueConstIterator<ZPerNUMAStorage, T> {
   312 public:
   181 public:
   313   ZPerNUMAConstIterator(const ZPerNUMA<T>* value) :
   182   ZPerNUMAConstIterator(const ZPerNUMA<T>* value);
   314       ZValueConstIterator<ZPerNUMAStorage, T>(value) {}
       
   315 };
   183 };
   316 
   184 
   317 template <typename T>
   185 template <typename T>
   318 class ZPerWorkerConstIterator : public ZValueConstIterator<ZPerWorkerStorage, T> {
   186 class ZPerWorkerConstIterator : public ZValueConstIterator<ZPerWorkerStorage, T> {
   319 public:
   187 public:
   320   ZPerWorkerConstIterator(const ZPerWorker<T>* value) :
   188   ZPerWorkerConstIterator(const ZPerWorker<T>* value);
   321       ZValueConstIterator<ZPerWorkerStorage, T>(value) {}
       
   322 };
   189 };
   323 
   190 
   324 #endif // SHARE_GC_Z_ZVALUE_HPP
   191 #endif // SHARE_GC_Z_ZVALUE_HPP