Mercurial > hg > graal-compiler
comparison src/share/vm/runtime/jfieldIDWorkaround.hpp @ 0:a61af66fc99e jdk7-b24
Initial load
author | duke |
---|---|
date | Sat, 01 Dec 2007 00:00:00 +0000 |
parents | |
children | c18cbe5936b8 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:a61af66fc99e |
---|---|
1 /* | |
2 * Copyright 2003-2005 Sun Microsystems, Inc. All Rights Reserved. | |
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 * | |
19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, | |
20 * CA 95054 USA or visit www.sun.com if you need additional information or | |
21 * have any questions. | |
22 * | |
23 */ | |
24 | |
25 class jfieldIDWorkaround: AllStatic { | |
26 // This workaround is because JVMTI doesn't have distinct entry points | |
27 // for methods that use static jfieldIDs and instance jfieldIDs. | |
28 // The workaround is to steal a low-order bit: | |
29 // a 1 means the jfieldID is an instance jfieldID, | |
30 // and the rest of the word is the offset of the field. | |
31 // a 0 means the jfieldID is a static jfieldID, | |
32 // and the rest of the word is the JNIid*. | |
33 // | |
34 // Another low-order bit is used to mark if an instance field | |
35 // is accompanied by an indication of which class it applies to. | |
36 // | |
37 // Bit-format of a jfieldID (most significant first): | |
38 // address:30 instance=0:1 checked=0:1 | |
39 // offset:30 instance=1:1 checked=0:1 | |
40 // klass:23 offset:7 instance=1:1 checked=1:1 | |
41 // | |
42 // If the offset does not fit in 7 bits, or if the fieldID is | |
43 // not checked, then the checked bit is zero and the rest of | |
44 // the word (30 bits) contains only the offset. | |
45 // | |
46 private: | |
47 enum { | |
48 checked_bits = 1, | |
49 instance_bits = 1, | |
50 address_bits = BitsPerWord - checked_bits - instance_bits, | |
51 | |
52 large_offset_bits = address_bits, // unioned with address | |
53 small_offset_bits = 7, | |
54 klass_bits = address_bits - small_offset_bits, | |
55 | |
56 checked_shift = 0, | |
57 instance_shift = checked_shift + checked_bits, | |
58 address_shift = instance_shift + instance_bits, | |
59 | |
60 offset_shift = address_shift, // unioned with address | |
61 klass_shift = offset_shift + small_offset_bits, | |
62 | |
63 checked_mask_in_place = right_n_bits(checked_bits) << checked_shift, | |
64 instance_mask_in_place = right_n_bits(instance_bits) << instance_shift, | |
65 #ifndef _WIN64 | |
66 large_offset_mask = right_n_bits(large_offset_bits), | |
67 small_offset_mask = right_n_bits(small_offset_bits), | |
68 klass_mask = right_n_bits(klass_bits) | |
69 #endif | |
70 }; | |
71 | |
72 #ifdef _WIN64 | |
73 // These values are too big for Win64 | |
74 const static uintptr_t large_offset_mask = right_n_bits(large_offset_bits); | |
75 const static uintptr_t small_offset_mask = right_n_bits(small_offset_bits); | |
76 const static uintptr_t klass_mask = right_n_bits(klass_bits); | |
77 #endif | |
78 | |
79 // helper routines: | |
80 static bool is_checked_jfieldID(jfieldID id) { | |
81 uintptr_t as_uint = (uintptr_t) id; | |
82 return ((as_uint & checked_mask_in_place) != 0); | |
83 } | |
84 static intptr_t raw_instance_offset(jfieldID id) { | |
85 uintptr_t result = (uintptr_t) id >> address_shift; | |
86 if (VerifyJNIFields && is_checked_jfieldID(id)) { | |
87 result &= small_offset_mask; // cut off the hash bits | |
88 } | |
89 return (intptr_t)result; | |
90 } | |
91 static intptr_t encode_klass_hash(klassOop k, intptr_t offset); | |
92 static bool klass_hash_ok(klassOop k, jfieldID id); | |
93 static void verify_instance_jfieldID(klassOop k, jfieldID id); | |
94 | |
95 public: | |
96 static bool is_valid_jfieldID(klassOop k, jfieldID id); | |
97 | |
98 static bool is_instance_jfieldID(klassOop k, jfieldID id) { | |
99 uintptr_t as_uint = (uintptr_t) id; | |
100 return ((as_uint & instance_mask_in_place) != 0); | |
101 } | |
102 static bool is_static_jfieldID(jfieldID id) { | |
103 uintptr_t as_uint = (uintptr_t) id; | |
104 return ((as_uint & instance_mask_in_place) == 0); | |
105 } | |
106 | |
107 static jfieldID to_instance_jfieldID(klassOop k, int offset) { | |
108 intptr_t as_uint = ((offset & large_offset_mask) << offset_shift) | instance_mask_in_place; | |
109 if (VerifyJNIFields) { | |
110 as_uint |= encode_klass_hash(k, offset); | |
111 } | |
112 jfieldID result = (jfieldID) as_uint; | |
113 #ifndef ASSERT | |
114 // always verify in debug mode; switchable in anything else | |
115 if (VerifyJNIFields) | |
116 #endif // ASSERT | |
117 { | |
118 verify_instance_jfieldID(k, result); | |
119 } | |
120 assert(raw_instance_offset(result) == (offset & large_offset_mask), "extract right offset"); | |
121 return result; | |
122 } | |
123 | |
124 static intptr_t from_instance_jfieldID(klassOop k, jfieldID id) { | |
125 #ifndef ASSERT | |
126 // always verify in debug mode; switchable in anything else | |
127 if (VerifyJNIFields) | |
128 #endif // ASSERT | |
129 { | |
130 verify_instance_jfieldID(k, id); | |
131 } | |
132 return raw_instance_offset(id); | |
133 } | |
134 | |
135 static jfieldID to_static_jfieldID(JNIid* id) { | |
136 assert(id->is_static_field_id(), "from_JNIid, but not static field id"); | |
137 jfieldID result = (jfieldID) id; | |
138 assert(from_static_jfieldID(result) == id, "must produce the same static id"); | |
139 return result; | |
140 } | |
141 | |
142 static JNIid* from_static_jfieldID(jfieldID id) { | |
143 assert(jfieldIDWorkaround::is_static_jfieldID(id), | |
144 "to_JNIid, but not static jfieldID"); | |
145 JNIid* result = (JNIid*) id; | |
146 assert(result->is_static_field_id(), "to_JNIid, but not static field id"); | |
147 return result; | |
148 } | |
149 | |
150 static jfieldID to_jfieldID(instanceKlassHandle k, int offset, bool is_static) { | |
151 if (is_static) { | |
152 JNIid *id = k->jni_id_for(offset); | |
153 debug_only(id->set_is_static_field_id()); | |
154 return jfieldIDWorkaround::to_static_jfieldID(id); | |
155 } else { | |
156 return jfieldIDWorkaround::to_instance_jfieldID(k(), offset); | |
157 } | |
158 } | |
159 }; |