Mercurial > hg > truffle
annotate src/share/vm/interpreter/oopMapCache.hpp @ 20543:e7d0505c8a30
8059758: Footprint regressions with JDK-8038423
Summary: Changes in JDK-8038423 always initialize (zero out) virtual memory used for auxiliary data structures. This causes a footprint regression for G1 in startup benchmarks. This is because they do not touch that memory at all, so the operating system does not actually commit these pages. The fix is to, if the initialization value of the data structures matches the default value of just committed memory (=0), do not do anything.
Reviewed-by: jwilhelm, brutisso
author | tschatzl |
---|---|
date | Fri, 10 Oct 2014 15:51:58 +0200 |
parents | c204e2044c29 |
children |
rev | line source |
---|---|
0 | 1 /* |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
2 * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. |
0 | 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 * | |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
0
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
0
diff
changeset
|
20 * or visit www.oracle.com if you need additional information or have any |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
0
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
1972 | 25 #ifndef SHARE_VM_INTERPRETER_OOPMAPCACHE_HPP |
26 #define SHARE_VM_INTERPRETER_OOPMAPCACHE_HPP | |
27 | |
28 #include "oops/generateOopMap.hpp" | |
1983
c760f78e0a53
7003125: precompiled.hpp is included when precompiled headers are not used
stefank
parents:
1972
diff
changeset
|
29 #include "runtime/mutex.hpp" |
1972 | 30 |
0 | 31 // A Cache for storing (method, bci) -> oopMap. |
32 // The memory management system uses the cache when locating object | |
33 // references in an interpreted frame. | |
34 // | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
35 // OopMapCache's are allocated lazily per InstanceKlass. |
0 | 36 |
37 // The oopMap (InterpreterOopMap) is stored as a bit mask. If the | |
38 // bit_mask can fit into two words it is stored in | |
39 // the _bit_mask array, otherwise it is allocated on the heap. | |
40 // For OopMapCacheEntry the bit_mask is allocated in the C heap | |
41 // because these entries persist between garbage collections. | |
42 // For InterpreterOopMap the bit_mask is allocated in | |
43 // a resource area for better performance. InterpreterOopMap | |
44 // should only be created and deleted during same garbage collection. | |
45 // | |
46 // If ENABBLE_ZAP_DEAD_LOCALS is defined, two bits are used | |
47 // per entry instead of one. In all cases, | |
48 // the first bit is set to indicate oops as opposed to other | |
49 // values. If the second bit is available, | |
50 // it is set for dead values. We get the following encoding: | |
51 // | |
52 // 00 live value | |
53 // 01 live oop | |
54 // 10 dead value | |
55 // 11 <unused> (we cannot distinguish between dead oops or values with the current oop map generator) | |
56 | |
57 | |
58 class OffsetClosure { | |
59 public: | |
60 virtual void offset_do(int offset) = 0; | |
61 }; | |
62 | |
63 | |
64 class InterpreterOopMap: ResourceObj { | |
65 friend class OopMapCache; | |
66 | |
67 public: | |
68 enum { | |
69 N = 2, // the number of words reserved | |
70 // for inlined mask storage | |
71 small_mask_limit = N * BitsPerWord, // the maximum number of bits | |
72 // available for small masks, | |
73 // small_mask_limit can be set to 0 | |
74 // for testing bit_mask allocation | |
75 | |
76 #ifdef ENABLE_ZAP_DEAD_LOCALS | |
77 bits_per_entry = 2, | |
78 dead_bit_number = 1, | |
79 #else | |
80 bits_per_entry = 1, | |
81 #endif | |
82 oop_bit_number = 0 | |
83 }; | |
84 | |
85 private: | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
86 Method* _method; // the method for which the mask is valid |
0 | 87 unsigned short _bci; // the bci for which the mask is valid |
88 int _mask_size; // the mask size in bits | |
89 int _expression_stack_size; // the size of the expression stack in slots | |
90 | |
91 protected: | |
92 intptr_t _bit_mask[N]; // the bit mask if | |
93 // mask_size <= small_mask_limit, | |
94 // ptr to bit mask otherwise | |
95 // "protected" so that sub classes can | |
96 // access it without using trickery in | |
97 // methd bit_mask(). | |
98 #ifdef ASSERT | |
99 bool _resource_allocate_bit_mask; | |
100 #endif | |
101 | |
102 // access methods | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
103 Method* method() const { return _method; } |
20501
c204e2044c29
8038624: interpretedVFrame::expressions() must respect InterpreterOopMap for liveness
mgronlun
parents:
6725
diff
changeset
|
104 void set_method(Method* v) { _method = v; } |
0 | 105 int bci() const { return _bci; } |
106 void set_bci(int v) { _bci = v; } | |
107 int mask_size() const { return _mask_size; } | |
108 void set_mask_size(int v) { _mask_size = v; } | |
109 // Test bit mask size and return either the in-line bit mask or allocated | |
110 // bit mask. | |
20501
c204e2044c29
8038624: interpretedVFrame::expressions() must respect InterpreterOopMap for liveness
mgronlun
parents:
6725
diff
changeset
|
111 uintptr_t* bit_mask() const { return (uintptr_t*)(mask_size() <= small_mask_limit ? (intptr_t)_bit_mask : _bit_mask[0]); } |
0 | 112 |
113 // return the word size of_bit_mask. mask_size() <= 4 * MAX_USHORT | |
20501
c204e2044c29
8038624: interpretedVFrame::expressions() must respect InterpreterOopMap for liveness
mgronlun
parents:
6725
diff
changeset
|
114 size_t mask_word_size() const { |
0 | 115 return (mask_size() + BitsPerWord - 1) / BitsPerWord; |
116 } | |
117 | |
20501
c204e2044c29
8038624: interpretedVFrame::expressions() must respect InterpreterOopMap for liveness
mgronlun
parents:
6725
diff
changeset
|
118 uintptr_t entry_at(int offset) const { int i = offset * bits_per_entry; return bit_mask()[i / BitsPerWord] >> (i % BitsPerWord); } |
0 | 119 |
20501
c204e2044c29
8038624: interpretedVFrame::expressions() must respect InterpreterOopMap for liveness
mgronlun
parents:
6725
diff
changeset
|
120 void set_expression_stack_size(int sz) { _expression_stack_size = sz; } |
0 | 121 |
122 #ifdef ENABLE_ZAP_DEAD_LOCALS | |
20501
c204e2044c29
8038624: interpretedVFrame::expressions() must respect InterpreterOopMap for liveness
mgronlun
parents:
6725
diff
changeset
|
123 bool is_dead(int offset) const { return (entry_at(offset) & (1 << dead_bit_number)) != 0; } |
0 | 124 #endif |
125 | |
126 // Lookup | |
20501
c204e2044c29
8038624: interpretedVFrame::expressions() must respect InterpreterOopMap for liveness
mgronlun
parents:
6725
diff
changeset
|
127 bool match(methodHandle method, int bci) const { return _method == method() && _bci == bci; } |
c204e2044c29
8038624: interpretedVFrame::expressions() must respect InterpreterOopMap for liveness
mgronlun
parents:
6725
diff
changeset
|
128 bool is_empty() const; |
0 | 129 |
130 // Initialization | |
131 void initialize(); | |
132 | |
133 public: | |
134 InterpreterOopMap(); | |
135 ~InterpreterOopMap(); | |
136 | |
137 // Copy the OopMapCacheEntry in parameter "from" into this | |
138 // InterpreterOopMap. If the _bit_mask[0] in "from" points to | |
139 // allocated space (i.e., the bit mask was to large to hold | |
140 // in-line), allocate the space from a Resource area. | |
141 void resource_copy(OopMapCacheEntry* from); | |
142 | |
20501
c204e2044c29
8038624: interpretedVFrame::expressions() must respect InterpreterOopMap for liveness
mgronlun
parents:
6725
diff
changeset
|
143 void iterate_oop(OffsetClosure* oop_closure) const; |
c204e2044c29
8038624: interpretedVFrame::expressions() must respect InterpreterOopMap for liveness
mgronlun
parents:
6725
diff
changeset
|
144 void print() const; |
0 | 145 |
20501
c204e2044c29
8038624: interpretedVFrame::expressions() must respect InterpreterOopMap for liveness
mgronlun
parents:
6725
diff
changeset
|
146 int number_of_entries() const { return mask_size() / bits_per_entry; } |
c204e2044c29
8038624: interpretedVFrame::expressions() must respect InterpreterOopMap for liveness
mgronlun
parents:
6725
diff
changeset
|
147 bool is_oop (int offset) const { return (entry_at(offset) & (1 << oop_bit_number )) != 0; } |
0 | 148 |
20501
c204e2044c29
8038624: interpretedVFrame::expressions() must respect InterpreterOopMap for liveness
mgronlun
parents:
6725
diff
changeset
|
149 int expression_stack_size() const { return _expression_stack_size; } |
0 | 150 |
151 #ifdef ENABLE_ZAP_DEAD_LOCALS | |
152 void iterate_all(OffsetClosure* oop_closure, OffsetClosure* value_closure, OffsetClosure* dead_closure); | |
153 #endif | |
154 }; | |
155 | |
6197 | 156 class OopMapCache : public CHeapObj<mtClass> { |
0 | 157 private: |
158 enum { _size = 32, // Use fixed size for now | |
159 _probe_depth = 3 // probe depth in case of collisions | |
160 }; | |
161 | |
162 OopMapCacheEntry* _array; | |
163 | |
20501
c204e2044c29
8038624: interpretedVFrame::expressions() must respect InterpreterOopMap for liveness
mgronlun
parents:
6725
diff
changeset
|
164 unsigned int hash_value_for(methodHandle method, int bci) const; |
0 | 165 OopMapCacheEntry* entry_at(int i) const; |
166 | |
20501
c204e2044c29
8038624: interpretedVFrame::expressions() must respect InterpreterOopMap for liveness
mgronlun
parents:
6725
diff
changeset
|
167 mutable Mutex _mut; |
0 | 168 |
169 void flush(); | |
170 | |
171 public: | |
172 OopMapCache(); | |
173 ~OopMapCache(); // free up memory | |
174 | |
175 // flush cache entry is occupied by an obsolete method | |
176 void flush_obsolete_entries(); | |
177 | |
178 // Returns the oopMap for (method, bci) in parameter "entry". | |
179 // Returns false if an oop map was not found. | |
20501
c204e2044c29
8038624: interpretedVFrame::expressions() must respect InterpreterOopMap for liveness
mgronlun
parents:
6725
diff
changeset
|
180 void lookup(methodHandle method, int bci, InterpreterOopMap* entry) const; |
0 | 181 |
182 // Compute an oop map without updating the cache or grabbing any locks (for debugging) | |
183 static void compute_one_oop_map(methodHandle method, int bci, InterpreterOopMap* entry); | |
184 | |
185 // Returns total no. of bytes allocated as part of OopMapCache's | |
186 static long memory_usage() PRODUCT_RETURN0; | |
187 }; | |
1972 | 188 |
189 #endif // SHARE_VM_INTERPRETER_OOPMAPCACHE_HPP |