annotate src/share/vm/runtime/jfieldIDWorkaround.hpp @ 94:0834225a7916

6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction Summary: The option CMSInitiatingPermOccupancyFraction now controls perm triggering threshold. Even though the actual value of the threshold has not yet been changed, so there is no change in policy, we now have the infrastructure in place for dynamically deciding when to collect the perm gen, an issue that will be addressed in the near future. Reviewed-by: jmasa
author ysr
date Sun, 16 Mar 2008 21:57:25 -0700
parents a61af66fc99e
children c18cbe5936b8
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1 /*
a61af66fc99e Initial load
duke
parents:
diff changeset
2 * Copyright 2003-2005 Sun Microsystems, Inc. All Rights Reserved.
a61af66fc99e Initial load
duke
parents:
diff changeset
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
a61af66fc99e Initial load
duke
parents:
diff changeset
4 *
a61af66fc99e Initial load
duke
parents:
diff changeset
5 * This code is free software; you can redistribute it and/or modify it
a61af66fc99e Initial load
duke
parents:
diff changeset
6 * under the terms of the GNU General Public License version 2 only, as
a61af66fc99e Initial load
duke
parents:
diff changeset
7 * published by the Free Software Foundation.
a61af66fc99e Initial load
duke
parents:
diff changeset
8 *
a61af66fc99e Initial load
duke
parents:
diff changeset
9 * This code is distributed in the hope that it will be useful, but WITHOUT
a61af66fc99e Initial load
duke
parents:
diff changeset
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
a61af66fc99e Initial load
duke
parents:
diff changeset
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
a61af66fc99e Initial load
duke
parents:
diff changeset
12 * version 2 for more details (a copy is included in the LICENSE file that
a61af66fc99e Initial load
duke
parents:
diff changeset
13 * accompanied this code).
a61af66fc99e Initial load
duke
parents:
diff changeset
14 *
a61af66fc99e Initial load
duke
parents:
diff changeset
15 * You should have received a copy of the GNU General Public License version
a61af66fc99e Initial load
duke
parents:
diff changeset
16 * 2 along with this work; if not, write to the Free Software Foundation,
a61af66fc99e Initial load
duke
parents:
diff changeset
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
a61af66fc99e Initial load
duke
parents:
diff changeset
18 *
a61af66fc99e Initial load
duke
parents:
diff changeset
19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
a61af66fc99e Initial load
duke
parents:
diff changeset
20 * CA 95054 USA or visit www.sun.com if you need additional information or
a61af66fc99e Initial load
duke
parents:
diff changeset
21 * have any questions.
a61af66fc99e Initial load
duke
parents:
diff changeset
22 *
a61af66fc99e Initial load
duke
parents:
diff changeset
23 */
a61af66fc99e Initial load
duke
parents:
diff changeset
24
a61af66fc99e Initial load
duke
parents:
diff changeset
25 class jfieldIDWorkaround: AllStatic {
a61af66fc99e Initial load
duke
parents:
diff changeset
26 // This workaround is because JVMTI doesn't have distinct entry points
a61af66fc99e Initial load
duke
parents:
diff changeset
27 // for methods that use static jfieldIDs and instance jfieldIDs.
a61af66fc99e Initial load
duke
parents:
diff changeset
28 // The workaround is to steal a low-order bit:
a61af66fc99e Initial load
duke
parents:
diff changeset
29 // a 1 means the jfieldID is an instance jfieldID,
a61af66fc99e Initial load
duke
parents:
diff changeset
30 // and the rest of the word is the offset of the field.
a61af66fc99e Initial load
duke
parents:
diff changeset
31 // a 0 means the jfieldID is a static jfieldID,
a61af66fc99e Initial load
duke
parents:
diff changeset
32 // and the rest of the word is the JNIid*.
a61af66fc99e Initial load
duke
parents:
diff changeset
33 //
a61af66fc99e Initial load
duke
parents:
diff changeset
34 // Another low-order bit is used to mark if an instance field
a61af66fc99e Initial load
duke
parents:
diff changeset
35 // is accompanied by an indication of which class it applies to.
a61af66fc99e Initial load
duke
parents:
diff changeset
36 //
a61af66fc99e Initial load
duke
parents:
diff changeset
37 // Bit-format of a jfieldID (most significant first):
a61af66fc99e Initial load
duke
parents:
diff changeset
38 // address:30 instance=0:1 checked=0:1
a61af66fc99e Initial load
duke
parents:
diff changeset
39 // offset:30 instance=1:1 checked=0:1
a61af66fc99e Initial load
duke
parents:
diff changeset
40 // klass:23 offset:7 instance=1:1 checked=1:1
a61af66fc99e Initial load
duke
parents:
diff changeset
41 //
a61af66fc99e Initial load
duke
parents:
diff changeset
42 // If the offset does not fit in 7 bits, or if the fieldID is
a61af66fc99e Initial load
duke
parents:
diff changeset
43 // not checked, then the checked bit is zero and the rest of
a61af66fc99e Initial load
duke
parents:
diff changeset
44 // the word (30 bits) contains only the offset.
a61af66fc99e Initial load
duke
parents:
diff changeset
45 //
a61af66fc99e Initial load
duke
parents:
diff changeset
46 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
47 enum {
a61af66fc99e Initial load
duke
parents:
diff changeset
48 checked_bits = 1,
a61af66fc99e Initial load
duke
parents:
diff changeset
49 instance_bits = 1,
a61af66fc99e Initial load
duke
parents:
diff changeset
50 address_bits = BitsPerWord - checked_bits - instance_bits,
a61af66fc99e Initial load
duke
parents:
diff changeset
51
a61af66fc99e Initial load
duke
parents:
diff changeset
52 large_offset_bits = address_bits, // unioned with address
a61af66fc99e Initial load
duke
parents:
diff changeset
53 small_offset_bits = 7,
a61af66fc99e Initial load
duke
parents:
diff changeset
54 klass_bits = address_bits - small_offset_bits,
a61af66fc99e Initial load
duke
parents:
diff changeset
55
a61af66fc99e Initial load
duke
parents:
diff changeset
56 checked_shift = 0,
a61af66fc99e Initial load
duke
parents:
diff changeset
57 instance_shift = checked_shift + checked_bits,
a61af66fc99e Initial load
duke
parents:
diff changeset
58 address_shift = instance_shift + instance_bits,
a61af66fc99e Initial load
duke
parents:
diff changeset
59
a61af66fc99e Initial load
duke
parents:
diff changeset
60 offset_shift = address_shift, // unioned with address
a61af66fc99e Initial load
duke
parents:
diff changeset
61 klass_shift = offset_shift + small_offset_bits,
a61af66fc99e Initial load
duke
parents:
diff changeset
62
a61af66fc99e Initial load
duke
parents:
diff changeset
63 checked_mask_in_place = right_n_bits(checked_bits) << checked_shift,
a61af66fc99e Initial load
duke
parents:
diff changeset
64 instance_mask_in_place = right_n_bits(instance_bits) << instance_shift,
a61af66fc99e Initial load
duke
parents:
diff changeset
65 #ifndef _WIN64
a61af66fc99e Initial load
duke
parents:
diff changeset
66 large_offset_mask = right_n_bits(large_offset_bits),
a61af66fc99e Initial load
duke
parents:
diff changeset
67 small_offset_mask = right_n_bits(small_offset_bits),
a61af66fc99e Initial load
duke
parents:
diff changeset
68 klass_mask = right_n_bits(klass_bits)
a61af66fc99e Initial load
duke
parents:
diff changeset
69 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
70 };
a61af66fc99e Initial load
duke
parents:
diff changeset
71
a61af66fc99e Initial load
duke
parents:
diff changeset
72 #ifdef _WIN64
a61af66fc99e Initial load
duke
parents:
diff changeset
73 // These values are too big for Win64
a61af66fc99e Initial load
duke
parents:
diff changeset
74 const static uintptr_t large_offset_mask = right_n_bits(large_offset_bits);
a61af66fc99e Initial load
duke
parents:
diff changeset
75 const static uintptr_t small_offset_mask = right_n_bits(small_offset_bits);
a61af66fc99e Initial load
duke
parents:
diff changeset
76 const static uintptr_t klass_mask = right_n_bits(klass_bits);
a61af66fc99e Initial load
duke
parents:
diff changeset
77 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
78
a61af66fc99e Initial load
duke
parents:
diff changeset
79 // helper routines:
a61af66fc99e Initial load
duke
parents:
diff changeset
80 static bool is_checked_jfieldID(jfieldID id) {
a61af66fc99e Initial load
duke
parents:
diff changeset
81 uintptr_t as_uint = (uintptr_t) id;
a61af66fc99e Initial load
duke
parents:
diff changeset
82 return ((as_uint & checked_mask_in_place) != 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
83 }
a61af66fc99e Initial load
duke
parents:
diff changeset
84 static intptr_t raw_instance_offset(jfieldID id) {
a61af66fc99e Initial load
duke
parents:
diff changeset
85 uintptr_t result = (uintptr_t) id >> address_shift;
a61af66fc99e Initial load
duke
parents:
diff changeset
86 if (VerifyJNIFields && is_checked_jfieldID(id)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
87 result &= small_offset_mask; // cut off the hash bits
a61af66fc99e Initial load
duke
parents:
diff changeset
88 }
a61af66fc99e Initial load
duke
parents:
diff changeset
89 return (intptr_t)result;
a61af66fc99e Initial load
duke
parents:
diff changeset
90 }
a61af66fc99e Initial load
duke
parents:
diff changeset
91 static intptr_t encode_klass_hash(klassOop k, intptr_t offset);
a61af66fc99e Initial load
duke
parents:
diff changeset
92 static bool klass_hash_ok(klassOop k, jfieldID id);
a61af66fc99e Initial load
duke
parents:
diff changeset
93 static void verify_instance_jfieldID(klassOop k, jfieldID id);
a61af66fc99e Initial load
duke
parents:
diff changeset
94
a61af66fc99e Initial load
duke
parents:
diff changeset
95 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
96 static bool is_valid_jfieldID(klassOop k, jfieldID id);
a61af66fc99e Initial load
duke
parents:
diff changeset
97
a61af66fc99e Initial load
duke
parents:
diff changeset
98 static bool is_instance_jfieldID(klassOop k, jfieldID id) {
a61af66fc99e Initial load
duke
parents:
diff changeset
99 uintptr_t as_uint = (uintptr_t) id;
a61af66fc99e Initial load
duke
parents:
diff changeset
100 return ((as_uint & instance_mask_in_place) != 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
101 }
a61af66fc99e Initial load
duke
parents:
diff changeset
102 static bool is_static_jfieldID(jfieldID id) {
a61af66fc99e Initial load
duke
parents:
diff changeset
103 uintptr_t as_uint = (uintptr_t) id;
a61af66fc99e Initial load
duke
parents:
diff changeset
104 return ((as_uint & instance_mask_in_place) == 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
105 }
a61af66fc99e Initial load
duke
parents:
diff changeset
106
a61af66fc99e Initial load
duke
parents:
diff changeset
107 static jfieldID to_instance_jfieldID(klassOop k, int offset) {
a61af66fc99e Initial load
duke
parents:
diff changeset
108 intptr_t as_uint = ((offset & large_offset_mask) << offset_shift) | instance_mask_in_place;
a61af66fc99e Initial load
duke
parents:
diff changeset
109 if (VerifyJNIFields) {
a61af66fc99e Initial load
duke
parents:
diff changeset
110 as_uint |= encode_klass_hash(k, offset);
a61af66fc99e Initial load
duke
parents:
diff changeset
111 }
a61af66fc99e Initial load
duke
parents:
diff changeset
112 jfieldID result = (jfieldID) as_uint;
a61af66fc99e Initial load
duke
parents:
diff changeset
113 #ifndef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
114 // always verify in debug mode; switchable in anything else
a61af66fc99e Initial load
duke
parents:
diff changeset
115 if (VerifyJNIFields)
a61af66fc99e Initial load
duke
parents:
diff changeset
116 #endif // ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
117 {
a61af66fc99e Initial load
duke
parents:
diff changeset
118 verify_instance_jfieldID(k, result);
a61af66fc99e Initial load
duke
parents:
diff changeset
119 }
a61af66fc99e Initial load
duke
parents:
diff changeset
120 assert(raw_instance_offset(result) == (offset & large_offset_mask), "extract right offset");
a61af66fc99e Initial load
duke
parents:
diff changeset
121 return result;
a61af66fc99e Initial load
duke
parents:
diff changeset
122 }
a61af66fc99e Initial load
duke
parents:
diff changeset
123
a61af66fc99e Initial load
duke
parents:
diff changeset
124 static intptr_t from_instance_jfieldID(klassOop k, jfieldID id) {
a61af66fc99e Initial load
duke
parents:
diff changeset
125 #ifndef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
126 // always verify in debug mode; switchable in anything else
a61af66fc99e Initial load
duke
parents:
diff changeset
127 if (VerifyJNIFields)
a61af66fc99e Initial load
duke
parents:
diff changeset
128 #endif // ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
129 {
a61af66fc99e Initial load
duke
parents:
diff changeset
130 verify_instance_jfieldID(k, id);
a61af66fc99e Initial load
duke
parents:
diff changeset
131 }
a61af66fc99e Initial load
duke
parents:
diff changeset
132 return raw_instance_offset(id);
a61af66fc99e Initial load
duke
parents:
diff changeset
133 }
a61af66fc99e Initial load
duke
parents:
diff changeset
134
a61af66fc99e Initial load
duke
parents:
diff changeset
135 static jfieldID to_static_jfieldID(JNIid* id) {
a61af66fc99e Initial load
duke
parents:
diff changeset
136 assert(id->is_static_field_id(), "from_JNIid, but not static field id");
a61af66fc99e Initial load
duke
parents:
diff changeset
137 jfieldID result = (jfieldID) id;
a61af66fc99e Initial load
duke
parents:
diff changeset
138 assert(from_static_jfieldID(result) == id, "must produce the same static id");
a61af66fc99e Initial load
duke
parents:
diff changeset
139 return result;
a61af66fc99e Initial load
duke
parents:
diff changeset
140 }
a61af66fc99e Initial load
duke
parents:
diff changeset
141
a61af66fc99e Initial load
duke
parents:
diff changeset
142 static JNIid* from_static_jfieldID(jfieldID id) {
a61af66fc99e Initial load
duke
parents:
diff changeset
143 assert(jfieldIDWorkaround::is_static_jfieldID(id),
a61af66fc99e Initial load
duke
parents:
diff changeset
144 "to_JNIid, but not static jfieldID");
a61af66fc99e Initial load
duke
parents:
diff changeset
145 JNIid* result = (JNIid*) id;
a61af66fc99e Initial load
duke
parents:
diff changeset
146 assert(result->is_static_field_id(), "to_JNIid, but not static field id");
a61af66fc99e Initial load
duke
parents:
diff changeset
147 return result;
a61af66fc99e Initial load
duke
parents:
diff changeset
148 }
a61af66fc99e Initial load
duke
parents:
diff changeset
149
a61af66fc99e Initial load
duke
parents:
diff changeset
150 static jfieldID to_jfieldID(instanceKlassHandle k, int offset, bool is_static) {
a61af66fc99e Initial load
duke
parents:
diff changeset
151 if (is_static) {
a61af66fc99e Initial load
duke
parents:
diff changeset
152 JNIid *id = k->jni_id_for(offset);
a61af66fc99e Initial load
duke
parents:
diff changeset
153 debug_only(id->set_is_static_field_id());
a61af66fc99e Initial load
duke
parents:
diff changeset
154 return jfieldIDWorkaround::to_static_jfieldID(id);
a61af66fc99e Initial load
duke
parents:
diff changeset
155 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
156 return jfieldIDWorkaround::to_instance_jfieldID(k(), offset);
a61af66fc99e Initial load
duke
parents:
diff changeset
157 }
a61af66fc99e Initial load
duke
parents:
diff changeset
158 }
a61af66fc99e Initial load
duke
parents:
diff changeset
159 };