comparison src/share/vm/c1x/c1x_VMEntries.cpp @ 1423:760213a60e8b

* rewrite of the code installation * partial support for safepoints * macro-based CiTargetMethod interface * code stub support
author Lukas Stadler <lukas.stadler@oracle.com>
date Mon, 16 Aug 2010 18:59:36 -0700
parents 3483ec571caf
children 98fffb304868
comparison
equal deleted inserted replaced
1422:3483ec571caf 1423:760213a60e8b
25 25
26 # include "incls/_precompiled.incl" 26 # include "incls/_precompiled.incl"
27 # include "incls/_c1x_VMEntries.cpp.incl" 27 # include "incls/_c1x_VMEntries.cpp.incl"
28 28
29 29
30 /* 30
31 * Class: com_sun_hotspot_c1x_VMEntries 31
32 * Method: RiMethod_code 32 // public byte[] RiMethod_code(HotSpotProxy method);
33 * Signature: (Ljava/lang/reflect/Method;)[B 33 JNIEXPORT jbyteArray JNICALL Java_com_sun_hotspot_c1x_VMEntries_RiMethod_1code(JNIEnv *env, jobject, jlong vmId) {
34 */ 34 methodOop method = C1XObjects::get<methodOop>(vmId);
35 JNIEXPORT jbyteArray JNICALL Java_com_sun_hotspot_c1x_VMEntries_RiMethod_1code(JNIEnv *env, jobject, jobject method) { 35 int code_size = method->code_size();
36 methodOop m = C1XObjects::getInternalMethod(method);
37 int code_size = m->code_size();
38 jbyteArray result = env->NewByteArray(code_size); 36 jbyteArray result = env->NewByteArray(code_size);
39 env->SetByteArrayRegion(result, 0, code_size, (const jbyte *)m->code_base()); 37 env->SetByteArrayRegion(result, 0, code_size, (const jbyte *)method->code_base());
40 return result; 38 return result;
41 } 39 }
42 40
43 /* 41 // public int RiMethod_maxStackSize(HotSpotProxy method);
44 * Class: com_sun_hotspot_c1x_VMEntries 42 JNIEXPORT jint JNICALL Java_com_sun_hotspot_c1x_VMEntries_RiMethod_1maxStackSize(JNIEnv *, jobject, jlong vmId) {
45 * Method: RiMethod_maxStackSize 43 return C1XObjects::get<methodOop>(vmId)->max_stack();
46 * Signature: (Ljava/lang/reflect/Method;)I 44 }
47 */ 45
48 JNIEXPORT jint JNICALL Java_com_sun_hotspot_c1x_VMEntries_RiMethod_1maxStackSize(JNIEnv *, jobject, jobject method) { 46 // public int RiMethod_maxLocals(HotSpotProxy method);
49 return C1XObjects::getInternalMethod(method)->max_stack(); 47 JNIEXPORT jint JNICALL Java_com_sun_hotspot_c1x_VMEntries_RiMethod_1maxLocals(JNIEnv *, jobject, jlong vmId) {
50 } 48 return C1XObjects::get<methodOop>(vmId)->max_locals();
51 49 }
52 /* 50
53 * Class: com_sun_hotspot_c1x_VMEntries 51 // public RiType RiMethod_holder(HotSpotProxy method);
54 * Method: RiMethod_maxLocals 52 JNIEXPORT jobject JNICALL Java_com_sun_hotspot_c1x_VMEntries_RiMethod_1holder(JNIEnv *, jobject, jlong vmId) {
55 * Signature: (Ljava/lang/reflect/Method;)I
56 */
57 JNIEXPORT jint JNICALL Java_com_sun_hotspot_c1x_VMEntries_RiMethod_1maxLocals(JNIEnv *, jobject, jobject method) {
58 return C1XObjects::getInternalMethod(method)->max_locals();
59 }
60
61 /*
62 * Class: com_sun_hotspot_c1x_VMEntries
63 * Method: RiMethod_holder
64 * Signature: (Ljava/lang/reflect/Method;)Lcom/sun/cri/ri/RiType;
65 */
66 JNIEXPORT jobject JNICALL Java_com_sun_hotspot_c1x_VMEntries_RiMethod_1holder(JNIEnv *, jobject, jobject method) {
67 VM_ENTRY_MARK 53 VM_ENTRY_MARK
68 oop holder = VMExits::createRiType(C1XObjects::getInternalMethod(method)->method_holder(), THREAD); 54 klassOop klass = C1XObjects::get<methodOop>(vmId)->method_holder();
55 jlong klassVmId = C1XObjects::add<klassOop>(klass);
56 Handle name = C1XObjects::toString<Handle>(klass->klass_part()->name(), CHECK_NULL);
57 oop holder = VMExits::createRiType(klassVmId, name, THREAD);
69 return JNIHandles::make_local(THREAD, holder); 58 return JNIHandles::make_local(THREAD, holder);
70 } 59 }
71 60
72 /* 61 // public String RiMethod_signature(HotSpotProxy method);
73 * Class: com_sun_hotspot_c1x_VMEntries 62 JNIEXPORT jstring JNICALL Java_com_sun_hotspot_c1x_VMEntries_RiMethod_1signature(JNIEnv *env, jobject, jlong vmId) {
74 * Method: RiMethod_signature
75 * Signature: (Ljava/lang/reflect/Method;)Lcom/sun/cri/ri/RiSignature;
76 */
77 JNIEXPORT jstring JNICALL Java_com_sun_hotspot_c1x_VMEntries_RiMethod_1signature(JNIEnv *env, jobject, jobject method) {
78 VM_ENTRY_MARK 63 VM_ENTRY_MARK
79 return (jstring)JNIHandles::make_local(java_lang_String::create_from_symbol(C1XObjects::getInternalMethod(method)->signature(), Thread::current())()); 64 methodOop method = C1XObjects::get<methodOop>(vmId);
80 } 65 return C1XObjects::toString<jstring>(method->signature(), THREAD);
81 66 }
82 /* 67
83 * Class: com_sun_hotspot_c1x_VMEntries 68 // public int RiMethod_accessFlags(HotSpotProxy method);
84 * Method: RiMethod_name 69 JNIEXPORT jint JNICALL Java_com_sun_hotspot_c1x_VMEntries_RiMethod_1accessFlags(JNIEnv *, jobject, jlong vmId) {
85 * Signature: (Ljava/lang/reflect/Method;)Ljava/lang/String; 70 return C1XObjects::get<methodOop>(vmId)->access_flags().as_int();
86 */ 71 }
87 JNIEXPORT jstring JNICALL Java_com_sun_hotspot_c1x_VMEntries_RiMethod_1name(JNIEnv *env, jobject, jobject method) { 72
88 VM_ENTRY_MARK 73 // public RiType RiSignature_lookupType(String returnType, HotSpotProxy accessingClass);
89 return (jstring)JNIHandles::make_local(java_lang_String::create_from_symbol(C1XObjects::getInternalMethod(method)->name(), Thread::current())()); 74 JNIEXPORT jobject JNICALL Java_com_sun_hotspot_c1x_VMEntries_RiSignature_1lookupType(JNIEnv *, jobject, jstring jname, jlong accessingClassVmId) {
90 } 75 VM_ENTRY_MARK;
91 76
92 /* 77 symbolOop nameSymbol = C1XObjects::toSymbol(jname);
93 * Class: com_sun_hotspot_c1x_VMEntries 78 Handle name = JNIHandles::resolve(jname);
94 * Method: RiMethod_accessFlags 79
95 * Signature: (Ljava/lang/reflect/Method;)I 80 oop result;
96 */ 81 if (nameSymbol == vmSymbols::int_signature()) {
97 JNIEXPORT jint JNICALL Java_com_sun_hotspot_c1x_VMEntries_RiMethod_1accessFlags(JNIEnv *, jobject, jobject method) { 82 result = VMExits::createRiTypePrimitive((int)T_INT, THREAD);
98 return C1XObjects::getInternalMethod(method)->access_flags().as_int(); 83 } else if (nameSymbol == vmSymbols::long_signature()) {
99 } 84 result = VMExits::createRiTypePrimitive((int)T_LONG, THREAD);
100 85 } else if (nameSymbol == vmSymbols::bool_signature()) {
101 /* 86 result = VMExits::createRiTypePrimitive((int)T_BOOLEAN, THREAD);
102 * Class: com_sun_hotspot_c1x_VMEntries 87 } else if (nameSymbol == vmSymbols::char_signature()) {
103 * Method: RiSignature_lookupType 88 result = VMExits::createRiTypePrimitive((int)T_CHAR, THREAD);
104 * Signature: (Ljava/lang/String;Lcom/sun/cri/ri/RiType;)Lcom/sun/cri/ri/RiType; 89 } else if (nameSymbol == vmSymbols::short_signature()) {
105 */ 90 result = VMExits::createRiTypePrimitive((int)T_SHORT, THREAD);
106 JNIEXPORT jobject JNICALL Java_com_sun_hotspot_c1x_VMEntries_RiSignature_1lookupType(JNIEnv *, jobject, jstring name, jobject accessor) { 91 } else if (nameSymbol == vmSymbols::byte_signature()) {
107 VM_ENTRY_MARK 92 result = VMExits::createRiTypePrimitive((int)T_BYTE, THREAD);
108 klassOop k = C1XObjects::getInternalClass(accessor); 93 } else if (nameSymbol == vmSymbols::double_signature()) {
109 oop n = JNIHandles::resolve(name); 94 result = VMExits::createRiTypePrimitive((int)T_DOUBLE, THREAD);
110 if (n == NULL) { 95 } else if (nameSymbol == vmSymbols::float_signature()) {
111 THROW_MSG_(vmSymbols::java_lang_NullPointerException(), "Name must not be null.", NULL); 96 result = VMExits::createRiTypePrimitive((int)T_FLOAT, THREAD);
112 } 97 } else {
113 oop result = C1XCompiler::get_RiType(n, k, THREAD); 98 Handle classloader;
99 Handle protectionDomain;
100 if (accessingClassVmId != 0) {
101 classloader = C1XObjects::get<klassOop>(accessingClassVmId)->klass_part()->class_loader();
102 protectionDomain = C1XObjects::get<klassOop>(accessingClassVmId)->klass_part()->protection_domain();
103 }
104 klassOop resolved_type = SystemDictionary::resolve_or_null(nameSymbol, classloader, protectionDomain, THREAD);
105 if (resolved_type != NULL) {
106 result = VMExits::createRiType(C1XObjects::add<klassOop>(resolved_type), name, THREAD);
107 } else {
108 result = VMExits::createRiTypeUnresolved(name, accessingClassVmId, THREAD);
109 }
110 }
111
114 return JNIHandles::make_local(THREAD, result); 112 return JNIHandles::make_local(THREAD, result);
115 } 113 }
116 114
117 115 // public Object RiConstantPool_lookupConstant(HotSpotProxy constantPool, int cpi);
118 /* 116 JNIEXPORT jobject JNICALL Java_com_sun_hotspot_c1x_VMEntries_RiConstantPool_1lookupConstant(JNIEnv *env, jobject, jlong vmId, jint index) {
119 * Class: com_sun_hotspot_c1x_VMEntries
120 * Method: RiConstantPool_lookupConstant
121 * Signature: (Ljava/lang/Class;I)Ljava/lang/Object;
122 */
123 JNIEXPORT jobject JNICALL Java_com_sun_hotspot_c1x_VMEntries_RiConstantPool_1lookupConstant(JNIEnv *env, jobject, jobject cpHandle, jint index) {
124 VM_ENTRY_MARK; 117 VM_ENTRY_MARK;
125 klassOop klass = C1XObjects::getInternalClass(cpHandle); 118
126 constantPoolOop cp = instanceKlass::cast(klass)->constants(); 119 constantPoolOop cp = C1XObjects::get<constantPoolOop>(vmId);
127 120
128 oop result = NULL; 121 oop result = NULL;
129 constantTag tag = cp->tag_at(index); 122 constantTag tag = cp->tag_at(index);
130 if (tag.is_int()) { 123 if (tag.is_int()) {
131 result = VMExits::createCiConstantInt(cp->int_at(index), CHECK_0); 124 result = VMExits::createCiConstantInt(cp->int_at(index), CHECK_0);
146 // TODO: Gracefully exit compilation. 139 // TODO: Gracefully exit compilation.
147 fatal("out of memory during compilation!"); 140 fatal("out of memory during compilation!");
148 return NULL; 141 return NULL;
149 } 142 }
150 } 143 }
151 result = VMExits::createCiConstantObject(string, CHECK_0); 144 result = VMExits::createCiConstantObject(C1XObjects::add<oop>(string), CHECK_0);
152 } else if (tag.is_klass() || tag.is_unresolved_klass()) { 145 } else if (tag.is_klass() || tag.is_unresolved_klass()) {
153 146
154 // TODO: Return RiType object 147 // TODO: Return RiType object
155 ShouldNotReachHere(); 148 ShouldNotReachHere();
156 // 4881222: allow ldc to take a class type 149 // 4881222: allow ldc to take a class type
157 //bool ignore; 150 //bool ignore;
158 //ciKlass* klass = get_klass_by_index_impl(cpool, index, ignore, accessor); 151 //ciKlass* klass = get_klass_by_index_impl(cpool, index, ignore, accessor);
165 // "must be an instance or array klass "); 158 // "must be an instance or array klass ");
166 //return ciConstant(T_OBJECT, klass); 159 //return ciConstant(T_OBJECT, klass);
167 } else if (tag.is_object()) { 160 } else if (tag.is_object()) {
168 oop obj = cp->object_at(index); 161 oop obj = cp->object_at(index);
169 assert(obj->is_instance(), "must be an instance"); 162 assert(obj->is_instance(), "must be an instance");
170 result = VMExits::createCiConstantObject(obj, CHECK_0); 163 result = VMExits::createCiConstantObject(C1XObjects::add<oop>(obj), CHECK_0);
171 } else { 164 } else {
172 ShouldNotReachHere(); 165 ShouldNotReachHere();
173 } 166 }
174 167
175 return JNIHandles::make_local(THREAD, result); 168 return JNIHandles::make_local(THREAD, result);
176 } 169 }
177 170
178 /* 171 // public RiMethod RiConstantPool_lookupMethod(HotSpotProxy constantPool, int cpi, byte byteCode
179 * Class: com_sun_hotspot_c1x_VMEntries 172 JNIEXPORT jobject JNICALL Java_com_sun_hotspot_c1x_VMEntries_RiConstantPool_1lookupMethod(JNIEnv *env, jobject, jlong vmId, jint index, jbyte byteCode) {
180 * Method: RiConstantPool_lookupMethod
181 * Signature: (Ljava/lang/Object;I)Lcom/sun/cri/ri/RiMethod;
182 */
183 JNIEXPORT jobject JNICALL Java_com_sun_hotspot_c1x_VMEntries_RiConstantPool_1lookupMethod(JNIEnv *env, jobject, jobject cpHandle, jint index, jbyte byteCode) {
184 VM_ENTRY_MARK; 173 VM_ENTRY_MARK;
185 klassOop klass = C1XObjects::getInternalClass(cpHandle); 174
186 constantPoolOop cp = instanceKlass::cast(klass)->constants(); 175 constantPoolOop cp = C1XObjects::get<constantPoolOop>(vmId);
187 // assert(cp->tag_at(cp->cache() != NULL ? cp->cache()->entry_at(index)->constant_pool_index() : index).is_method(), "reading field from non-field cp index"); 176
188 Bytecodes::Code bc = (Bytecodes::Code)(((int)byteCode) & 0xFF); 177 Bytecodes::Code bc = (Bytecodes::Code)(((int)byteCode) & 0xFF);
189 ciInstanceKlass* loading_klass = (ciInstanceKlass *)CURRENT_ENV->get_object(cp->pool_holder()); 178 ciInstanceKlass* loading_klass = (ciInstanceKlass *)CURRENT_ENV->get_object(cp->pool_holder());
190 ciMethod *method = CURRENT_ENV->get_method_by_index(cp, index, bc, loading_klass); 179 ciMethod *cimethod = CURRENT_ENV->get_method_by_index(cp, index, bc, loading_klass);
191 return JNIHandles::make_local(THREAD, VMExits::createRiMethod((methodOop)method->get_oop(), THREAD)); 180 methodOop method = (methodOop)cimethod->get_oop();
192 } 181 Handle name = C1XObjects::toString<Handle>(method->name(), CHECK_NULL);
193 182 return JNIHandles::make_local(THREAD, VMExits::createRiMethod(C1XObjects::add<methodOop>(method), name, THREAD));
194 /* 183 }
195 * Class: com_sun_hotspot_c1x_VMEntries 184
196 * Method: RiConstantPool_lookupSignature 185 // public RiSignature RiConstantPool_lookupSignature(HotSpotProxy constantPool, int cpi);
197 * Signature: (Ljava/lang/Object;I)Lcom/sun/cri/ri/RiSignature; 186 JNIEXPORT jobject JNICALL Java_com_sun_hotspot_c1x_VMEntries_RiConstantPool_1lookupSignature(JNIEnv *env, jobject, jlong vmId, jint index) {
198 */
199 JNIEXPORT jobject JNICALL Java_com_sun_hotspot_c1x_VMEntries_RiConstantPool_1lookupSignature(JNIEnv *env, jobject, jobject cpHandle, jint index) {
200 fatal("currently unsupported"); 187 fatal("currently unsupported");
201 return NULL; 188 return NULL;
202 } 189 }
203 190
204 /* 191 // public RiType RiConstantPool_lookupType(HotSpotProxy constantPool, int cpi);
205 * Class: com_sun_hotspot_c1x_VMEntries 192 JNIEXPORT jobject JNICALL Java_com_sun_hotspot_c1x_VMEntries_RiConstantPool_1lookupType(JNIEnv *env, jobject, jlong vmId, jint index) {
206 * Method: RiConstantPool_lookupType
207 * Signature: (Ljava/lang/Object;I)Lcom/sun/cri/ri/RiType;
208 */
209 JNIEXPORT jobject JNICALL Java_com_sun_hotspot_c1x_VMEntries_RiConstantPool_1lookupType(JNIEnv *env, jobject, jobject cpHandle, jint index) {
210 VM_ENTRY_MARK; 193 VM_ENTRY_MARK;
211 klassOop cpKlass = C1XObjects::getInternalClass(cpHandle); 194
212 constantPoolOop cp = instanceKlass::cast(cpKlass)->constants(); 195 constantPoolOop cp = C1XObjects::get<constantPoolOop>(vmId);
213 ciInstanceKlass* loading_klass = (ciInstanceKlass *)CURRENT_ENV->get_object(cpKlass); 196
197 ciInstanceKlass* loading_klass = (ciInstanceKlass *)CURRENT_ENV->get_object(cp->pool_holder());
214 bool is_accessible = false; 198 bool is_accessible = false;
215 ciKlass *klass = CURRENT_ENV->get_klass_by_index(cp, index, is_accessible, loading_klass); 199 ciKlass *klass = CURRENT_ENV->get_klass_by_index(cp, index, is_accessible, loading_klass);
216 return JNIHandles::make_local(THREAD, C1XCompiler::get_RiType(klass, cpKlass, THREAD)); 200 return JNIHandles::make_local(THREAD, C1XCompiler::get_RiType(klass, cp->klass(), THREAD));
217 201
218 } 202 }
219 203
220 /* 204 // public RiField RiConstantPool_lookupField(HotSpotProxy constantPool, int cpi);
221 * Class: com_sun_hotspot_c1x_VMEntries 205 JNIEXPORT jobject JNICALL Java_com_sun_hotspot_c1x_VMEntries_RiConstantPool_1lookupField(JNIEnv *env, jobject, jlong vmId, jint index) {
222 * Method: RiConstantPool_lookupField
223 * Signature: (Ljava/lang/Object;I)Lcom/sun/cri/ri/RiField;
224 */
225 JNIEXPORT jobject JNICALL Java_com_sun_hotspot_c1x_VMEntries_RiConstantPool_1lookupField(JNIEnv *env, jobject, jobject cpHandle, jint index) {
226 VM_ENTRY_MARK; 206 VM_ENTRY_MARK;
227 klassOop klass = C1XObjects::getInternalClass(cpHandle); 207
228 constantPoolOop cp = instanceKlass::cast(klass)->constants(); 208 constantPoolOop cp = C1XObjects::get<constantPoolOop>(vmId);
229 // assert(cp->tag_at(cp->cache() != NULL ? cp->cache()->entry_at(index)->constant_pool_index() : index).is_field(), "reading field from non-field cp index"); 209
230 ciInstanceKlass* loading_klass = (ciInstanceKlass *)CURRENT_ENV->get_object(cp->pool_holder()); 210 ciInstanceKlass* loading_klass = (ciInstanceKlass *)CURRENT_ENV->get_object(cp->pool_holder());
231 ciField *field = CURRENT_ENV->get_field_by_index(loading_klass, index); 211 ciField *field = CURRENT_ENV->get_field_by_index(loading_klass, index);
232 return JNIHandles::make_local(THREAD, C1XCompiler::get_RiField(field, THREAD)); 212 return JNIHandles::make_local(THREAD, C1XCompiler::get_RiField(field, THREAD));
233 } 213 }
234 214
235 /* 215 // public RiConstantPool RiType_constantPool(HotSpotProxy type);
236 * Class: com_sun_hotspot_c1x_VMEntries 216 JNIEXPORT jobject JNICALL Java_com_sun_hotspot_c1x_VMEntries_RiType_1constantPool(JNIEnv *, jobject, jlong vmId) {
237 * Method: RiType_name 217 VM_ENTRY_MARK;
238 * Signature: (Ljava/lang/Class;)Ljava/lang/String; 218
239 */ 219 constantPoolOop constantPool = instanceKlass::cast(C1XObjects::get<klassOop>(vmId))->constants();
240 JNIEXPORT jstring JNICALL Java_com_sun_hotspot_c1x_VMEntries_RiType_1name(JNIEnv *env, jobject, jobject klass) { 220 return JNIHandles::make_local(VMExits::createRiConstantPool(C1XObjects::add<constantPoolOop>(constantPool), THREAD));
241 VM_ENTRY_MARK 221 }
242 klassOop k = C1XObjects::getInternalClass(klass); 222
243 return (jstring)JNIHandles::make_local(java_lang_String::create_from_symbol(k->klass_part()->name(), Thread::current())()); 223 // public boolean RiType_isArrayClass(HotSpotProxy klass);
244 } 224 JNIEXPORT jboolean JNICALL Java_com_sun_hotspot_c1x_VMEntries_RiType_1isArrayClass(JNIEnv *, jobject, jlong vmId) {
245 225 return C1XObjects::get<klassOop>(vmId)->klass_part()->oop_is_javaArray();
246 /* 226 }
247 * Class: com_sun_hotspot_c1x_VMEntries 227
248 * Method: RiType_isArrayClass 228 // public boolean RiType_isInstanceClass(HotSpotProxy klass);
249 * Signature: (Ljava/lang/Class;)Z 229 JNIEXPORT jboolean JNICALL Java_com_sun_hotspot_c1x_VMEntries_RiType_1isInstanceClass(JNIEnv *, jobject, jlong vmId) {
250 */ 230 return C1XObjects::get<klassOop>(vmId)->klass_part()->oop_is_instance();
251 JNIEXPORT jboolean JNICALL Java_com_sun_hotspot_c1x_VMEntries_RiType_1isArrayClass(JNIEnv *, jobject, jobject klass) { 231 }
252 klassOop o = C1XObjects::getInternalClass(klass); 232
253 return o->klass_part()->oop_is_array(); 233 // public boolean RiType_isInterface(HotSpotProxy klass);
254 } 234 JNIEXPORT jboolean JNICALL Java_com_sun_hotspot_c1x_VMEntries_RiType_1isInterface(JNIEnv *, jobject, jlong vmId) {
255 235 return C1XObjects::get<klassOop>(vmId)->klass_part()->is_interface();
256 /*
257 * Class: com_sun_hotspot_c1x_VMEntries
258 * Method: RiType_isInstanceClass
259 * Signature: (Ljava/lang/Class;)Z
260 */
261 JNIEXPORT jboolean JNICALL Java_com_sun_hotspot_c1x_VMEntries_RiType_1isInstanceClass(JNIEnv *, jobject, jobject klass) {
262 klassOop o = C1XObjects::getInternalClass(klass);
263 return o->klass_part()->oop_is_instanceKlass();
264 }
265
266 /*
267 * Class: com_sun_hotspot_c1x_VMEntries
268 * Method: RiType_isInterface
269 * Signature: (Ljava/lang/Class;)Z
270 */
271 JNIEXPORT jboolean JNICALL Java_com_sun_hotspot_c1x_VMEntries_RiType_1isInterface(JNIEnv *, jobject, jobject klass) {
272 klassOop o = C1XObjects::getInternalClass(klass);
273 return o->klass_part()->is_interface();
274 } 236 }
275 237
276 238
277 // helpers used to set fields in the HotSpotVMConfig object 239 // helpers used to set fields in the HotSpotVMConfig object
278 jfieldID getFieldID(JNIEnv* env, jobject obj, const char* name, const char* sig) { 240 jfieldID getFieldID(JNIEnv* env, jobject obj, const char* name, const char* sig) {
285 } 247 }
286 248
287 void set_boolean(JNIEnv* env, jobject obj, const char* name, bool value) { env->SetBooleanField(obj, getFieldID(env, obj, name, "Z"), value); } 249 void set_boolean(JNIEnv* env, jobject obj, const char* name, bool value) { env->SetBooleanField(obj, getFieldID(env, obj, name, "Z"), value); }
288 void set_int(JNIEnv* env, jobject obj, const char* name, int value) { env->SetIntField(obj, getFieldID(env, obj, name, "I"), value); } 250 void set_int(JNIEnv* env, jobject obj, const char* name, int value) { env->SetIntField(obj, getFieldID(env, obj, name, "I"), value); }
289 void set_long(JNIEnv* env, jobject obj, const char* name, long value) { env->SetLongField(obj, getFieldID(env, obj, name, "J"), value); } 251 void set_long(JNIEnv* env, jobject obj, const char* name, long value) { env->SetLongField(obj, getFieldID(env, obj, name, "J"), value); }
252 void set_object(JNIEnv* env, jobject obj, const char* name, jobject value) { env->SetObjectField(obj, getFieldID(env, obj, name, "Ljava/lang/Object;"), value); }
253 void set_int_array(JNIEnv* env, jobject obj, const char* name, jarray value) { env->SetObjectField(obj, getFieldID(env, obj, name, "[I"), value); }
290 254
291 jboolean get_boolean(JNIEnv* env, jobject obj, const char* name) { return env->GetBooleanField(obj, getFieldID(env, obj, name, "Z")); } 255 jboolean get_boolean(JNIEnv* env, jobject obj, const char* name) { return env->GetBooleanField(obj, getFieldID(env, obj, name, "Z")); }
292 jint get_int(JNIEnv* env, jobject obj, const char* name) { return env->GetIntField(obj, getFieldID(env, obj, name, "I")); } 256 jint get_int(JNIEnv* env, jobject obj, const char* name) { return env->GetIntField(obj, getFieldID(env, obj, name, "I")); }
257 jlong get_long(JNIEnv* env, jobject obj, const char* name) { return env->GetLongField(obj, getFieldID(env, obj, name, "J")); }
293 jobject get_object(JNIEnv* env, jobject obj, const char* name) { return env->GetObjectField(obj, getFieldID(env, obj, name, "Ljava/lang/Object;")); } 258 jobject get_object(JNIEnv* env, jobject obj, const char* name) { return env->GetObjectField(obj, getFieldID(env, obj, name, "Ljava/lang/Object;")); }
294 jobject get_object(JNIEnv* env, jobject obj, const char* name, const char* sig) { return env->GetObjectField(obj, getFieldID(env, obj, name, sig)); } 259 jobject get_object(JNIEnv* env, jobject obj, const char* name, const char* sig) { return env->GetObjectField(obj, getFieldID(env, obj, name, sig)); }
295 260
296 261
297 // Helpful routine for computing field offsets at run time rather than hardcoding them 262 BasicType basicTypes[] = { T_BOOLEAN, T_BYTE, T_SHORT, T_CHAR, T_INT, T_FLOAT, T_LONG, T_DOUBLE, T_OBJECT };
298 int compute_offset(klassOop klass_oop, const char* name, const char* sig) { 263 int basicTypeCount = sizeof(basicTypes) / sizeof(BasicType);
299 JavaThread* THREAD = JavaThread::current(); 264
300 fieldDescriptor fd; 265 // public HotSpotVMConfig getConfiguration();
301 instanceKlass* ik = instanceKlass::cast(klass_oop);
302 symbolOop name_symbol = SymbolTable::probe(name, (int)strlen(name));
303 symbolOop signature_symbol = SymbolTable::probe(sig, (int)strlen(sig));
304 if (name_symbol == NULL || signature_symbol == NULL || !ik->find_local_field(name_symbol, signature_symbol, &fd)) {
305 ResourceMark rm;
306 tty->print_cr("Invalid layout of %s at %s", ik->external_name(), name_symbol->as_C_string());
307 fatal("Invalid layout of c1x4hotspot class");
308 }
309 return fd.offset();
310 }
311
312
313 class TypeHelper {
314 public:
315 jclass jniHotSpotType;
316 jclass jniHotSpotTargetMethod;
317 klassOop HotSpotType;
318 klassOop HotSpotTargetMethod;
319 int HotSpotType_klassOop;
320
321 TypeHelper(JNIEnv* jniEnv) {
322 jniHotSpotType = jniEnv->FindClass("com/sun/hotspot/c1x/HotSpotType");
323 jniHotSpotTargetMethod = jniEnv->FindClass("com/sun/hotspot/c1x/HotSpotTargetMethod");
324 }
325
326 void initialize() {
327 HotSpotType = java_lang_Class::as_klassOop(JNIHandles::resolve(jniHotSpotType));
328 HotSpotTargetMethod = java_lang_Class::as_klassOop(JNIHandles::resolve(jniHotSpotTargetMethod));
329 HotSpotType_klassOop = compute_offset(HotSpotType, "klass", "Ljava/lang/Class;");
330 }
331 };
332
333
334
335
336 /*
337 * Class: com_sun_hotspot_c1x_VMEntries
338 * Method: installCode
339 * Signature: (Lcom/sun/hotspot/c1x/HotSpotTargetMethod;)V
340 */
341 JNIEXPORT void JNICALL Java_com_sun_hotspot_c1x_VMEntries_installCode(JNIEnv *jniEnv, jobject, jobject targetMethod) {
342 TypeHelper types(jniEnv);
343
344 methodOop m = C1XObjects::getInternalMethod(get_object(jniEnv, targetMethod, "method", "Ljava/lang/reflect/Method;"));
345 jbyteArray code = (jbyteArray)get_object(jniEnv, targetMethod, "code", "[B");
346 jint codeSize = get_int(jniEnv, targetMethod, "codeSize");
347 jintArray relocationOffsetsObj = (jintArray)get_object(jniEnv, targetMethod, "relocationOffsets", "[I");
348 jobjectArray relocationDataObj = (jobjectArray)get_object(jniEnv, targetMethod, "relocationData", "[Ljava/lang/Object;");
349 jint frameSize = get_int(jniEnv, targetMethod, "frameSize");
350
351 assert(codeSize > 0 && codeSize <= ((arrayOop)JNIHandles::resolve(code))->length(), "invalid codeSize");
352
353 CodeOffsets offsets;
354
355 // TODO: This is a hack.. Produce correct entries.
356 offsets.set_value(CodeOffsets::Exceptions, 0);
357 offsets.set_value(CodeOffsets::Deopt, 0);
358
359 offsets.set_value(CodeOffsets::Entry, get_int(jniEnv, targetMethod, "unverifiedEntrypoint"));
360 offsets.set_value(CodeOffsets::Verified_Entry, get_int(jniEnv, targetMethod, "verifiedEntrypoint"));
361
362 VM_ENTRY_MARK;
363 ciEnv *env = CURRENT_ENV;
364
365 types.initialize();
366
367 env->set_oop_recorder(new OopRecorder(env->arena()));
368 env->set_debug_info(new DebugInformationRecorder(env->oop_recorder()));
369 env->set_dependencies(new Dependencies(env));
370 ciMethod *ciMethodObject = (ciMethod *)env->get_object(m);
371
372 int relocationCount = relocationOffsetsObj == NULL ? 0 : ((arrayOop)JNIHandles::resolve(relocationOffsetsObj))->length();
373
374 CodeBuffer buffer("c1x nmethod", codeSize, relocationCount * relocInfo::length_limit);
375 buffer.initialize_oop_recorder(env->oop_recorder());
376
377 // copy the code into the newly created CodeBuffer
378 CodeSection* instructions = buffer.insts();
379 memcpy(instructions->start(), ((arrayOop)JNIHandles::resolve(code))->base(T_BYTE), codeSize);
380 instructions->set_end(instructions->start() + codeSize);
381
382 if (relocationCount > 0) {
383 jint* relocationOffsets = (jint*)((arrayOop)JNIHandles::resolve(relocationOffsetsObj))->base(T_INT);
384 oop* relocationObjects = (oop*)((arrayOop)JNIHandles::resolve(relocationDataObj))->base(T_OBJECT);
385
386 for (int i=0; i<relocationCount; i++) {
387 address inst = (address)instructions->start() + relocationOffsets[i];
388 u_char inst_byte = *inst;
389 oop obj = relocationObjects[i];
390 assert(obj != NULL, "NULL oop needn't be patched");
391
392 if (java_lang_boxing_object::is_instance(obj, T_LONG)) {
393 address operand = Assembler::locate_operand(inst, Assembler::call32_operand);
394 long dest = obj->long_field(java_lang_boxing_object::value_offset_in_bytes(T_LONG));
395 long disp = dest - (long)(operand + 4);
396 assert(disp == (int) disp, "disp doesn't fit in 32 bits");
397 *((int*)operand) = (int)disp;
398
399 instructions->relocate(inst, runtime_call_Relocation::spec(), Assembler::call32_operand);
400 tty->print_cr("relocating (Long) %02x at %016x/%016x", inst_byte, inst, operand);
401 } else if (obj->is_a(types.HotSpotType)) {
402 address operand = Assembler::locate_operand(inst, Assembler::imm_operand);
403
404 *((jobject*)operand) = JNIHandles::make_local(C1XObjects::getInternalClass(obj->obj_field(types.HotSpotType_klassOop)));
405 instructions->relocate(inst, oop_Relocation::spec_for_immediate(), Assembler::imm_operand);
406 tty->print_cr("relocating (HotSpotType) %02x at %016x/%016x", inst_byte, inst, operand);
407 } else {
408 tty->print_cr("unknown relocation type");
409 }
410 }
411 }
412
413 buffer.print();
414
415 address entry = instructions->start() + offsets.value(CodeOffsets::Verified_Entry);
416
417
418 OopMapSet oop_map_set;
419 ExceptionHandlerTable handler_table;
420 ImplicitExceptionTable inc_table;
421 {
422 ThreadToNativeFromVM t((JavaThread*)THREAD);
423 env->register_method(ciMethodObject, -1, &offsets, 0, &buffer, frameSize, &oop_map_set, &handler_table, &inc_table, NULL, env->comp_level(), false, false);
424
425 }
426 }
427
428 /*
429 * Class: com_sun_hotspot_c1x_VMEntries
430 * Method: getConfiguration
431 * Signature: ()Lcom/sun/hotspot/c1x/HotSpotVMConfig;
432 */
433 JNIEXPORT jobject JNICALL Java_com_sun_hotspot_c1x_VMEntries_getConfiguration(JNIEnv *env, jobject) { 266 JNIEXPORT jobject JNICALL Java_com_sun_hotspot_c1x_VMEntries_getConfiguration(JNIEnv *env, jobject) {
434 tty->print_cr("Java_com_sun_hotspot_c1x_VMEntries_getConfiguration"); 267 tty->print_cr("Java_com_sun_hotspot_c1x_VMEntries_getConfiguration");
435 jclass klass = env->FindClass("com/sun/hotspot/c1x/HotSpotVMConfig"); 268 jclass klass = env->FindClass("com/sun/hotspot/c1x/HotSpotVMConfig");
436 assert(klass != NULL, "HotSpot vm config class not found"); 269 assert(klass != NULL, "HotSpot vm config class not found");
437 jobject config = env->AllocObject(klass); 270 jobject config = env->AllocObject(klass);
443 set_int(env, config, "codeEntryAlignment", CodeEntryAlignment); 276 set_int(env, config, "codeEntryAlignment", CodeEntryAlignment);
444 set_int(env, config, "vmPageSize", os::vm_page_size()); 277 set_int(env, config, "vmPageSize", os::vm_page_size());
445 set_int(env, config, "stackShadowPages", StackShadowPages); 278 set_int(env, config, "stackShadowPages", StackShadowPages);
446 set_int(env, config, "hubOffset", oopDesc::klass_offset_in_bytes()); 279 set_int(env, config, "hubOffset", oopDesc::klass_offset_in_bytes());
447 set_int(env, config, "arrayLengthOffset", arrayOopDesc::length_offset_in_bytes()); 280 set_int(env, config, "arrayLengthOffset", arrayOopDesc::length_offset_in_bytes());
448 set_long(env, config, "instanceofStub", (long)Runtime1::entry_for(Runtime1::slow_subtype_check_id)); 281
449 set_long(env, config, "debugStub", (long)warning); 282 set_long(env, config, "instanceofStub", C1XObjects::addStub(Runtime1::entry_for(Runtime1::slow_subtype_check_id)));
283 set_long(env, config, "debugStub", C1XObjects::addStub((address)warning));
284 set_long(env, config, "resolveStaticCallStub", C1XObjects::addStub(SharedRuntime::get_resolve_static_call_stub()));
285 jintArray arrayOffsets = env->NewIntArray(basicTypeCount);
286 for (int i=0; i<basicTypeCount; i++) {
287 jint offset = arrayOopDesc::base_offset_in_bytes(basicTypes[i]);
288 env->SetIntArrayRegion(arrayOffsets, i, 1, &offset);
289 }
290 set_int_array(env, config, "arrayOffsets", arrayOffsets);
291 set_int(env, config, "arrayClassElementOffset", objArrayKlass::element_klass_offset_in_bytes() + sizeof(oopDesc));
450 return config; 292 return config;
451 } 293 }
452 294
295 #define C1X_REGISTER_COUNT 32
296
297 VMReg get_hotspot_reg(jint c1x_reg) {
298 Register cpu_registers[] = { rax, rcx, rdx, rbx, rsp, rbp, rsi, rdi, r8, r9, r10, r11, r12, r13, r14, r15 };
299 XMMRegister xmm_registers[] = { xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7, xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15 };
300
301 if (c1x_reg < 16) {
302 return cpu_registers[c1x_reg]->as_VMReg();
303 } else {
304 assert(c1x_reg < C1X_REGISTER_COUNT, "invalid register number");
305 return xmm_registers[c1x_reg - 16]->as_VMReg();
306 }
307
308 }
309
310 static OopMap* create_oop_map(jint frame_size, jint parameter_count, oop debug_info) {
311 OopMap* map = new OopMap(frame_size, parameter_count);
312 arrayOop register_map = (arrayOop)CiDebugInfo::registerRefMap(debug_info);
313 arrayOop frame_map = (arrayOop)CiDebugInfo::frameRefMap(debug_info);
314
315 jint register_count = VMRegImpl::stack2reg(0)->value();
316 tty->print_cr("register count: %i", register_count);
317
318 for (jint i=0; i<C1X_REGISTER_COUNT; i++) {
319 unsigned char byte = ((unsigned char*)register_map->base(T_BYTE))[i / 8];
320 bool is_oop = (byte & (1 << (i % 8))) != 0;
321 VMReg reg = get_hotspot_reg(i);
322 if (is_oop) {
323 map->set_oop(reg);
324 } else {
325 map->set_value(reg);
326 }
327 }
328
329 for (jint i=0; i<frame_size; i++) {
330 unsigned char byte = ((unsigned char*)frame_map->base(T_BYTE))[i / 8];
331 bool is_oop = (byte & (1 << (i % 8))) != 0;
332 VMReg reg = VMRegImpl::stack2reg(i);
333 if (is_oop) {
334 map->set_oop(reg);
335 } else {
336 map->set_value(reg);
337 }
338 }
339
340 // TODO parameters?
341 return map;
342 }
343
344 static ScopeValue* get_hotspot_value(oop value) {
345 fatal("not implemented");
346 if (value->is_a(CiRegisterValue::klass())) {
347 tty->print("register value");
348 value->print();
349 } else if (value->is_a(CiStackSlot::klass())) {
350 tty->print("stack value");
351 value->print();
352 } else {
353 ShouldNotReachHere();
354 }
355 }
356
357
358 class CodeInstaller {
359 private:
360 ciEnv* _env;
361
362 oop _citarget_method;
363 oop _hotspot_method;
364 oop _name;
365 arrayOop _sites;
366 CodeOffsets _offsets;
367
368 arrayOop _code;
369 jint _code_size;
370 jint _frame_size;
371 jint _parameter_count;
372 jint _constants_size;
373 jint _total_size;
374
375 CodeSection* _instructions;
376 CodeSection* _constants;
377
378 OopRecorder* _oop_recorder;
379 DebugInformationRecorder* _debug_recorder;
380 Dependencies* _dependencies;
381
382 public:
383
384 // constructor used to create a method
385 CodeInstaller(oop target_method) {
386 VM_ENTRY_MARK;
387 _env = CURRENT_ENV;
388
389 initialize_fields(target_method);
390 assert(_hotspot_method != NULL && _name == NULL, "installMethod needs NON-NULL method and NULL name");
391
392
393 // TODO: This is a hack.. Produce correct entries.
394 _offsets.set_value(CodeOffsets::Exceptions, 0);
395 _offsets.set_value(CodeOffsets::Deopt, 0);
396
397 methodOop method = C1XObjects::get<methodOop>(HotSpotMethod::vmId(_hotspot_method));
398 ciMethod *ciMethodObject = (ciMethod *)_env->get_object(method);
399 _parameter_count = method->size_of_parameters();
400
401 // (very) conservative estimate: each site needs a relocation
402 CodeBuffer buffer("temp c1x method", _total_size, _sites->length() * relocInfo::length_limit);
403 initialize_buffer(buffer);
404 ExceptionHandlerTable handler_table;
405 ImplicitExceptionTable inc_table;
406 {
407 ThreadToNativeFromVM t((JavaThread*)THREAD);
408 _env->register_method(ciMethodObject, -1, &_offsets, 0, &buffer, _frame_size, _debug_recorder->_oopmaps, &handler_table, &inc_table, NULL, _env->comp_level(), false, false);
409 }
410 }
411
412 // constructor used to create a stub
413 CodeInstaller(oop target_method, jlong& id) {
414 VM_ENTRY_MARK;
415 _env = CURRENT_ENV;
416
417 initialize_fields(target_method);
418 assert(_hotspot_method == NULL && _name != NULL, "installMethod needs NON-NULL name and NULL method");
419
420 // (very) conservative estimate: each site needs a relocation
421 CodeBuffer buffer("temp c1x stub", _total_size, _sites->length() * relocInfo::length_limit);
422 initialize_buffer(buffer);
423
424 const char* cname = java_lang_String::as_utf8_string(_name);
425 BufferBlob* blob = BufferBlob::create(strdup(cname), &buffer); // this is leaking strings... but only a limited number of stubs will be created
426 Disassembler::decode((CodeBlob*)blob);
427 id = C1XObjects::addStub(blob->instructions_begin());
428 }
429
430 private:
431 void initialize_fields(oop target_method) {
432 _citarget_method = HotSpotTargetMethod::targetMethod(target_method);
433 _hotspot_method = HotSpotTargetMethod::method(target_method);
434 _name = HotSpotTargetMethod::name(target_method);
435 _sites = (arrayOop)HotSpotTargetMethod::sites(target_method);
436
437 _code = (arrayOop)CiTargetMethod::targetCode(_citarget_method);
438 _code_size = CiTargetMethod::targetCodeSize(_citarget_method);
439 _frame_size = CiTargetMethod::frameSize(_citarget_method);
440
441 // (very) conservative estimate: each site needs a constant section entry
442 _constants_size = _sites->length() * BytesPerLong;
443 _total_size = align_size_up(_code_size, HeapWordSize) + _constants_size;
444 }
445
446 void site_Safepoint(CodeBuffer& buffer, jint pc_offset, oop site) {
447
448 }
449
450 void record_frame(jint pc_offset, oop code_pos, oop frame) {
451 oop caller_pos = CiCodePos::caller(code_pos);
452 if (caller_pos != NULL) {
453 oop caller_frame = CiDebugInfo_Frame::caller(frame);
454 record_frame(pc_offset, caller_pos, caller_frame);
455 } else {
456 assert(frame == NULL || CiDebugInfo_Frame::caller(frame) == NULL, "unexpected layout - different nesting of Frame and CiCodePos");
457 }
458
459 assert(frame == NULL || code_pos == CiDebugInfo_Frame::codePos(frame), "unexpected CiCodePos layout");
460
461 oop hotspot_method = CiCodePos::method(code_pos);
462 methodOop method = C1XObjects::get<methodOop>(HotSpotMethod::vmId(hotspot_method));
463 ciMethod *cimethod = (ciMethod *)_env->get_object(method);
464 jint bci = CiCodePos::bci(code_pos);
465
466 if (frame != NULL) {
467 jint local_count = CiDebugInfo_Frame::numLocals(frame);
468 jint expression_count = CiDebugInfo_Frame::numStack(frame);
469 jint monitor_count = CiDebugInfo_Frame::numLocks(frame);
470 arrayOop values = (arrayOop)CiDebugInfo_Frame::values(frame);
471
472 assert(local_count + expression_count + monitor_count == values->length(), "unexpected values length");
473 assert(monitor_count == 0, "monitors not supported");
474
475 GrowableArray<ScopeValue*>* locals = new GrowableArray<ScopeValue*>();
476 GrowableArray<ScopeValue*>* expressions = new GrowableArray<ScopeValue*>();
477 GrowableArray<MonitorValue*>* monitors = new GrowableArray<MonitorValue*>();
478
479 for (jint i=0; i<values->length(); i++) {
480 ScopeValue* value = get_hotspot_value(((oop*)values->base(T_OBJECT))[i]);
481
482 if (i < local_count) {
483 locals->append(value);
484 } else if (i < local_count + expression_count) {
485 expressions->append(value);
486 } else {
487 ShouldNotReachHere();
488 // monitors->append(value);
489 }
490 }
491 DebugToken* locals_token = _debug_recorder->create_scope_values(locals);
492 DebugToken* expressions_token = _debug_recorder->create_scope_values(expressions);
493 DebugToken* monitors_token = _debug_recorder->create_monitor_values(monitors);
494
495 _debug_recorder->describe_scope(pc_offset, cimethod, bci, false, false, false, locals_token, expressions_token, monitors_token);
496 } else {
497 _debug_recorder->describe_scope(pc_offset, cimethod, bci, false, false, false, NULL, NULL, NULL);
498 }
499 }
500
501 void site_Call(CodeBuffer& buffer, jint pc_offset, oop site) {
502 oop runtime_call = CiTargetMethod_Call::runtimeCall(site);
503 oop hotspot_method = CiTargetMethod_Call::method(site);
504 oop symbol = CiTargetMethod_Call::symbol(site);
505 oop global_stub = CiTargetMethod_Call::globalStubID(site);
506
507 oop debug_info = CiTargetMethod_Call::debugInfo(site);
508 arrayOop stack_map = (arrayOop)CiTargetMethod_Call::stackMap(site);
509 arrayOop register_map = (arrayOop)CiTargetMethod_Call::registerMap(site);
510
511 assert((runtime_call ? 1 : 0) + (hotspot_method ? 1 : 0) + (symbol ? 1 : 0) + (global_stub ? 1 : 0) == 1, "Call site needs exactly one type");
512
513 if (runtime_call != NULL) {
514 tty->print_cr("runtime_call");
515 } else if (global_stub != NULL) {
516 tty->print_cr("global_stub_id");
517 } else if (symbol != NULL) {
518 tty->print_cr("symbol");
519 } else { // method != NULL
520 assert(hotspot_method->is_a(SystemDictionary::HotSpotMethod_klass()), "unexpected RiMethod subclass");
521 methodOop method = C1XObjects::get<methodOop>(HotSpotMethod::vmId(hotspot_method));
522
523 address instruction = _instructions->start() + pc_offset;
524 address operand = Assembler::locate_operand(instruction, Assembler::call32_operand);
525 address next_instruction = Assembler::locate_next_instruction(instruction);
526 jint next_pc_offset = next_instruction - _instructions->start();
527
528 assert(debug_info != NULL, "debug info expected");
529 _debug_recorder->add_safepoint(next_pc_offset, create_oop_map(_frame_size, _parameter_count, debug_info));
530 oop code_pos = CiDebugInfo::codePos(debug_info);
531 oop frame = CiDebugInfo::frame(debug_info);
532 record_frame(next_pc_offset, code_pos, frame);
533
534 if (method->is_static()) {
535 tty->print_cr("static method");
536
537
538 address dest = SharedRuntime::get_resolve_static_call_stub();
539 long disp = dest - next_instruction;
540 assert(disp == (jint) disp, "disp doesn't fit in 32 bits");
541 *((jint*)operand) = (jint)disp;
542
543 _instructions->relocate(instruction, relocInfo::static_call_type, Assembler::call32_operand);
544 tty->print_cr("relocating (Long) %016x/%016x", instruction, operand);
545 } else {
546 tty->print_cr("non-static method");
547 ShouldNotReachHere();
548 }
549
550 _debug_recorder->end_safepoint(pc_offset);
551 }
552 }
553
554 void site_DataPatch(CodeBuffer& buffer, jint pc_offset, oop site) {
555 oop constant = CiTargetMethod_DataPatch::constant(site);
556 oop kind = CiConstant::kind(constant);
557
558 address instruction = _instructions->start() + pc_offset;
559 address operand = Assembler::locate_operand(instruction, Assembler::disp32_operand);
560 address next_instruction = Assembler::locate_next_instruction(instruction);
561
562 switch(CiKind::typeChar(kind)) {
563 case 'z':
564 case 'b':
565 case 's':
566 case 'c':
567 case 'i':
568 fatal("int-sized values not expected in DataPatch");
569 break;
570 case 'f':
571 case 'l':
572 case 'd': {
573 // we don't care if this is a long/double/etc., the primitive field contains the right bits
574 address dest = _constants->end();
575 *(jlong*)dest = CiConstant::primitive(constant);
576 _constants->set_end(dest + BytesPerLong);
577
578 long disp = dest - next_instruction;
579 assert(disp == (jint) disp, "disp doesn't fit in 32 bits");
580 *((jint*)operand) = (jint)disp;
581
582 _instructions->relocate(instruction, section_word_Relocation::spec((address)dest, CodeBuffer::SECT_CONSTS), Assembler::disp32_operand);
583 tty->print_cr("relocating (Float/Long/Double) at %016x/%016x", instruction, operand);
584 break;
585 }
586 case 'a':
587 CiConstant::object(constant)->print();
588 tty->print_cr("DataPatch of object type");
589 break;
590 default:
591 fatal("unexpected CiKind in DataPatch");
592 break;
593 }
594 }
595
596 void site_ExceptionHandler(CodeBuffer& buffer, jint pc_offset, oop site) {
597
598 }
599
600 void site_Mark(CodeBuffer& buffer, jint pc_offset, oop site) {
601 oop id_obj = CiTargetMethod_Mark::id(site);
602 arrayOop references = (arrayOop)CiTargetMethod_Mark::references(site);
603
604 if (id_obj != NULL) {
605 assert(java_lang_boxing_object::is_instance(id_obj, T_INT), "Integer id expected");
606 jint id = id_obj->int_field(java_lang_boxing_object::value_offset_in_bytes(T_INT));
607
608 address instruction = _instructions->start() + pc_offset;
609
610 switch (id) {
611 case C1XCompiler::MARK_UNVERIFIED_ENTRY:
612 _offsets.set_value(CodeOffsets::Entry, pc_offset);
613 break;
614 case C1XCompiler::MARK_VERIFIED_ENTRY:
615 _offsets.set_value(CodeOffsets::Verified_Entry, pc_offset);
616 break;
617 case C1XCompiler::MARK_STATIC_CALL_STUB: {
618 assert(references->length() == 1, "static call stub needs one reference");
619 oop ref = ((oop*)references->base(T_OBJECT))[0];
620 address call_pc = _instructions->start() + CiTargetMethod_Site::pcOffset(ref);
621 _instructions->relocate(instruction, static_stub_Relocation::spec(call_pc));
622 break;
623 }
624 }
625 }
626 }
627
628 // perform data and call relocation on the CodeBuffer
629 void initialize_buffer(CodeBuffer& buffer) {
630 _oop_recorder = new OopRecorder(_env->arena());
631 _env->set_oop_recorder(_oop_recorder);
632 _debug_recorder = new DebugInformationRecorder(_env->oop_recorder());
633 _debug_recorder->set_oopmaps(new OopMapSet());
634 _dependencies = new Dependencies(_env);
635
636 _env->set_oop_recorder(_oop_recorder);
637 _env->set_debug_info(_debug_recorder);
638 _env->set_dependencies(_dependencies);
639 buffer.initialize_oop_recorder(_oop_recorder);
640
641 buffer.initialize_consts_size(_constants_size);
642 _instructions = buffer.insts();
643 _constants = buffer.consts();
644
645 // copy the code into the newly created CodeBuffer
646 memcpy(_instructions->start(), _code->base(T_BYTE), _code_size);
647 _instructions->set_end(_instructions->start() + _code_size);
648
649 oop* sites = (oop*)_sites->base(T_OBJECT);
650 for (int i=0; i<_sites->length(); i++) {
651 oop site = sites[i];
652 jint pc_offset = CiTargetMethod_Site::pcOffset(site);
653
654 if (site->is_a(CiTargetMethod_Safepoint::klass())) {
655 tty->print_cr("safepoint at %i", pc_offset);
656 site_Safepoint(buffer, pc_offset, site);
657 } else if (site->is_a(CiTargetMethod_Call::klass())) {
658 tty->print_cr("call at %i", pc_offset);
659 site_Call(buffer, pc_offset, site);
660 } else if (site->is_a(CiTargetMethod_DataPatch::klass())) {
661 tty->print_cr("datapatch at %i", pc_offset);
662 site_DataPatch(buffer, pc_offset, site);
663 } else if (site->is_a(CiTargetMethod_ExceptionHandler::klass())) {
664 tty->print_cr("exception handler at %i", pc_offset);
665 site_ExceptionHandler(buffer, pc_offset, site);
666 } else if (site->is_a(CiTargetMethod_Mark::klass())) {
667 tty->print_cr("mark at %i", pc_offset);
668 site_Mark(buffer, pc_offset, site);
669 } else {
670 ShouldNotReachHere();
671 }
672 }
673
674 /*
675 if (_relocation_count > 0) {
676 jint* relocation_offsets = (jint*)((arrayOop)JNIHandles::resolve(_relocation_offsets))->base(T_INT);
677 oop* relocation_objects = (oop*)((arrayOop)JNIHandles::resolve(_relocation_data))->base(T_OBJECT);
678
679 for (int i = 0; i < _relocation_count; i++) {
680 address inst = (address)instructions->start() + relocation_offsets[i];
681 u_char inst_byte = *inst;
682 oop obj = relocation_objects[i];
683 assert(obj != NULL, "NULL oop needn't be patched");
684
685 if (obj->is_a(SystemDictionary::HotSpotProxy_klass())) {
686 jlong id = com_sun_hotspot_c1x_HotSpotProxy::get_id(obj);
687 switch (id & C1XObjects::TYPE_MASK) {
688 case C1XObjects::CONSTANT: {
689 address operand = Assembler::locate_operand(inst, Assembler::imm_operand);
690
691 *((jobject*)operand) = JNIHandles::make_local(C1XObjects::get<oop>(id));
692 instructions->relocate(inst, oop_Relocation::spec_for_immediate(), Assembler::imm_operand);
693 tty->print_cr("relocating (HotSpotType) %02x at %016x/%016x", inst_byte, inst, operand);
694 break;
695 }
696 case C1XObjects::STUB: {
697 address operand = Assembler::locate_operand(inst, Assembler::call32_operand);
698
699 long dest = (long)C1XObjects::getStub(id);
700 long disp = dest - (long)(operand + 4);
701 assert(disp == (int) disp, "disp doesn't fit in 32 bits");
702 *((int*)operand) = (int)disp;
703
704 instructions->relocate(inst, runtime_call_Relocation::spec(), Assembler::call32_operand);
705 tty->print_cr("relocating (Long) %02x at %016x/%016x", inst_byte, inst, operand);
706 break;
707 }
708 }
709 } else if (java_lang_boxing_object::is_instance(obj)) {
710 address operand = Assembler::locate_operand(inst, Assembler::disp32_operand);
711 long dest = (long)constants->end();
712 if (java_lang_boxing_object::is_instance(obj, T_LONG)) {
713 // tty->print("relocate: %l\n", obj->long_field(java_lang_boxing_object::value_offset_in_bytes(T_LONG)));
714 *(jlong*)constants->end() = obj->long_field(java_lang_boxing_object::value_offset_in_bytes(T_LONG));
715 } else if (java_lang_boxing_object::is_instance(obj, T_DOUBLE)) {
716 // tty->print("relocate: %f\n", obj->double_field(java_lang_boxing_object::value_offset_in_bytes(T_DOUBLE)));
717 *(jdouble*)constants->end() = obj->double_field(java_lang_boxing_object::value_offset_in_bytes(T_DOUBLE));
718 } else if (java_lang_boxing_object::is_instance(obj, T_FLOAT)) {
719 // tty->print("relocate: %f\n", obj->double_field(java_lang_boxing_object::value_offset_in_bytes(T_DOUBLE)));
720 *(jfloat*)constants->end() = obj->float_field(java_lang_boxing_object::value_offset_in_bytes(T_FLOAT));
721 }
722 constants->set_end(constants->end() + 8);
723
724 long disp = dest - (long)(operand + 4);
725 assert(disp == (int) disp, "disp doesn't fit in 32 bits");
726 *((int*)operand) = (int)disp;
727
728 instructions->relocate(inst, section_word_Relocation::spec((address)dest, CodeBuffer::SECT_CONSTS), Assembler::disp32_operand);
729 tty->print_cr("relocating (Long/Double) %02x at %016x/%016x", inst_byte, inst, operand);
730 } else if (obj->is_a(_types.HotSpotTypeResolved)) {
731 address operand = Assembler::locate_operand(inst, Assembler::imm_operand);
732
733 *((jobject*)operand) = JNIHandles::make_local(C1XObjects::get<klassOop>(obj->obj_field(_types.HotSpotTypeResolved_klassOop)));
734 instructions->relocate(inst, oop_Relocation::spec_for_immediate(), Assembler::imm_operand);
735 tty->print_cr("relocating (HotSpotType) %02x at %016x/%016x", inst_byte, inst, operand);
736 } else {
737 tty->print_cr("unknown relocation type");
738 obj->print();
739 }
740 }
741 }*/
742 }
743 };
744
745 // public void installMethod(HotSpotTargetMethod targetMethod);
746 JNIEXPORT void JNICALL Java_com_sun_hotspot_c1x_VMEntries_installMethod(JNIEnv *jniEnv, jobject, jobject targetMethod) {
747 CodeInstaller installer(JNIHandles::resolve(targetMethod));
748 }
749
750 // public HotSpotProxy installStub(HotSpotTargetMethod targetMethod, String name);
751 JNIEXPORT jlong JNICALL Java_com_sun_hotspot_c1x_VMEntries_installStub(JNIEnv *jniEnv, jobject, jobject targetMethod) {
752 jlong id;
753 CodeInstaller installer(JNIHandles::resolve(targetMethod), id);
754 return id;
755 }
756
757
758
759
760 #define CC (char*) /*cast a literal from (const char*)*/
761 #define FN_PTR(f) CAST_FROM_FN_PTR(void*, &f)
762
763 #define PROXY "J"
764 #define TYPE "Lcom/sun/cri/ri/RiType;"
765 #define METHOD "Lcom/sun/cri/ri/RiMethod;"
766 #define SIGNATURE "Lcom/sun/cri/ri/RiSignature;"
767 #define FIELD "Lcom/sun/cri/ri/RiField;"
768 #define CONSTANT_POOL "Lcom/sun/cri/ri/RiConstantPool;"
769 #define TARGET_METHOD "Lcom/sun/hotspot/c1x/HotSpotTargetMethod;"
770 #define CONFIG "Lcom/sun/hotspot/c1x/HotSpotVMConfig;"
771 #define HS_METHOD "Lcom/sun/hotspot/c1x/HotSpotMethod;"
772 #define CI_CONSTANT "Lcom/sun/cri/ci/CiConstant;"
773 #define STRING "Ljava/lang/String;"
774 #define OBJECT "Ljava/lang/Object;"
453 775
454 JNINativeMethod VMEntries_methods[] = { 776 JNINativeMethod VMEntries_methods[] = {
455 {CC"RiMethod_code", CC"(Ljava/lang/reflect/Method;)[B", FN_PTR(Java_com_sun_hotspot_c1x_VMEntries_RiMethod_1code)}, 777 {CC"RiMethod_code", CC"("PROXY")[B", FN_PTR(Java_com_sun_hotspot_c1x_VMEntries_RiMethod_1code)},
456 {CC"RiMethod_maxStackSize", CC"(Ljava/lang/reflect/Method;)I", FN_PTR(Java_com_sun_hotspot_c1x_VMEntries_RiMethod_1maxStackSize)}, 778 {CC"RiMethod_maxStackSize", CC"("PROXY")I", FN_PTR(Java_com_sun_hotspot_c1x_VMEntries_RiMethod_1maxStackSize)},
457 {CC"RiMethod_maxLocals", CC"(Ljava/lang/reflect/Method;)I", FN_PTR(Java_com_sun_hotspot_c1x_VMEntries_RiMethod_1maxLocals)}, 779 {CC"RiMethod_maxLocals", CC"("PROXY")I", FN_PTR(Java_com_sun_hotspot_c1x_VMEntries_RiMethod_1maxLocals)},
458 {CC"RiMethod_holder", CC"(Ljava/lang/reflect/Method;)Lcom/sun/cri/ri/RiType;", FN_PTR(Java_com_sun_hotspot_c1x_VMEntries_RiMethod_1holder)}, 780 {CC"RiMethod_holder", CC"("PROXY")"TYPE, FN_PTR(Java_com_sun_hotspot_c1x_VMEntries_RiMethod_1holder)},
459 {CC"RiMethod_signature", CC"(Ljava/lang/reflect/Method;)Ljava/lang/String;", FN_PTR(Java_com_sun_hotspot_c1x_VMEntries_RiMethod_1signature)}, 781 {CC"RiMethod_signature", CC"("PROXY")"STRING, FN_PTR(Java_com_sun_hotspot_c1x_VMEntries_RiMethod_1signature)},
460 {CC"RiMethod_name", CC"(Ljava/lang/reflect/Method;)Ljava/lang/String;", FN_PTR(Java_com_sun_hotspot_c1x_VMEntries_RiMethod_1name)}, 782 {CC"RiMethod_accessFlags", CC"("PROXY")I", FN_PTR(Java_com_sun_hotspot_c1x_VMEntries_RiMethod_1accessFlags)},
461 {CC"RiMethod_accessFlags", CC"(Ljava/lang/reflect/Method;)I", FN_PTR(Java_com_sun_hotspot_c1x_VMEntries_RiMethod_1accessFlags)}, 783 {CC"RiSignature_lookupType", CC"("STRING PROXY")"TYPE, FN_PTR(Java_com_sun_hotspot_c1x_VMEntries_RiSignature_1lookupType)},
462 {CC"RiSignature_lookupType", CC"(Ljava/lang/String;Ljava/lang/Class;)Lcom/sun/cri/ri/RiType;", FN_PTR(Java_com_sun_hotspot_c1x_VMEntries_RiSignature_1lookupType)}, 784 {CC"RiConstantPool_lookupConstant", CC"("PROXY"I)"CI_CONSTANT, FN_PTR(Java_com_sun_hotspot_c1x_VMEntries_RiConstantPool_1lookupConstant)},
463 {CC"RiType_name", CC"(Ljava/lang/Class;)Ljava/lang/String;", FN_PTR(Java_com_sun_hotspot_c1x_VMEntries_RiType_1name)}, 785 {CC"RiConstantPool_lookupMethod", CC"("PROXY"IB)"METHOD, FN_PTR(Java_com_sun_hotspot_c1x_VMEntries_RiConstantPool_1lookupMethod)},
464 {CC"RiConstantPool_lookupConstant", CC"(Ljava/lang/Class;I)Ljava/lang/Object;", FN_PTR(Java_com_sun_hotspot_c1x_VMEntries_RiConstantPool_1lookupConstant)}, 786 {CC"RiConstantPool_lookupSignature", CC"("PROXY"I)"SIGNATURE, FN_PTR(Java_com_sun_hotspot_c1x_VMEntries_RiConstantPool_1lookupSignature)},
465 {CC"RiConstantPool_lookupMethod", CC"(Ljava/lang/Class;IB)Lcom/sun/cri/ri/RiMethod;", FN_PTR(Java_com_sun_hotspot_c1x_VMEntries_RiConstantPool_1lookupMethod)}, 787 {CC"RiConstantPool_lookupType", CC"("PROXY"I)"TYPE, FN_PTR(Java_com_sun_hotspot_c1x_VMEntries_RiConstantPool_1lookupType)},
466 {CC"RiConstantPool_lookupSignature", CC"(Ljava/lang/Class;I)Lcom/sun/cri/ri/RiSignature;", FN_PTR(Java_com_sun_hotspot_c1x_VMEntries_RiConstantPool_1lookupSignature)}, 788 {CC"RiConstantPool_lookupField", CC"("PROXY"I)"FIELD, FN_PTR(Java_com_sun_hotspot_c1x_VMEntries_RiConstantPool_1lookupField)},
467 {CC"RiConstantPool_lookupType", CC"(Ljava/lang/Class;I)Lcom/sun/cri/ri/RiType;", FN_PTR(Java_com_sun_hotspot_c1x_VMEntries_RiConstantPool_1lookupType)}, 789 {CC"RiType_constantPool", CC"("PROXY")"CONSTANT_POOL, FN_PTR(Java_com_sun_hotspot_c1x_VMEntries_RiType_1constantPool)},
468 {CC"RiConstantPool_lookupField", CC"(Ljava/lang/Class;I)Lcom/sun/cri/ri/RiField;", FN_PTR(Java_com_sun_hotspot_c1x_VMEntries_RiConstantPool_1lookupField)}, 790 {CC"RiType_isArrayClass", CC"("PROXY")Z", FN_PTR(Java_com_sun_hotspot_c1x_VMEntries_RiType_1isArrayClass)},
469 {CC"RiType_isArrayClass", CC"(Ljava/lang/Class;)Z", FN_PTR(Java_com_sun_hotspot_c1x_VMEntries_RiType_1isArrayClass)}, 791 {CC"RiType_isInstanceClass", CC"("PROXY")Z", FN_PTR(Java_com_sun_hotspot_c1x_VMEntries_RiType_1isInstanceClass)},
470 {CC"RiType_isInstanceClass", CC"(Ljava/lang/Class;)Z", FN_PTR(Java_com_sun_hotspot_c1x_VMEntries_RiType_1isInstanceClass)}, 792 {CC"RiType_isInterface", CC"("PROXY")Z", FN_PTR(Java_com_sun_hotspot_c1x_VMEntries_RiType_1isInterface)},
471 {CC"RiType_isInterface", CC"(Ljava/lang/Class;)Z", FN_PTR(Java_com_sun_hotspot_c1x_VMEntries_RiType_1isInterface)}, 793 {CC"getConfiguration", CC"()"CONFIG, FN_PTR(Java_com_sun_hotspot_c1x_VMEntries_getConfiguration)},
472 {CC"installCode", CC"(Lcom/sun/hotspot/c1x/HotSpotTargetMethod;)V", FN_PTR(Java_com_sun_hotspot_c1x_VMEntries_installCode)}, 794 {CC"installMethod", CC"("TARGET_METHOD")V", FN_PTR(Java_com_sun_hotspot_c1x_VMEntries_installMethod)},
473 {CC"getConfiguration", CC"()Lcom/sun/hotspot/c1x/HotSpotVMConfig;", FN_PTR(Java_com_sun_hotspot_c1x_VMEntries_getConfiguration)} 795 {CC"installStub", CC"("TARGET_METHOD")"PROXY, FN_PTR(Java_com_sun_hotspot_c1x_VMEntries_installStub)}
474 }; 796 };
475 797
476 int VMEntries_methods_count() { 798 int VMEntries_methods_count() {
477 return sizeof(VMEntries_methods) / sizeof(JNINativeMethod); 799 return sizeof(VMEntries_methods) / sizeof(JNINativeMethod);
478 } 800 }