55 #include "runtime/biasedLocking.hpp"
56 #include "runtime/compilationPolicy.hpp"
57 #include "runtime/deoptimization.hpp"
58 #include "runtime/fieldDescriptor.hpp"
59 #include "runtime/handles.inline.hpp"
60 #include "runtime/icache.hpp"
61 #include "runtime/interfaceSupport.hpp"
62 #include "runtime/java.hpp"
63 #include "runtime/jfieldIDWorkaround.hpp"
64 #include "runtime/osThread.hpp"
65 #include "runtime/sharedRuntime.hpp"
66 #include "runtime/stubRoutines.hpp"
67 #include "runtime/synchronizer.hpp"
68 #include "runtime/threadCritical.hpp"
69 #include "utilities/align.hpp"
70 #include "utilities/events.hpp"
71 #include "utilities/globalDefinitions.hpp"
72 #ifdef COMPILER2
73 #include "opto/runtime.hpp"
74 #endif
75
76 class UnlockFlagSaver {
77 private:
78 JavaThread* _thread;
79 bool _do_not_unlock;
80 public:
81 UnlockFlagSaver(JavaThread* t) {
82 _thread = t;
83 _do_not_unlock = t->do_not_unlock_if_synchronized();
84 t->set_do_not_unlock_if_synchronized(false);
85 }
86 ~UnlockFlagSaver() {
87 _thread->set_do_not_unlock_if_synchronized(_do_not_unlock);
88 }
89 };
90
91 //------------------------------------------------------------------------------------------------------------------------
92 // State accessors
93
94 void InterpreterRuntime::set_bcp_and_mdp(address bcp, JavaThread *thread) {
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 if (cp_entry->is_flatten()) {
270 Klass* field_k = vklass->get_value_field_klass(field_index);
271 ValueKlass* field_vk = ValueKlass::cast(field_k);
272 oop vt_oop = *(oop*)f.interpreter_frame_expression_stack_at(tos_idx);
273 assert(vt_oop != NULL && oopDesc::is_oop(vt_oop) && vt_oop->is_value(),"argument must be a value type");
274 assert(field_vk == vt_oop->klass(), "Must match");
275 field_vk->value_store(field_vk->data_for_oop(vt_oop),
276 ((char*)(oopDesc*)new_value_h()) + field_offset, true, false);
277 } else {
278 oop voop = *(oop*)f.interpreter_frame_expression_stack_at(tos_idx);
279 assert(voop != NULL || (oopDesc::is_oop(voop) && (voop->is_value())),"argument must be a value type");
280 new_value_h()->obj_field_put(field_offset, voop);
281 }
282 } else {
283 intptr_t* addr = f.interpreter_frame_expression_stack_at(tos_idx);
284 copy_primitive_argument(addr, new_value_h, field_offset, field_type);
285 }
286
287 // returning result
288 thread->set_vm_result(new_value_h());
289 return (type2size[field_type] + type2size[T_VALUETYPE]) * AbstractInterpreter::stackElementSize;
290 IRT_END
291
292 IRT_ENTRY(void, InterpreterRuntime::vbox(JavaThread* thread, ConstantPool* pool, int index, oopDesc* value))
293 assert(EnableMVT, "vbox is supported only when the MVT programming model is enabled");
294 if (value == NULL) {
295 THROW(vmSymbols::java_lang_NullPointerException());
296 }
297
298 // Since the verifier is probably disabled, a few extra type check
299 Klass* target_klass = pool->klass_at(index, CHECK);
300 if (target_klass->is_value()) {
341 InstanceKlass* klass = InstanceKlass::cast(field_holder);
342
343 Klass* field_k = klass->get_value_field_klass(index);
344 ValueKlass* field_vklass = ValueKlass::cast(field_k);
345 field_vklass->initialize(THREAD);
346
347 instanceOop res;
348 bool in_heap;
349 if (klass->is_field_flatten(index)) {
350 // allocate instance
351 res = field_vklass->allocate_buffered_or_heap_instance(&in_heap, CHECK);
352 instanceHandle res_h(THREAD, res);
353 // copy value
354 field_vklass->value_store(((char*)(oopDesc*)value_h()) + klass->field_offset(index),
355 field_vklass->data_for_oop(res), in_heap, false);
356 thread->set_vm_result(res_h());
357 } else {
358 oop res = value_h()->obj_field_acquire(klass->field_offset(index));
359 if (res == NULL) {
360 res = field_vklass->allocate_buffered_or_heap_instance(&in_heap, CHECK);
361 }
362 thread->set_vm_result(res);
363 }
364 IRT_END
365
366 IRT_ENTRY(void, InterpreterRuntime::initialize_static_value_field(JavaThread* thread, oopDesc* mirror, int index))
367 instanceHandle mirror_h(THREAD, (instanceOop)mirror);
368 InstanceKlass* klass = InstanceKlass::cast(java_lang_Class::as_Klass(mirror));
369 int offset = klass->field_offset(index);
370 assert(mirror->obj_field(offset) == NULL,"Field must not be initialized twice");
371
372 Klass* field_k = klass->get_value_field_klass_or_null(index);
373 if (field_k == NULL) {
374 field_k = SystemDictionary::resolve_or_fail(klass->field_signature(index),
375 Handle(THREAD, klass->class_loader()),
376 Handle(THREAD, klass->protection_domain()), true, CHECK);
377 assert(field_k != NULL, "Sanity check");
378 assert(field_k->access_flags().is_value_type(), "Value type expected");
379 klass->set_value_field_klass(index, field_k);
380 }
381 ValueKlass* field_vklass = ValueKlass::cast(field_k);
382 // allocate instance, because it is going to be assigned to a static field
383 // it must not be a buffered value
385 instanceHandle res_h(THREAD, res);
386 mirror_h()->obj_field_put(offset, res_h());
387 thread->set_vm_result(res_h());
388 IRT_END
389
390 IRT_ENTRY(void, InterpreterRuntime::qputfield(JavaThread* thread, oopDesc* obj, oopDesc* value, ConstantPoolCache* cp_cache))
391 Handle value_h(THREAD, value);
392 Handle obj_h(THREAD, obj);
393 assert(!obj_h()->klass()->is_value(), "obj must be an object");
394 assert(value_h()->klass()->is_value(), "value must be an value type");
395
396 int idx = ConstantPool::decode_cpcache_index(get_index_u2_cpcache(thread, Bytecodes::_putfield));
397 ConstantPoolCacheEntry* cp_entry = cp_cache->entry_at(idx);
398
399 int index = cp_entry->field_index();
400 bool flatten = cp_entry->is_flatten();
401
402 InstanceKlass* klass = InstanceKlass::cast(cp_entry->f1_as_klass());
403 Klass* field_k = klass->get_value_field_klass(index);
404 ValueKlass* field_vklass = ValueKlass::cast(value->klass());
405 assert(field_k == field_vklass, "Field descriptor and argument must match");
406 if (flatten) {
407 // copy value
408 field_vklass->value_store(field_vklass->data_for_oop(value_h()),
409 ((char*)(oopDesc*)obj_h()) + klass->field_offset(index), true, false);
410 } else {
411 if (Universe::heap()->is_in_reserved(value_h())) {
412 obj_h()->obj_field_put(klass->field_offset(index), value_h());
413 } else {
414 // allocate heap instance
415 instanceOop val = field_vklass->allocate_instance(CHECK);
416 instanceHandle res_h(THREAD, val);
417 // copy value
418 field_vklass->value_store(field_vklass->data_for_oop(value_h()),
419 field_vklass->data_for_oop(res_h()), true, false);
420
421
422 obj_h()->obj_field_put(klass->field_offset(index), res_h());
423 }
424 }
425 IRT_END
426
427 IRT_ENTRY(void, InterpreterRuntime::qputstatic(JavaThread* thread, oopDesc* value, int offset, oopDesc* mirror))
428 instanceHandle value_h(THREAD, (instanceOop)value);
429 assert(value_h()->is_value(), "qputstatic only deals with value arguments");
430 if (Universe::heap()->is_in_reserved(value_h())) {
431 mirror->obj_field_put(offset, value_h());
432 } else {
433 // The argument is a buffered value, a copy must be created in the Java heap
434 // because a static field cannot point to a thread-local buffered value
435 ValueKlass* field_vklass = ValueKlass::cast(value_h()->klass());
436 Handle mirror_h(THREAD, mirror);
437 // allocate heap instance
438 instanceOop res = field_vklass->allocate_instance(CHECK);
439 assert(Universe::heap()->is_in_reserved(res), "Must be in the Java heap");
440 instanceHandle res_h(THREAD, res);
441 // copy value
442 field_vklass->value_store(field_vklass->data_for_oop(value_h()),
443 field_vklass->data_for_oop(res), true, false);
444 // writing static field
445 mirror_h->obj_field_put(offset, res_h());
446 assert(mirror_h->obj_field(offset) != NULL,"Sanity check");
447 }
448 IRT_END
449
450 IRT_ENTRY(void, InterpreterRuntime::newarray(JavaThread* thread, BasicType type, jint size))
451 oop obj = oopFactory::new_typeArray(type, size, CHECK);
452 thread->set_vm_result(obj);
453 IRT_END
454
455
456 IRT_ENTRY(void, InterpreterRuntime::anewarray(JavaThread* thread, ConstantPool* pool, int index, jint size))
457 Klass* klass = pool->klass_at(index, CHECK);
458 if (klass->is_value()) { // Logically creates elements, ensure klass init
459 klass->initialize(CHECK);
460 }
461 arrayOop obj = oopFactory::new_array(klass, size, CHECK);
462 thread->set_vm_result(obj);
463 IRT_END
464
465 IRT_ENTRY(void, InterpreterRuntime::value_array_load(JavaThread* thread, arrayOopDesc* array, int index))
466 Klass* klass = array->klass();
467 assert(klass->is_valueArray_klass() || klass->is_objArray_klass(), "expected value or object array oop");
468
469 if (klass->is_objArray_klass()) {
470 thread->set_vm_result(((objArrayOop) array)->obj_at(index));
471 }
472 else {
473 ValueArrayKlass* vaklass = ValueArrayKlass::cast(klass);
474 ValueKlass* vklass = vaklass->element_klass();
475 arrayHandle ah(THREAD, array);
476 bool in_heap;
477 instanceOop value_holder = vklass->allocate_buffered_or_heap_instance(&in_heap, CHECK);
478 void* src = ((valueArrayOop)ah())->value_at_addr(index, vaklass->layout_helper());
479 vklass->value_store(src, vklass->data_for_oop(value_holder),
480 vaklass->element_byte_size(), in_heap, false);
481 thread->set_vm_result(value_holder);
482 }
483 IRT_END
484
485 IRT_ENTRY(void, InterpreterRuntime::value_array_store(JavaThread* thread, arrayOopDesc* array, int index, void* val))
486 Klass* klass = array->klass();
487 assert(klass->is_valueArray_klass() || klass->is_objArray_klass(), "expected value or object array oop");
488
489 if (ArrayKlass::cast(klass)->element_klass() != ((oop)val)->klass()) {
490 THROW(vmSymbols::java_lang_ArrayStoreException());
491 }
492 if (klass->is_objArray_klass()) {
493 if(!Universe::heap()->is_in_reserved(val)) {
494 // A Java heap allocated copy must be made because an array cannot
495 // reference a thread-local buffered value
496 Handle val_h(THREAD, (oop)val);
497 ObjArrayKlass* aklass = ObjArrayKlass::cast(klass);
498 Klass* eklass = aklass->element_klass();
499 assert(eklass->is_value(), "Sanity check");
500 assert(eklass == ((oop)val)->klass(), "Sanity check");
501 ValueKlass* vklass = ValueKlass::cast(eklass);
502 // allocate heap instance
503 instanceOop res = vklass->allocate_instance(CHECK);
504 Handle res_h(THREAD, res);
505 // copy value
506 vklass->value_store(((char*)(oopDesc*)val_h()) + vklass->first_field_offset(),
507 ((char*)(oopDesc*)res_h()) + vklass->first_field_offset(),true, false);
508 val = res_h();
509 }
510 ((objArrayOop) array)->obj_at_put(index, (oop)val);
511 } else {
512 valueArrayOop varray = (valueArrayOop)array;
513 ValueArrayKlass* vaklass = ValueArrayKlass::cast(klass);
514 ValueKlass* vklass = vaklass->element_klass();
515 const int lh = vaklass->layout_helper();
516 vklass->value_store(vklass->data_for_oop((oop)val), varray->value_at_addr(index, lh),
517 vaklass->element_byte_size(), true, false);
518 }
519 IRT_END
520
521 IRT_ENTRY(void, InterpreterRuntime::multianewarray(JavaThread* thread, jint* first_size_address))
522 // We may want to pass in more arguments - could make this slightly faster
523 ConstantPool* constants = method(thread)->constants();
524 int i = get_index_u2(thread, Bytecodes::_multianewarray);
525 Klass* klass = constants->klass_at(i, CHECK);
526 int nof_dims = number_of_dimensions(thread);
527 assert(klass->is_klass(), "not a class");
528 assert(nof_dims >= 1, "multianewarray rank must be nonzero");
529
530 if (klass->is_value()) { // Logically creates elements, ensure klass init
531 klass->initialize(CHECK);
532 }
533
534 // We must create an array of jints to pass to multi_allocate.
535 ResourceMark rm(thread);
536 const int small_dims = 10;
537 jint dim_array[small_dims];
538 jint *dims = &dim_array[0];
539 if (nof_dims > small_dims) {
540 dims = (jint*) NEW_RESOURCE_ARRAY(jint, nof_dims);
541 }
542 for (int index = 0; index < nof_dims; index++) {
543 // offset from first_size_address is addressed as local[index]
544 int n = Interpreter::local_offset_in_bytes(index)/jintSize;
545 dims[index] = first_size_address[n];
546 }
547 oop obj = ArrayKlass::cast(klass)->multi_allocate(nof_dims, dims, CHECK);
548 thread->set_vm_result(obj);
549 IRT_END
550
551 IRT_ENTRY(void, InterpreterRuntime::recycle_vtbuffer(JavaThread* thread))
552 VTBuffer::recycle_vtbuffer(thread, last_frame(thread));
553 IRT_END
554
555 IRT_ENTRY(void, InterpreterRuntime::recycle_buffered_values(JavaThread* thread))
556 frame f = thread->last_frame();
557 assert(f.is_interpreted_frame(), "recycling can only be triggered from interpreted frames");
558 VTBuffer::recycle_vt_in_frame(thread, &f);
559 IRT_END
560
561 IRT_ENTRY(void, InterpreterRuntime::fix_frame_vt_alloc_ptr(JavaThread* thread))
562 frame f = thread->last_frame();
563 VTBuffer::fix_frame_vt_alloc_ptr(f, VTBufferChunk::chunk(thread->vt_alloc_ptr()));
564 IRT_END
565
566 IRT_ENTRY(void, InterpreterRuntime::return_value(JavaThread* thread, oopDesc* obj))
567 if (Universe::heap()->is_in_reserved(obj)) {
568 thread->set_vm_result(obj);
569 return;
570 }
571 assert(obj->klass()->is_value(), "Sanity check");
572 ValueKlass* vk = ValueKlass::cast(obj->klass());
573 RegisterMap reg_map(thread, false);
574 frame current_frame = last_frame(thread);
575 frame caller_frame = current_frame.sender(®_map);
576 if (!caller_frame.is_interpreted_frame()) {
577 // caller is not an interpreted frame, creating a new value in Java heap
578 Handle obj_h(THREAD, obj);
579 instanceOop res = vk->allocate_instance(CHECK);
580 Handle res_h(THREAD, res);
581 // copy value
582 vk->value_store(vk->data_for_oop(obj_h()),
583 vk->data_for_oop(res_h()), true, false);
584 thread->set_vm_result(res_h());
585 return;
586 } else {
587 oop dest = VTBuffer::relocate_return_value(thread, current_frame, obj);
588 thread->set_vm_result(dest);
589 }
590 IRT_END
591
592 IRT_ENTRY(void, InterpreterRuntime::check_areturn(JavaThread* thread, oopDesc* obj))
593 if (obj != NULL) {
594 Klass* k = obj->klass();
595 if (k->is_value()) {
596 ResourceMark rm(thread);
597 tty->print_cr("areturn used on a value from %s", k->name()->as_C_string());
598 }
599 assert(!k->is_value(), "areturn should never be used on values");
600 }
601 thread->set_vm_result(obj);
602 IRT_END
603
604 IRT_ENTRY(void, InterpreterRuntime::register_finalizer(JavaThread* thread, oopDesc* obj))
605 assert(oopDesc::is_oop(obj), "must be a valid oop");
606 assert(obj->klass()->has_finalizer(), "shouldn't be here otherwise");
607 InstanceKlass::register_finalizer(instanceOop(obj), CHECK);
608 IRT_END
609
|
55 #include "runtime/biasedLocking.hpp"
56 #include "runtime/compilationPolicy.hpp"
57 #include "runtime/deoptimization.hpp"
58 #include "runtime/fieldDescriptor.hpp"
59 #include "runtime/handles.inline.hpp"
60 #include "runtime/icache.hpp"
61 #include "runtime/interfaceSupport.hpp"
62 #include "runtime/java.hpp"
63 #include "runtime/jfieldIDWorkaround.hpp"
64 #include "runtime/osThread.hpp"
65 #include "runtime/sharedRuntime.hpp"
66 #include "runtime/stubRoutines.hpp"
67 #include "runtime/synchronizer.hpp"
68 #include "runtime/threadCritical.hpp"
69 #include "utilities/align.hpp"
70 #include "utilities/events.hpp"
71 #include "utilities/globalDefinitions.hpp"
72 #ifdef COMPILER2
73 #include "opto/runtime.hpp"
74 #endif
75 #if INCLUDE_ALL_GCS
76 #include "gc/g1/g1SATBCardTableModRefBS.hpp"
77 #endif // INCLUDE_ALL_GCS
78
79 class UnlockFlagSaver {
80 private:
81 JavaThread* _thread;
82 bool _do_not_unlock;
83 public:
84 UnlockFlagSaver(JavaThread* t) {
85 _thread = t;
86 _do_not_unlock = t->do_not_unlock_if_synchronized();
87 t->set_do_not_unlock_if_synchronized(false);
88 }
89 ~UnlockFlagSaver() {
90 _thread->set_do_not_unlock_if_synchronized(_do_not_unlock);
91 }
92 };
93
94 //------------------------------------------------------------------------------------------------------------------------
95 // State accessors
96
97 void InterpreterRuntime::set_bcp_and_mdp(address bcp, JavaThread *thread) {
250 frame f = last_frame(thread);
251 jint tos_idx = f.interpreter_frame_expression_stack_size() - 1;
252 int vt_offset = type2size[field_type];
253 oop old_value = *(oop*)f.interpreter_frame_expression_stack_at(tos_idx - vt_offset);
254 assert(old_value != NULL && oopDesc::is_oop(old_value) && old_value->is_value(),"Verifying receiver");
255 Handle old_value_h(THREAD, old_value);
256
257 // Creating new value by copying the one passed in argument
258 bool in_heap;
259 instanceOop new_value = vklass->allocate_buffered_or_heap_instance(&in_heap,
260 CHECK_((type2size[field_type]) * AbstractInterpreter::stackElementSize));
261 Handle new_value_h = Handle(THREAD, new_value);
262 int first_offset = vklass->first_field_offset();
263 vklass->value_store(vklass->data_for_oop(old_value_h()),
264 vklass->data_for_oop(new_value_h()), in_heap, false);
265
266 // Updating the field specified in arguments
267 if (field_type == T_OBJECT || field_type == T_ARRAY) {
268 oop aoop = *(oop*)f.interpreter_frame_expression_stack_at(tos_idx);
269 assert(aoop == NULL || (oopDesc::is_oop(aoop) && (!aoop->is_value())),"argument must be a reference type");
270 if (in_heap) {
271 new_value_h()->obj_field_put(field_offset, aoop);
272 } else {
273 if (UseG1GC) {
274 if (aoop != NULL) {
275 G1SATBCardTableModRefBS::enqueue(aoop);
276 }
277 oop old = new_value_h()->obj_field_acquire(field_offset);
278 if (old != NULL) {
279 G1SATBCardTableModRefBS::enqueue(old);
280 }
281 }
282 new_value_h()->obj_field_put_raw(field_offset, aoop);
283 }
284 } else if (field_type == T_VALUETYPE) {
285 if (cp_entry->is_flatten()) {
286 Klass* field_k = vklass->get_value_field_klass(field_index);
287 ValueKlass* field_vk = ValueKlass::cast(field_k);
288 oop vt_oop = *(oop*)f.interpreter_frame_expression_stack_at(tos_idx);
289 assert(vt_oop != NULL && oopDesc::is_oop(vt_oop) && vt_oop->is_value(),"argument must be a value type");
290 assert(field_vk == vt_oop->klass(), "Must match");
291 field_vk->value_store(field_vk->data_for_oop(vt_oop),
292 ((char*)(oopDesc*)new_value_h()) + field_offset, in_heap, false);
293 } else {
294 oop voop = *(oop*)f.interpreter_frame_expression_stack_at(tos_idx);
295 assert(voop != NULL || (oopDesc::is_oop(voop) && (voop->is_value())),"argument must be a value type");
296 if (VTBuffer::is_in_vt_buffer(voop)) {
297 // new value field is currently allocated in a TLVB, a heap allocated
298 // copy must be created because a field must never point to a TLVB allocated value
299 Handle voop_h = Handle(THREAD, voop);
300 ValueKlass* field_vk = ValueKlass::cast(voop->klass());
301 assert(field_vk == vklass->get_value_field_klass(field_index), "Sanity check");
302 instanceOop field_copy = field_vk->allocate_instance(CHECK_((type2size[field_type]) * AbstractInterpreter::stackElementSize));
303 Handle field_copy_h = Handle(THREAD, field_copy);
304 field_vk->value_store(field_vk->data_for_oop(voop_h()), field_vk->data_for_oop(field_copy_h()), true, false);
305 if (in_heap) {
306 new_value_h()->obj_field_put(field_offset, field_copy_h());
307 } else {
308 new_value_h()->obj_field_put_raw(field_offset, field_copy_h());
309 if (UseG1GC) {
310 G1SATBCardTableModRefBS::enqueue(field_copy_h());
311 }
312 }
313 } else {
314 if (in_heap) {
315 new_value_h()->obj_field_put(field_offset, voop);
316 } else {
317 new_value_h()->obj_field_put_raw(field_offset, voop);
318 if (UseG1GC) {
319 G1SATBCardTableModRefBS::enqueue(voop);
320 }
321 }
322 }
323 }
324 } else {
325 intptr_t* addr = f.interpreter_frame_expression_stack_at(tos_idx);
326 copy_primitive_argument(addr, new_value_h, field_offset, field_type);
327 }
328
329 // returning result
330 thread->set_vm_result(new_value_h());
331 return (type2size[field_type] + type2size[T_VALUETYPE]) * AbstractInterpreter::stackElementSize;
332 IRT_END
333
334 IRT_ENTRY(void, InterpreterRuntime::vbox(JavaThread* thread, ConstantPool* pool, int index, oopDesc* value))
335 assert(EnableMVT, "vbox is supported only when the MVT programming model is enabled");
336 if (value == NULL) {
337 THROW(vmSymbols::java_lang_NullPointerException());
338 }
339
340 // Since the verifier is probably disabled, a few extra type check
341 Klass* target_klass = pool->klass_at(index, CHECK);
342 if (target_klass->is_value()) {
383 InstanceKlass* klass = InstanceKlass::cast(field_holder);
384
385 Klass* field_k = klass->get_value_field_klass(index);
386 ValueKlass* field_vklass = ValueKlass::cast(field_k);
387 field_vklass->initialize(THREAD);
388
389 instanceOop res;
390 bool in_heap;
391 if (klass->is_field_flatten(index)) {
392 // allocate instance
393 res = field_vklass->allocate_buffered_or_heap_instance(&in_heap, CHECK);
394 instanceHandle res_h(THREAD, res);
395 // copy value
396 field_vklass->value_store(((char*)(oopDesc*)value_h()) + klass->field_offset(index),
397 field_vklass->data_for_oop(res), in_heap, false);
398 thread->set_vm_result(res_h());
399 } else {
400 oop res = value_h()->obj_field_acquire(klass->field_offset(index));
401 if (res == NULL) {
402 res = field_vklass->allocate_buffered_or_heap_instance(&in_heap, CHECK);
403 } else {
404 assert(res->klass() == field_k, "Sanity check");
405 assert(!VTBuffer::is_in_vt_buffer(res), "Sanity check");
406 }
407 thread->set_vm_result(res);
408 }
409 assert(thread->vm_result()->klass() == field_vklass, "sanity check");
410 IRT_END
411
412 IRT_ENTRY(void, InterpreterRuntime::initialize_static_value_field(JavaThread* thread, oopDesc* mirror, int index))
413 instanceHandle mirror_h(THREAD, (instanceOop)mirror);
414 InstanceKlass* klass = InstanceKlass::cast(java_lang_Class::as_Klass(mirror));
415 int offset = klass->field_offset(index);
416 assert(mirror->obj_field(offset) == NULL,"Field must not be initialized twice");
417
418 Klass* field_k = klass->get_value_field_klass_or_null(index);
419 if (field_k == NULL) {
420 field_k = SystemDictionary::resolve_or_fail(klass->field_signature(index),
421 Handle(THREAD, klass->class_loader()),
422 Handle(THREAD, klass->protection_domain()), true, CHECK);
423 assert(field_k != NULL, "Sanity check");
424 assert(field_k->access_flags().is_value_type(), "Value type expected");
425 klass->set_value_field_klass(index, field_k);
426 }
427 ValueKlass* field_vklass = ValueKlass::cast(field_k);
428 // allocate instance, because it is going to be assigned to a static field
429 // it must not be a buffered value
431 instanceHandle res_h(THREAD, res);
432 mirror_h()->obj_field_put(offset, res_h());
433 thread->set_vm_result(res_h());
434 IRT_END
435
436 IRT_ENTRY(void, InterpreterRuntime::qputfield(JavaThread* thread, oopDesc* obj, oopDesc* value, ConstantPoolCache* cp_cache))
437 Handle value_h(THREAD, value);
438 Handle obj_h(THREAD, obj);
439 assert(!obj_h()->klass()->is_value(), "obj must be an object");
440 assert(value_h()->klass()->is_value(), "value must be an value type");
441
442 int idx = ConstantPool::decode_cpcache_index(get_index_u2_cpcache(thread, Bytecodes::_putfield));
443 ConstantPoolCacheEntry* cp_entry = cp_cache->entry_at(idx);
444
445 int index = cp_entry->field_index();
446 bool flatten = cp_entry->is_flatten();
447
448 InstanceKlass* klass = InstanceKlass::cast(cp_entry->f1_as_klass());
449 Klass* field_k = klass->get_value_field_klass(index);
450 ValueKlass* field_vklass = ValueKlass::cast(value->klass());
451 assert(value_h()->klass() == field_k, "Sanity check");
452 assert(field_k == field_vklass, "Field descriptor and argument must match");
453 if (flatten) {
454 // copy value
455 field_vklass->value_store(field_vklass->data_for_oop(value_h()),
456 ((char*)(oopDesc*)obj_h()) + klass->field_offset(index), true, false);
457 } else {
458 if (!VTBuffer::is_in_vt_buffer(value_h())) {
459 obj_h()->obj_field_put(klass->field_offset(index), value_h());
460 } else {
461 // allocate heap instance
462 instanceOop val = field_vklass->allocate_instance(CHECK);
463 instanceHandle res_h(THREAD, val);
464 // copy value
465 field_vklass->value_store(field_vklass->data_for_oop(value_h()),
466 field_vklass->data_for_oop(res_h()), true, false);
467
468
469 obj_h()->obj_field_put(klass->field_offset(index), res_h());
470 }
471 }
472 IRT_END
473
474 IRT_ENTRY(void, InterpreterRuntime::qputstatic(JavaThread* thread, oopDesc* value, int offset, oopDesc* mirror))
475 instanceHandle value_h(THREAD, (instanceOop)value);
476 assert(value_h()->is_value(), "qputstatic only deals with value arguments");
477 if (!VTBuffer::is_in_vt_buffer(value_h())) {
478 mirror->obj_field_put(offset, value_h());
479 } else {
480 // The argument is a buffered value, a copy must be created in the Java heap
481 // because a static field cannot point to a thread-local buffered value
482 ValueKlass* field_vklass = ValueKlass::cast(value_h()->klass());
483 Handle mirror_h(THREAD, mirror);
484 // allocate heap instance
485 instanceOop res = field_vklass->allocate_instance(CHECK);
486 assert(Universe::heap()->is_in_reserved(res), "Must be in the Java heap");
487 instanceHandle res_h(THREAD, res);
488 // copy value
489 field_vklass->value_store(field_vklass->data_for_oop(value_h()),
490 field_vklass->data_for_oop(res), true, false);
491 // writing static field
492 mirror_h->obj_field_put(offset, res_h());
493 assert(mirror_h->obj_field(offset) != NULL,"Sanity check");
494 }
495 IRT_END
496
497 IRT_ENTRY(void, InterpreterRuntime::newarray(JavaThread* thread, BasicType type, jint size))
498 oop obj = oopFactory::new_typeArray(type, size, CHECK);
499 thread->set_vm_result(obj);
500 IRT_END
501
502
503 IRT_ENTRY(void, InterpreterRuntime::anewarray(JavaThread* thread, ConstantPool* pool, int index, jint size))
504 Klass* klass = pool->klass_at(index, CHECK);
505 if (klass->is_value()) { // Logically creates elements, ensure klass init
506 klass->initialize(CHECK);
507 }
508 arrayOop obj = oopFactory::new_array(klass, size, CHECK);
509 thread->set_vm_result(obj);
510 IRT_END
511
512 IRT_ENTRY(void, InterpreterRuntime::value_array_load(JavaThread* thread, arrayOopDesc* array, int index))
513 Klass* klass = array->klass();
514 assert(klass->is_valueArray_klass() || klass->is_objArray_klass(), "expected value or object array oop");
515
516 if (klass->is_objArray_klass()) {
517 thread->set_vm_result(((objArrayOop) array)->obj_at(index));
518 } else {
519 ValueArrayKlass* vaklass = ValueArrayKlass::cast(klass);
520 ValueKlass* vklass = vaklass->element_klass();
521 arrayHandle ah(THREAD, array);
522 bool in_heap;
523 instanceOop value_holder = vklass->allocate_buffered_or_heap_instance(&in_heap, CHECK);
524 void* src = ((valueArrayOop)ah())->value_at_addr(index, vaklass->layout_helper());
525 vklass->value_store(src, vklass->data_for_oop(value_holder),
526 vaklass->element_byte_size(), in_heap, false);
527 thread->set_vm_result(value_holder);
528 }
529 IRT_END
530
531 IRT_ENTRY(void, InterpreterRuntime::value_array_store(JavaThread* thread, arrayOopDesc* array, int index, void* val))
532 Klass* klass = array->klass();
533 assert(klass->is_valueArray_klass() || klass->is_objArray_klass(), "expected value or object array oop");
534 Handle array_h(THREAD, array);
535
536 if (ArrayKlass::cast(klass)->element_klass() != ((oop)val)->klass()) {
537 THROW(vmSymbols::java_lang_ArrayStoreException());
538 }
539 if (klass->is_objArray_klass()) {
540 if(VTBuffer::is_in_vt_buffer(val)) {
541 // A Java heap allocated copy must be made because an array cannot
542 // reference a thread-local buffered value
543 Handle val_h(THREAD, (oop)val);
544 ObjArrayKlass* aklass = ObjArrayKlass::cast(klass);
545 Klass* eklass = aklass->element_klass();
546 assert(eklass->is_value(), "Sanity check");
547 assert(eklass == ((oop)val)->klass(), "Sanity check");
548 ValueKlass* vklass = ValueKlass::cast(eklass);
549 // allocate heap instance
550 instanceOop res = vklass->allocate_instance(CHECK);
551 Handle res_h(THREAD, res);
552 // copy value
553 vklass->value_store(((char*)(oopDesc*)val_h()) + vklass->first_field_offset(),
554 ((char*)(oopDesc*)res_h()) + vklass->first_field_offset(),true, false);
555 val = res_h();
556 }
557 ((objArrayOop) array_h())->obj_at_put(index, (oop)val);
558 } else {
559 valueArrayOop varray = (valueArrayOop)array;
560 ValueArrayKlass* vaklass = ValueArrayKlass::cast(klass);
561 ValueKlass* vklass = vaklass->element_klass();
562 const int lh = vaklass->layout_helper();
563 vklass->value_store(vklass->data_for_oop((oop)val), varray->value_at_addr(index, lh),
564 vaklass->element_byte_size(), true, false);
565 }
566 IRT_END
567
568 IRT_ENTRY(void, InterpreterRuntime::multianewarray(JavaThread* thread, jint* first_size_address))
569 // We may want to pass in more arguments - could make this slightly faster
570 ConstantPool* constants = method(thread)->constants();
571 int i = get_index_u2(thread, Bytecodes::_multianewarray);
572 Klass* klass = constants->klass_at(i, CHECK);
573 int nof_dims = number_of_dimensions(thread);
574 assert(klass->is_klass(), "not a class");
575 assert(nof_dims >= 1, "multianewarray rank must be nonzero");
576
577 if (klass->is_value()) { // Logically creates elements, ensure klass init
578 klass->initialize(CHECK);
579 }
580
581 // We must create an array of jints to pass to multi_allocate.
582 ResourceMark rm(thread);
583 const int small_dims = 10;
584 jint dim_array[small_dims];
585 jint *dims = &dim_array[0];
586 if (nof_dims > small_dims) {
587 dims = (jint*) NEW_RESOURCE_ARRAY(jint, nof_dims);
588 }
589 for (int index = 0; index < nof_dims; index++) {
590 // offset from first_size_address is addressed as local[index]
591 int n = Interpreter::local_offset_in_bytes(index)/jintSize;
592 dims[index] = first_size_address[n];
593 }
594 oop obj = ArrayKlass::cast(klass)->multi_allocate(nof_dims, dims, CHECK);
595 thread->set_vm_result(obj);
596 IRT_END
597
598 IRT_LEAF(void, InterpreterRuntime::recycle_vtbuffer(void* alloc_ptr))
599 JavaThread* thread = (JavaThread*)Thread::current();
600 VTBuffer::recycle_vtbuffer(thread, alloc_ptr);
601 IRT_END
602
603 IRT_ENTRY(void, InterpreterRuntime::recycle_buffered_values(JavaThread* thread))
604 frame f = thread->last_frame();
605 assert(f.is_interpreted_frame(), "recycling can only be triggered from interpreted frames");
606 VTBuffer::recycle_vt_in_frame(thread, &f);
607 IRT_END
608
609 IRT_ENTRY(void, InterpreterRuntime::fix_frame_vt_alloc_ptr(JavaThread* thread))
610 frame f = thread->last_frame();
611 VTBuffer::fix_frame_vt_alloc_ptr(f, VTBufferChunk::chunk(thread->vt_alloc_ptr()));
612 IRT_END
613
614 IRT_ENTRY(void, InterpreterRuntime::return_value(JavaThread* thread, oopDesc* obj))
615 if (!VTBuffer::is_in_vt_buffer(obj)) {
616 thread->set_vm_result(obj);
617 return;
618 }
619 assert(obj->klass()->is_value(), "Sanity check");
620 ValueKlass* vk = ValueKlass::cast(obj->klass());
621 RegisterMap reg_map(thread, false);
622 frame current_frame = last_frame(thread);
623 frame caller_frame = current_frame.sender(®_map);
624 if (!caller_frame.is_interpreted_frame()) {
625 // caller is not an interpreted frame, creating a new value in Java heap
626 Handle obj_h(THREAD, obj);
627 instanceOop res = vk->allocate_instance(CHECK);
628 Handle res_h(THREAD, res);
629 // copy value
630 vk->value_store(vk->data_for_oop(obj_h()),
631 vk->data_for_oop(res_h()), true, false);
632 thread->set_vm_result(res_h());
633 return;
634 } else {
635 // A buffered value is being returned to an interpreted frame,
636 // but the work has to be delayed to remove_activation() because
637 // the frame cannot be modified now (GC can run at the safepoint
638 // when exiting runtime, and frame layout must be kept consistent
639 // with the OopMap).
640 thread->set_return_buffered_value(obj);
641 thread->set_vm_result(obj);
642 }
643 IRT_END
644
645 IRT_LEAF(void, InterpreterRuntime::return_value_step2(oopDesc* obj, void* alloc_ptr))
646
647 JavaThread* thread = (JavaThread*)Thread::current();
648 assert(obj == thread->return_buffered_value(), "Consistency check");
649 assert(!Universe::heap()->is_in_reserved(obj), "Should only apply to buffered values");
650
651 oop dest = VTBuffer::relocate_return_value(thread, alloc_ptr, obj);
652 thread->set_return_buffered_value(NULL);
653 thread->set_vm_result(dest);
654 IRT_END
655
656 IRT_ENTRY(void, InterpreterRuntime::check_areturn(JavaThread* thread, oopDesc* obj))
657 if (obj != NULL) {
658 Klass* k = obj->klass();
659 if (k->is_value()) {
660 ResourceMark rm(thread);
661 tty->print_cr("areturn used on a value from %s", k->name()->as_C_string());
662 }
663 assert(!k->is_value(), "areturn should never be used on values");
664 }
665 thread->set_vm_result(obj);
666 IRT_END
667
668 IRT_ENTRY(void, InterpreterRuntime::register_finalizer(JavaThread* thread, oopDesc* obj))
669 assert(oopDesc::is_oop(obj), "must be a valid oop");
670 assert(obj->klass()->has_finalizer(), "shouldn't be here otherwise");
671 InstanceKlass::register_finalizer(instanceOop(obj), CHECK);
672 IRT_END
673
|