Thu, 20 Nov 2008 16:56:09 -0800
6684579: SoftReference processing can be made more efficient
Summary: For current soft-ref clearing policies, we can decide at marking time if a soft-reference will definitely not be cleared, postponing the decision of whether it will definitely be cleared to the final reference processing phase. This can be especially beneficial in the case of concurrent collectors where the marking is usually concurrent but reference processing is usually not.
Reviewed-by: jmasa
duke@435 | 1 | /* |
duke@435 | 2 | * Copyright 2000-2004 Sun Microsystems, Inc. All Rights Reserved. |
duke@435 | 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
duke@435 | 4 | * |
duke@435 | 5 | * This code is free software; you can redistribute it and/or modify it |
duke@435 | 6 | * under the terms of the GNU General Public License version 2 only, as |
duke@435 | 7 | * published by the Free Software Foundation. |
duke@435 | 8 | * |
duke@435 | 9 | * This code is distributed in the hope that it will be useful, but WITHOUT |
duke@435 | 10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
duke@435 | 11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
duke@435 | 12 | * version 2 for more details (a copy is included in the LICENSE file that |
duke@435 | 13 | * accompanied this code). |
duke@435 | 14 | * |
duke@435 | 15 | * You should have received a copy of the GNU General Public License version |
duke@435 | 16 | * 2 along with this work; if not, write to the Free Software Foundation, |
duke@435 | 17 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
duke@435 | 18 | * |
duke@435 | 19 | * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, |
duke@435 | 20 | * CA 95054 USA or visit www.sun.com if you need additional information or |
duke@435 | 21 | * have any questions. |
duke@435 | 22 | * |
duke@435 | 23 | */ |
duke@435 | 24 | |
duke@435 | 25 | // The following two classes are used to represent 'sizes' and 'offsets' in the VM; |
duke@435 | 26 | // they serve as 'unit' types. ByteSize is used for sizes measured in bytes, while |
duke@435 | 27 | // WordSize is used for sizes measured in machine words (i.e., 32bit or 64bit words |
duke@435 | 28 | // depending on platform). |
duke@435 | 29 | // |
duke@435 | 30 | // The classes are defined with friend functions operating on them instead of member |
duke@435 | 31 | // functions so that they (the classes) can be re-#define'd to int types in optimized |
duke@435 | 32 | // mode. This allows full type checking and maximum safety in debug mode, and full |
duke@435 | 33 | // optimizations (constant folding) and zero overhead (time and space wise) in the |
duke@435 | 34 | // optimized build (some compilers do not optimize one-element value classes but |
duke@435 | 35 | // instead create an object in memory - thus the overhead may be significant). |
duke@435 | 36 | // |
duke@435 | 37 | // Note: 1) DO NOT add new overloaded friend functions that do not have a unique function |
duke@435 | 38 | // function name but require signature types for resolution. This will not work |
duke@435 | 39 | // in optimized mode as both, ByteSize and WordSize are mapped to the same type |
duke@435 | 40 | // and thus the distinction would not be possible anymore (=> compiler errors). |
duke@435 | 41 | // |
duke@435 | 42 | // 2) DO NOT add non-static member functions as they cannot be mapped so something |
duke@435 | 43 | // compilable in the optimized build. Static member functions could be added |
duke@435 | 44 | // but require a corresponding class definition in the optimized build. |
duke@435 | 45 | // |
duke@435 | 46 | // These classes should help doing a transition from (currently) word-size based offsets |
duke@435 | 47 | // to byte-size based offsets in the VM (this will be important if we desire to pack |
duke@435 | 48 | // objects more densely in the VM for 64bit machines). Such a transition should proceed |
duke@435 | 49 | // in two steps to minimize the risk of introducing hard-to-find bugs: |
duke@435 | 50 | // |
duke@435 | 51 | // a) first transition the whole VM into a form where all sizes are strongly typed |
duke@435 | 52 | // b) change all WordSize's to ByteSize's where desired and fix the compilation errors |
duke@435 | 53 | |
duke@435 | 54 | |
duke@435 | 55 | #ifdef ASSERT |
duke@435 | 56 | |
duke@435 | 57 | class ByteSize VALUE_OBJ_CLASS_SPEC { |
duke@435 | 58 | private: |
duke@435 | 59 | int _size; |
duke@435 | 60 | |
duke@435 | 61 | // Note: This constructor must be private to avoid implicit conversions! |
duke@435 | 62 | ByteSize(int size) { _size = size; } |
duke@435 | 63 | |
duke@435 | 64 | public: |
duke@435 | 65 | // constructors |
duke@435 | 66 | inline friend ByteSize in_ByteSize(int size); |
duke@435 | 67 | |
duke@435 | 68 | // accessors |
duke@435 | 69 | inline friend int in_bytes(ByteSize x); |
duke@435 | 70 | |
duke@435 | 71 | // operators |
duke@435 | 72 | friend ByteSize operator + (ByteSize x, ByteSize y) { return ByteSize(in_bytes(x) + in_bytes(y)); } |
duke@435 | 73 | friend ByteSize operator - (ByteSize x, ByteSize y) { return ByteSize(in_bytes(x) - in_bytes(y)); } |
duke@435 | 74 | friend ByteSize operator * (ByteSize x, int y) { return ByteSize(in_bytes(x) * y ); } |
duke@435 | 75 | |
duke@435 | 76 | // comparison |
duke@435 | 77 | friend bool operator == (ByteSize x, ByteSize y) { return in_bytes(x) == in_bytes(y); } |
duke@435 | 78 | friend bool operator != (ByteSize x, ByteSize y) { return in_bytes(x) != in_bytes(y); } |
duke@435 | 79 | friend bool operator < (ByteSize x, ByteSize y) { return in_bytes(x) < in_bytes(y); } |
duke@435 | 80 | friend bool operator <= (ByteSize x, ByteSize y) { return in_bytes(x) <= in_bytes(y); } |
duke@435 | 81 | friend bool operator > (ByteSize x, ByteSize y) { return in_bytes(x) > in_bytes(y); } |
duke@435 | 82 | friend bool operator >= (ByteSize x, ByteSize y) { return in_bytes(x) >= in_bytes(y); } |
duke@435 | 83 | }; |
duke@435 | 84 | |
duke@435 | 85 | inline ByteSize in_ByteSize(int size) { return ByteSize(size); } |
duke@435 | 86 | inline int in_bytes(ByteSize x) { return x._size; } |
duke@435 | 87 | |
duke@435 | 88 | |
duke@435 | 89 | class WordSize VALUE_OBJ_CLASS_SPEC { |
duke@435 | 90 | private: |
duke@435 | 91 | int _size; |
duke@435 | 92 | |
duke@435 | 93 | // Note: This constructor must be private to avoid implicit conversions! |
duke@435 | 94 | WordSize(int size) { _size = size; } |
duke@435 | 95 | |
duke@435 | 96 | public: |
duke@435 | 97 | // constructors |
duke@435 | 98 | inline friend WordSize in_WordSize(int size); |
duke@435 | 99 | |
duke@435 | 100 | // accessors |
duke@435 | 101 | inline friend int in_words(WordSize x); |
duke@435 | 102 | |
duke@435 | 103 | // operators |
duke@435 | 104 | friend WordSize operator + (WordSize x, WordSize y) { return WordSize(in_words(x) + in_words(y)); } |
duke@435 | 105 | friend WordSize operator - (WordSize x, WordSize y) { return WordSize(in_words(x) - in_words(y)); } |
duke@435 | 106 | friend WordSize operator * (WordSize x, int y) { return WordSize(in_words(x) * y ); } |
duke@435 | 107 | |
duke@435 | 108 | // comparison |
duke@435 | 109 | friend bool operator == (WordSize x, WordSize y) { return in_words(x) == in_words(y); } |
duke@435 | 110 | friend bool operator != (WordSize x, WordSize y) { return in_words(x) != in_words(y); } |
duke@435 | 111 | friend bool operator < (WordSize x, WordSize y) { return in_words(x) < in_words(y); } |
duke@435 | 112 | friend bool operator <= (WordSize x, WordSize y) { return in_words(x) <= in_words(y); } |
duke@435 | 113 | friend bool operator > (WordSize x, WordSize y) { return in_words(x) > in_words(y); } |
duke@435 | 114 | friend bool operator >= (WordSize x, WordSize y) { return in_words(x) >= in_words(y); } |
duke@435 | 115 | }; |
duke@435 | 116 | |
duke@435 | 117 | inline WordSize in_WordSize(int size) { return WordSize(size); } |
duke@435 | 118 | inline int in_words(WordSize x) { return x._size; } |
duke@435 | 119 | |
duke@435 | 120 | |
duke@435 | 121 | #else // ASSERT |
duke@435 | 122 | |
duke@435 | 123 | // The following definitions must match the corresponding friend declarations |
duke@435 | 124 | // in the Byte/WordSize classes if they are typedef'ed to be int. This will |
duke@435 | 125 | // be the case in optimized mode to ensure zero overhead for these types. |
duke@435 | 126 | // |
duke@435 | 127 | // Note: If a compiler does not inline these function calls away, one may |
duke@435 | 128 | // want to use #define's to make sure full optimization (constant |
duke@435 | 129 | // folding in particular) is possible. |
duke@435 | 130 | |
duke@435 | 131 | typedef int ByteSize; |
duke@435 | 132 | inline ByteSize in_ByteSize(int size) { return size; } |
duke@435 | 133 | inline int in_bytes (ByteSize x) { return x; } |
duke@435 | 134 | |
duke@435 | 135 | typedef int WordSize; |
duke@435 | 136 | inline WordSize in_WordSize(int size) { return size; } |
duke@435 | 137 | inline int in_words (WordSize x) { return x; } |
duke@435 | 138 | |
duke@435 | 139 | #endif // ASSERT |
duke@435 | 140 | |
duke@435 | 141 | |
duke@435 | 142 | // Use the following #define to get C++ field member offsets |
duke@435 | 143 | |
duke@435 | 144 | #define byte_offset_of(klass,field) in_ByteSize((int)offset_of(klass, field)) |