219 220 // Creating value 221 bool in_heap; 222 instanceOop value = vklass->allocate_buffered_or_heap_instance(&in_heap, CHECK); 223 Handle value_h = Handle(THREAD, value); 224 225 thread->set_vm_result(value_h()); 226 IRT_END 227 228 IRT_ENTRY(int, InterpreterRuntime::vwithfield(JavaThread* thread, ConstantPoolCache* cp_cache)) 229 // Getting the ValueKlass 230 int index = ConstantPool::decode_cpcache_index(get_index_u2_cpcache(thread, Bytecodes::_vwithfield)); 231 ConstantPoolCacheEntry* cp_entry = cp_cache->entry_at(index); 232 assert(cp_entry->is_resolved(Bytecodes::_vwithfield), "Should have been resolved"); 233 Klass* klass = cp_entry->f1_as_klass(); 234 assert(klass->is_value(), "vwithfield only applies to value types"); 235 ValueKlass* vklass = ValueKlass::cast(klass); 236 237 // Getting Field information 238 int offset = cp_entry->f2_as_index(); 239 fieldDescriptor fd; 240 vklass->find_field_from_offset(offset, false, &fd); 241 Symbol* field_signature = fd.signature(); 242 ResourceMark rm(THREAD); 243 const char* signature = (const char *) field_signature->as_utf8(); 244 BasicType field_type = char2type(signature[0]); 245 246 // Getting old value 247 frame f = last_frame(thread); 248 jint tos_idx = f.interpreter_frame_expression_stack_size() - 1; 249 int vt_offset = type2size[field_type]; 250 oop old_value = *(oop*)f.interpreter_frame_expression_stack_at(tos_idx - vt_offset); 251 assert(old_value != NULL && oopDesc::is_oop(old_value) && old_value->is_value(),"Verifying receiver"); 252 Handle old_value_h(THREAD, old_value); 253 254 // Creating new value by copying the one passed in argument 255 bool in_heap; 256 instanceOop new_value = vklass->allocate_buffered_or_heap_instance(&in_heap, 257 CHECK_((type2size[field_type]) * AbstractInterpreter::stackElementSize)); 258 Handle new_value_h = Handle(THREAD, new_value); 259 int first_offset = vklass->first_field_offset(); 260 vklass->value_store(vklass->data_for_oop(old_value_h()), 261 vklass->data_for_oop(new_value_h()), in_heap, false); 262 263 // Updating the field specified in arguments 264 if (field_type == T_OBJECT || field_type == T_ARRAY) { 265 oop aoop = *(oop*)f.interpreter_frame_expression_stack_at(tos_idx); 266 assert(aoop == NULL || (oopDesc::is_oop(aoop) && (!aoop->is_value())),"argument must be a reference type"); 267 new_value_h()->obj_field_put(fd.offset(), aoop); 268 } else if (field_type == T_VALUETYPE) { 269 Klass* field_k = vklass->get_value_field_klass(fd.index()); 270 ValueKlass* field_vk = ValueKlass::cast(field_k); 271 oop vt_oop = *(oop*)f.interpreter_frame_expression_stack_at(tos_idx); 272 assert(vt_oop != NULL && oopDesc::is_oop(vt_oop) && vt_oop->is_value(),"argument must be a value type"); 273 assert(field_vk == vt_oop->klass(), "Must match"); 274 field_vk->value_store(field_vk->data_for_oop(vt_oop), 275 ((char*)(oopDesc*)new_value_h()) + fd.offset(), true, false); 276 } else { 277 intptr_t* addr = f.interpreter_frame_expression_stack_at(tos_idx); 278 copy_primitive_argument(addr, new_value_h, fd.offset(), field_type); 279 } 280 281 // returning result 282 thread->set_vm_result(new_value_h()); 283 return (type2size[field_type] + type2size[T_VALUETYPE]) * AbstractInterpreter::stackElementSize; 284 IRT_END 285 286 IRT_ENTRY(void, InterpreterRuntime::vbox(JavaThread* thread, ConstantPool* pool, int index, oopDesc* value)) 287 assert(EnableMVT, "vbox is supported only when the MVT programming model is enabled"); 288 if (value == NULL) { 289 THROW(vmSymbols::java_lang_NullPointerException()); 290 } 291 292 // Since the verifier is probably disabled, a few extra type check 293 Klass* target_klass = pool->klass_at(index, CHECK); 294 if (target_klass->is_value()) { 295 THROW_MSG(vmSymbols::java_lang_ClassCastException(), "vbox target is value type"); 296 } 297 Klass* klass = value->klass(); 298 if (!klass->is_value()) { 313 if (obj == NULL) { 314 THROW(vmSymbols::java_lang_NullPointerException()); 315 } 316 Klass* target_klass = pool->klass_at(index, CHECK); 317 if (!target_klass->is_value()) { 318 THROW_MSG(vmSymbols::java_lang_ClassCastException(), "vunbox target is not value type"); 319 } 320 Klass* klass = obj->klass(); 321 if ((!klass->is_instance_klass()) || klass->is_value()) { 322 THROW_MSG(vmSymbols::java_lang_ClassCastException(), "vunbox source is not an instance"); 323 } 324 if (klass != InstanceKlass::cast(target_klass)->get_vcc_klass()) { 325 THROW_MSG(vmSymbols::java_lang_ClassCastException(), "vunbox target is not derive value type"); 326 } 327 oop value = ValueKlass::cast(target_klass)->unbox(Handle(THREAD, obj), 328 InstanceKlass::cast(target_klass), 329 CHECK); 330 thread->set_vm_result(value); 331 IRT_END 332 333 IRT_ENTRY(void, InterpreterRuntime::qgetfield(JavaThread* thread, oopDesc* value, int offset)) 334 Handle value_h(THREAD, value); 335 InstanceKlass* klass = InstanceKlass::cast(value->klass()); 336 337 fieldDescriptor fd; 338 klass->find_field_from_offset(offset, false, &fd); 339 Klass* field_k = klass->get_value_field_klass(fd.index()); 340 ValueKlass* field_vklass = ValueKlass::cast(field_k); 341 field_vklass->initialize(THREAD); 342 343 // allocate instance 344 bool in_heap; 345 instanceOop res = field_vklass->allocate_buffered_or_heap_instance(&in_heap, CHECK); 346 instanceHandle res_h(THREAD, res); 347 // copy value 348 field_vklass->value_store(((char*)(oopDesc*)value_h()) + offset, 349 field_vklass->data_for_oop(res), in_heap, false); 350 thread->set_vm_result(res_h()); 351 IRT_END 352 353 IRT_ENTRY(void, InterpreterRuntime::initialize_static_value_field(JavaThread* thread, oopDesc* mirror, int offset)) 354 instanceHandle mirror_h(THREAD, (instanceOop)mirror); 355 InstanceKlass* klass = InstanceKlass::cast(java_lang_Class::as_Klass(mirror)); 356 assert(mirror->obj_field(offset) == NULL,"Field must not be initialized twice"); 357 358 fieldDescriptor fd; 359 klass->find_field_from_offset(offset, true, &fd); 360 Klass* field_k = klass->get_value_field_klass(fd.index()); 361 ValueKlass* field_vklass = ValueKlass::cast(field_k); 362 // allocate instance, because it is going to be assigned to a static field 363 // it must not be a buffered value 364 instanceOop res = field_vklass->allocate_instance(CHECK); 365 instanceHandle res_h(THREAD, res); 366 mirror_h()->obj_field_put(offset, res_h()); 367 thread->set_vm_result(res_h()); 368 IRT_END 369 370 IRT_ENTRY(void, InterpreterRuntime::qputfield(JavaThread* thread, oopDesc* obj, oopDesc* value, int offset)) 371 Handle value_h(THREAD, value); 372 Handle obj_h(THREAD, obj); 373 assert(!obj_h()->klass()->is_value(), "obj must be an object"); 374 assert(value_h()->klass()->is_value(), "value must be an value type"); 375 376 InstanceKlass* klass = InstanceKlass::cast(obj->klass()); 377 fieldDescriptor fd; 378 klass->find_field_from_offset(offset, false, &fd); 379 Klass* field_k = klass->get_value_field_klass(fd.index()); 380 ValueKlass* field_vklass = ValueKlass::cast(value->klass()); 381 assert(field_k == field_vklass, "Field descriptor and argument must match"); 382 // copy value 383 field_vklass->value_store(field_vklass->data_for_oop(value_h()), 384 ((char*)(oopDesc*)obj_h()) + offset, true, false); 385 IRT_END 386 387 IRT_ENTRY(void, InterpreterRuntime::qputstatic(JavaThread* thread, oopDesc* value)) 388 instanceHandle value_h(THREAD, (instanceOop)value); 389 assert(value_h()->is_value(), "qputstatic only deals with value arguments"); 390 Method* m = last_frame(thread).interpreter_frame_method(); 391 jint bci = last_frame(thread).interpreter_frame_bci(); 392 assert(m->code_at(bci) == Bytecodes::_putstatic, "qputstatic is a particular case of putstatic"); 393 ConstantPoolCache* cp_cache = last_frame(thread).interpreter_frame_method()->constants()->cache(); 394 int index = ConstantPool::decode_cpcache_index(get_index_u2_cpcache(thread, Bytecodes::_putstatic)); 395 ConstantPoolCacheEntry* cp_entry = cp_cache->entry_at(index); 396 assert(cp_entry->is_field_entry(), "Sanity check"); 397 398 InstanceKlass* klass = InstanceKlass::cast(cp_entry->f1_as_klass()); 399 int offset = cp_entry->f2_as_index(); 400 oop mirror = klass->java_mirror(); 401 402 if (Universe::heap()->is_in_reserved(value_h())) { 403 mirror->obj_field_put(offset, value_h()); 404 } else { 405 // The argument is a buffered value, a copy must be created in the Java heap 406 // because a static field cannot point to a thread-local buffered value 407 fieldDescriptor fd; 408 klass->find_field_from_offset(offset, false, &fd); 409 Klass* field_k = klass->get_value_field_klass(fd.index()); 410 ValueKlass* field_vklass = ValueKlass::cast(field_k); 411 assert(field_vklass == value->klass(), "Field descriptor and argument must match"); 412 // allocate heap instance 413 instanceOop res = field_vklass->allocate_instance(CHECK); 414 assert(Universe::heap()->is_in_reserved(res), "Must be in the Java heap"); 415 instanceHandle res_h(THREAD, res); 416 // copy value 417 field_vklass->value_store(field_vklass->data_for_oop(value_h()), 418 field_vklass->data_for_oop(res), true, false); 419 // writing static field 420 mirror->obj_field_put(offset, res_h()); 421 assert(mirror->obj_field(offset) != NULL,"Sanity check"); 422 } 423 IRT_END 424 425 IRT_ENTRY(void, InterpreterRuntime::newarray(JavaThread* thread, BasicType type, jint size)) 426 oop obj = oopFactory::new_typeArray(type, size, CHECK); 427 thread->set_vm_result(obj); 428 IRT_END 429 430 431 IRT_ENTRY(void, InterpreterRuntime::anewarray(JavaThread* thread, ConstantPool* pool, int index, jint size)) 432 Klass* klass = pool->klass_at(index, CHECK); 433 if (klass->is_value()) { // Logically creates elements, ensure klass init 434 klass->initialize(CHECK); 435 } 436 arrayOop obj = oopFactory::new_array(klass, size, CHECK); 437 thread->set_vm_result(obj); 438 IRT_END 439 440 IRT_ENTRY(void, InterpreterRuntime::value_array_load(JavaThread* thread, arrayOopDesc* array, int index)) 441 Klass* klass = array->klass(); | 219 220 // Creating value 221 bool in_heap; 222 instanceOop value = vklass->allocate_buffered_or_heap_instance(&in_heap, CHECK); 223 Handle value_h = Handle(THREAD, value); 224 225 thread->set_vm_result(value_h()); 226 IRT_END 227 228 IRT_ENTRY(int, InterpreterRuntime::vwithfield(JavaThread* thread, ConstantPoolCache* cp_cache)) 229 // Getting the ValueKlass 230 int index = ConstantPool::decode_cpcache_index(get_index_u2_cpcache(thread, Bytecodes::_vwithfield)); 231 ConstantPoolCacheEntry* cp_entry = cp_cache->entry_at(index); 232 assert(cp_entry->is_resolved(Bytecodes::_vwithfield), "Should have been resolved"); 233 Klass* klass = cp_entry->f1_as_klass(); 234 assert(klass->is_value(), "vwithfield only applies to value types"); 235 ValueKlass* vklass = ValueKlass::cast(klass); 236 237 // Getting Field information 238 int offset = cp_entry->f2_as_index(); 239 int field_index = cp_entry->field_index(); 240 int field_offset = cp_entry->f2_as_offset(); 241 Symbol* field_signature = vklass->field_signature(field_index); 242 ResourceMark rm(THREAD); 243 const char* signature = (const char *) field_signature->as_utf8(); 244 BasicType field_type = char2type(signature[0]); 245 246 // Getting old value 247 frame f = last_frame(thread); 248 jint tos_idx = f.interpreter_frame_expression_stack_size() - 1; 249 int vt_offset = type2size[field_type]; 250 oop old_value = *(oop*)f.interpreter_frame_expression_stack_at(tos_idx - vt_offset); 251 assert(old_value != NULL && oopDesc::is_oop(old_value) && old_value->is_value(),"Verifying receiver"); 252 Handle old_value_h(THREAD, old_value); 253 254 // Creating new value by copying the one passed in argument 255 bool in_heap; 256 instanceOop new_value = vklass->allocate_buffered_or_heap_instance(&in_heap, 257 CHECK_((type2size[field_type]) * AbstractInterpreter::stackElementSize)); 258 Handle new_value_h = Handle(THREAD, new_value); 259 int first_offset = vklass->first_field_offset(); 260 vklass->value_store(vklass->data_for_oop(old_value_h()), 261 vklass->data_for_oop(new_value_h()), in_heap, false); 262 263 // Updating the field specified in arguments 264 if (field_type == T_OBJECT || field_type == T_ARRAY) { 265 oop aoop = *(oop*)f.interpreter_frame_expression_stack_at(tos_idx); 266 assert(aoop == NULL || (oopDesc::is_oop(aoop) && (!aoop->is_value())),"argument must be a reference type"); 267 new_value_h()->obj_field_put(field_offset, aoop); 268 } else if (field_type == T_VALUETYPE) { 269 Klass* field_k = vklass->get_value_field_klass(field_index); 270 ValueKlass* field_vk = ValueKlass::cast(field_k); 271 oop vt_oop = *(oop*)f.interpreter_frame_expression_stack_at(tos_idx); 272 assert(vt_oop != NULL && oopDesc::is_oop(vt_oop) && vt_oop->is_value(),"argument must be a value type"); 273 assert(field_vk == vt_oop->klass(), "Must match"); 274 field_vk->value_store(field_vk->data_for_oop(vt_oop), 275 ((char*)(oopDesc*)new_value_h()) + field_offset, true, false); 276 } else { 277 intptr_t* addr = f.interpreter_frame_expression_stack_at(tos_idx); 278 copy_primitive_argument(addr, new_value_h, field_offset, field_type); 279 } 280 281 // returning result 282 thread->set_vm_result(new_value_h()); 283 return (type2size[field_type] + type2size[T_VALUETYPE]) * AbstractInterpreter::stackElementSize; 284 IRT_END 285 286 IRT_ENTRY(void, InterpreterRuntime::vbox(JavaThread* thread, ConstantPool* pool, int index, oopDesc* value)) 287 assert(EnableMVT, "vbox is supported only when the MVT programming model is enabled"); 288 if (value == NULL) { 289 THROW(vmSymbols::java_lang_NullPointerException()); 290 } 291 292 // Since the verifier is probably disabled, a few extra type check 293 Klass* target_klass = pool->klass_at(index, CHECK); 294 if (target_klass->is_value()) { 295 THROW_MSG(vmSymbols::java_lang_ClassCastException(), "vbox target is value type"); 296 } 297 Klass* klass = value->klass(); 298 if (!klass->is_value()) { 313 if (obj == NULL) { 314 THROW(vmSymbols::java_lang_NullPointerException()); 315 } 316 Klass* target_klass = pool->klass_at(index, CHECK); 317 if (!target_klass->is_value()) { 318 THROW_MSG(vmSymbols::java_lang_ClassCastException(), "vunbox target is not value type"); 319 } 320 Klass* klass = obj->klass(); 321 if ((!klass->is_instance_klass()) || klass->is_value()) { 322 THROW_MSG(vmSymbols::java_lang_ClassCastException(), "vunbox source is not an instance"); 323 } 324 if (klass != InstanceKlass::cast(target_klass)->get_vcc_klass()) { 325 THROW_MSG(vmSymbols::java_lang_ClassCastException(), "vunbox target is not derive value type"); 326 } 327 oop value = ValueKlass::cast(target_klass)->unbox(Handle(THREAD, obj), 328 InstanceKlass::cast(target_klass), 329 CHECK); 330 thread->set_vm_result(value); 331 IRT_END 332 333 IRT_ENTRY(void, InterpreterRuntime::qgetfield(JavaThread* thread, oopDesc* value, int index)) 334 Handle value_h(THREAD, value); 335 InstanceKlass* klass = InstanceKlass::cast(value->klass()); 336 337 Klass* field_k = klass->get_value_field_klass(index); 338 ValueKlass* field_vklass = ValueKlass::cast(field_k); 339 field_vklass->initialize(THREAD); 340 341 // allocate instance 342 bool in_heap; 343 instanceOop res = field_vklass->allocate_buffered_or_heap_instance(&in_heap, CHECK); 344 instanceHandle res_h(THREAD, res); 345 // copy value 346 field_vklass->value_store(((char*)(oopDesc*)value_h()) + klass->field_offset(index), 347 field_vklass->data_for_oop(res), in_heap, false); 348 thread->set_vm_result(res_h()); 349 IRT_END 350 351 IRT_ENTRY(void, InterpreterRuntime::initialize_static_value_field(JavaThread* thread, oopDesc* mirror, int index)) 352 instanceHandle mirror_h(THREAD, (instanceOop)mirror); 353 InstanceKlass* klass = InstanceKlass::cast(java_lang_Class::as_Klass(mirror)); 354 int offset = klass->field_offset(index); 355 assert(mirror->obj_field(offset) == NULL,"Field must not be initialized twice"); 356 357 Klass* field_k = klass->get_value_field_klass(index); 358 ValueKlass* field_vklass = ValueKlass::cast(field_k); 359 // allocate instance, because it is going to be assigned to a static field 360 // it must not be a buffered value 361 instanceOop res = field_vklass->allocate_instance(CHECK); 362 instanceHandle res_h(THREAD, res); 363 mirror_h()->obj_field_put(offset, res_h()); 364 thread->set_vm_result(res_h()); 365 IRT_END 366 367 IRT_ENTRY(void, InterpreterRuntime::qputfield(JavaThread* thread, oopDesc* obj, oopDesc* value, int flags)) 368 Handle value_h(THREAD, value); 369 Handle obj_h(THREAD, obj); 370 assert(!obj_h()->klass()->is_value(), "obj must be an object"); 371 assert(value_h()->klass()->is_value(), "value must be an value type"); 372 int index = flags & ConstantPoolCacheEntry::field_index_mask; 373 374 InstanceKlass* klass = InstanceKlass::cast(obj->klass()); 375 Klass* field_k = klass->get_value_field_klass(index); 376 ValueKlass* field_vklass = ValueKlass::cast(value->klass()); 377 assert(field_k == field_vklass, "Field descriptor and argument must match"); 378 // copy value 379 field_vklass->value_store(field_vklass->data_for_oop(value_h()), 380 ((char*)(oopDesc*)obj_h()) + klass->field_offset(index), true, false); 381 IRT_END 382 383 IRT_ENTRY(void, InterpreterRuntime::qputstatic(JavaThread* thread, oopDesc* value, int offset, oopDesc* mirror)) 384 instanceHandle value_h(THREAD, (instanceOop)value); 385 assert(value_h()->is_value(), "qputstatic only deals with value arguments"); 386 if (Universe::heap()->is_in_reserved(value_h())) { 387 mirror->obj_field_put(offset, value_h()); 388 } else { 389 // The argument is a buffered value, a copy must be created in the Java heap 390 // because a static field cannot point to a thread-local buffered value 391 ValueKlass* field_vklass = ValueKlass::cast(value_h()->klass()); 392 Handle mirror_h(THREAD, mirror); 393 // allocate heap instance 394 instanceOop res = field_vklass->allocate_instance(CHECK); 395 assert(Universe::heap()->is_in_reserved(res), "Must be in the Java heap"); 396 instanceHandle res_h(THREAD, res); 397 // copy value 398 field_vklass->value_store(field_vklass->data_for_oop(value_h()), 399 field_vklass->data_for_oop(res), true, false); 400 // writing static field 401 mirror_h->obj_field_put(offset, res_h()); 402 assert(mirror_h->obj_field(offset) != NULL,"Sanity check"); 403 } 404 IRT_END 405 406 IRT_ENTRY(void, InterpreterRuntime::newarray(JavaThread* thread, BasicType type, jint size)) 407 oop obj = oopFactory::new_typeArray(type, size, CHECK); 408 thread->set_vm_result(obj); 409 IRT_END 410 411 412 IRT_ENTRY(void, InterpreterRuntime::anewarray(JavaThread* thread, ConstantPool* pool, int index, jint size)) 413 Klass* klass = pool->klass_at(index, CHECK); 414 if (klass->is_value()) { // Logically creates elements, ensure klass init 415 klass->initialize(CHECK); 416 } 417 arrayOop obj = oopFactory::new_array(klass, size, CHECK); 418 thread->set_vm_result(obj); 419 IRT_END 420 421 IRT_ENTRY(void, InterpreterRuntime::value_array_load(JavaThread* thread, arrayOopDesc* array, int index)) 422 Klass* klass = array->klass(); |