31 #include "compiler/compileBroker.hpp"
32 #include "compiler/disassembler.hpp"
33 #include "gc/shared/barrierSetNMethod.hpp"
34 #include "gc/shared/collectedHeap.hpp"
35 #include "interpreter/interpreter.hpp"
36 #include "interpreter/interpreterRuntime.hpp"
37 #include "interpreter/linkResolver.hpp"
38 #include "interpreter/templateTable.hpp"
39 #include "logging/log.hpp"
40 #include "memory/oopFactory.hpp"
41 #include "memory/resourceArea.hpp"
42 #include "memory/universe.hpp"
43 #include "oops/constantPool.hpp"
44 #include "oops/cpCache.inline.hpp"
45 #include "oops/instanceKlass.hpp"
46 #include "oops/methodData.hpp"
47 #include "oops/objArrayKlass.hpp"
48 #include "oops/objArrayOop.inline.hpp"
49 #include "oops/oop.inline.hpp"
50 #include "oops/symbol.hpp"
51 #include "oops/valueKlass.hpp"
52 #include "oops/valueArrayKlass.hpp"
53 #include "oops/valueArrayOop.hpp"
54 #include "oops/valueArrayOop.inline.hpp"
55 #include "prims/jvmtiExport.hpp"
56 #include "prims/nativeLookup.hpp"
57 #include "runtime/atomic.hpp"
58 #include "runtime/biasedLocking.hpp"
59 #include "runtime/compilationPolicy.hpp"
60 #include "runtime/deoptimization.hpp"
61 #include "runtime/fieldDescriptor.inline.hpp"
62 #include "runtime/frame.inline.hpp"
63 #include "runtime/handles.inline.hpp"
64 #include "runtime/icache.hpp"
65 #include "runtime/interfaceSupport.inline.hpp"
66 #include "runtime/java.hpp"
67 #include "runtime/javaCalls.hpp"
68 #include "runtime/jfieldIDWorkaround.hpp"
69 #include "runtime/osThread.hpp"
70 #include "runtime/sharedRuntime.hpp"
71 #include "runtime/stubRoutines.hpp"
72 #include "runtime/synchronizer.hpp"
73 #include "runtime/threadCritical.hpp"
74 #include "utilities/align.hpp"
320 int offset = cp_entry->f2_as_index();
321 int field_index = cp_entry->field_index();
322 int field_offset = cp_entry->f2_as_offset();
323 Symbol* field_signature = vklass->field_signature(field_index);
324 ResourceMark rm(THREAD);
325 const char* signature = (const char *) field_signature->as_utf8();
326 BasicType field_type = char2type(signature[0]);
327
328 // Getting old value
329 frame& f = last_frame.get_frame();
330 jint tos_idx = f.interpreter_frame_expression_stack_size() - 1;
331 int vt_offset = type2size[field_type];
332 oop old_value = *(oop*)f.interpreter_frame_expression_stack_at(tos_idx - vt_offset);
333 assert(old_value != NULL && oopDesc::is_oop(old_value) && old_value->is_value(),"Verifying receiver");
334 Handle old_value_h(THREAD, old_value);
335
336 // Creating new value by copying the one passed in argument
337 instanceOop new_value = vklass->allocate_instance(
338 CHECK_((type2size[field_type]) * AbstractInterpreter::stackElementSize));
339 Handle new_value_h = Handle(THREAD, new_value);
340 int first_offset = vklass->first_field_offset();
341 vklass->value_store(vklass->data_for_oop(old_value_h()),
342 vklass->data_for_oop(new_value_h()), true, false);
343
344 // Updating the field specified in arguments
345 if (field_type == T_ARRAY || field_type == T_OBJECT) {
346 oop aoop = *(oop*)f.interpreter_frame_expression_stack_at(tos_idx);
347 assert(aoop == NULL || oopDesc::is_oop(aoop),"argument must be a reference type");
348 new_value_h()->obj_field_put(field_offset, aoop);
349 } else if (field_type == T_VALUETYPE) {
350 if (cp_entry->is_flattened()) {
351 oop vt_oop = *(oop*)f.interpreter_frame_expression_stack_at(tos_idx);
352 if (vt_oop == NULL) {
353 THROW_(vmSymbols::java_lang_NullPointerException(),
354 (type2size[field_type] * AbstractInterpreter::stackElementSize));
355 }
356 assert(vt_oop != NULL && oopDesc::is_oop(vt_oop) && vt_oop->is_value(),"argument must be a value type");
357 Klass* field_k = vklass->get_value_field_klass(field_index);
358 ValueKlass* field_vk = ValueKlass::cast(field_k);
359 assert(field_vk == vt_oop->klass(), "Must match");
360 field_vk->value_store(field_vk->data_for_oop(vt_oop),
361 ((char*)(oopDesc*)new_value_h()) + field_offset, false, false);
362 } else { // not flattened
363 oop voop = *(oop*)f.interpreter_frame_expression_stack_at(tos_idx);
364 if (voop == NULL && cp_entry->is_flattenable()) {
365 THROW_(vmSymbols::java_lang_NullPointerException(),
366 (type2size[field_type] * AbstractInterpreter::stackElementSize));
367 }
368 assert(voop == NULL || oopDesc::is_oop(voop),"checking argument");
369 new_value_h()->obj_field_put(field_offset, voop);
370 }
371 } else { // not T_OBJECT nor T_ARRAY nor T_VALUETYPE
372 intptr_t* addr = f.interpreter_frame_expression_stack_at(tos_idx);
373 copy_primitive_argument(addr, new_value_h, field_offset, field_type);
374 }
375
376 // returning result
377 thread->set_vm_result(new_value_h());
378 return (type2size[field_type] + type2size[T_OBJECT]) * AbstractInterpreter::stackElementSize;
379 JRT_END
380
381 JRT_ENTRY(void, InterpreterRuntime::uninitialized_static_value_field(JavaThread* thread, oopDesc* mirror, int index))
428 JRT_END
429
430 JRT_ENTRY(void, InterpreterRuntime::uninitialized_instance_value_field(JavaThread* thread, oopDesc* obj, int index))
431 instanceHandle obj_h(THREAD, (instanceOop)obj);
432 InstanceKlass* klass = InstanceKlass::cast(obj_h()->klass());
433 Klass* field_k = klass->get_value_field_klass_or_null(index);
434 assert(field_k != NULL, "Must have been initialized");
435 ValueKlass* field_vklass = ValueKlass::cast(field_k);
436 assert(field_vklass->is_initialized(), "Must have been initialized at this point");
437 instanceOop res = (instanceOop)field_vklass->default_value();
438 thread->set_vm_result(res);
439 JRT_END
440
441 JRT_ENTRY(void, InterpreterRuntime::write_flattened_value(JavaThread* thread, oopDesc* value, int offset, oopDesc* rcv))
442 assert(oopDesc::is_oop(value), "Sanity check");
443 assert(oopDesc::is_oop(rcv), "Sanity check");
444 assert(value->is_value(), "Sanity check");
445
446 ValueKlass* vklass = ValueKlass::cast(value->klass());
447 if (!vklass->is_empty_value()) {
448 vklass->value_store(vklass->data_for_oop(value), ((char*)(oopDesc*)rcv) + offset, true, true);
449 }
450 JRT_END
451
452 JRT_ENTRY(void, InterpreterRuntime::read_flattened_field(JavaThread* thread, oopDesc* obj, int index, Klass* field_holder))
453 Handle obj_h(THREAD, obj);
454
455 assert(oopDesc::is_oop(obj), "Sanity check");
456
457 assert(field_holder->is_instance_klass(), "Sanity check");
458 InstanceKlass* klass = InstanceKlass::cast(field_holder);
459
460 assert(klass->field_is_flattened(index), "Sanity check");
461
462 ValueKlass* field_vklass = ValueKlass::cast(klass->get_value_field_klass(index));
463 assert(field_vklass->is_initialized(), "Must be initialized at this point");
464
465 instanceOop res = NULL;
466 if (field_vklass->is_empty_value()) {
467 res = (instanceOop)field_vklass->default_value();
468 } else {
469 // allocate instance
470 res = field_vklass->allocate_instance(CHECK);
471 // copy value
472 field_vklass->value_store(((char*)(oopDesc*)obj_h()) + klass->field_offset(index),
473 field_vklass->data_for_oop(res), true, true);
474 }
475 assert(res != NULL, "Must be set in one of two paths above");
476 thread->set_vm_result(res);
477 JRT_END
478
479 JRT_ENTRY(void, InterpreterRuntime::newarray(JavaThread* thread, BasicType type, jint size))
480 oop obj = oopFactory::new_typeArray(type, size, CHECK);
481 thread->set_vm_result(obj);
482 JRT_END
483
484
485 JRT_ENTRY(void, InterpreterRuntime::anewarray(JavaThread* thread, ConstantPool* pool, int index, jint size))
486 Klass* klass = pool->klass_at(index, CHECK);
487 bool is_qtype_desc = pool->tag_at(index).is_Qdescriptor_klass();
488 arrayOop obj;
489 if ((!klass->is_array_klass()) && is_qtype_desc) { // Logically creates elements, ensure klass init
490 klass->initialize(CHECK);
491 obj = oopFactory::new_valueArray(klass, size, CHECK);
492 } else {
493 obj = oopFactory::new_objArray(klass, size, CHECK);
494 }
495 thread->set_vm_result(obj);
496 JRT_END
497
498 JRT_ENTRY(void, InterpreterRuntime::value_array_load(JavaThread* thread, arrayOopDesc* array, int index))
499 Klass* klass = array->klass();
500 assert(klass->is_valueArray_klass(), "expected value array oop");
501
502 ValueArrayKlass* vaklass = ValueArrayKlass::cast(klass);
503 ValueKlass* vklass = vaklass->element_klass();
504 arrayHandle ah(THREAD, array);
505 instanceOop value_holder = NULL;
506 if (vklass->is_empty_value()) {
507 value_holder = (instanceOop)vklass->default_value();
508 } else {
509 value_holder = vklass->allocate_instance(CHECK);
510 void* src = ((valueArrayOop)ah())->value_at_addr(index, vaklass->layout_helper());
511 vklass->value_store(src, vklass->data_for_oop(value_holder),
512 vaklass->element_byte_size(), true, false);
513 }
514 assert(value_holder != NULL, "Must be set in one of two paths above");
515 thread->set_vm_result(value_holder);
516 JRT_END
517
518 JRT_ENTRY(void, InterpreterRuntime::value_array_store(JavaThread* thread, void* val, arrayOopDesc* array, int index))
519 assert(val != NULL, "can't store null into flat array");
520 Klass* klass = array->klass();
521 assert(klass->is_valueArray_klass(), "expected value array");
522 assert(ArrayKlass::cast(klass)->element_klass() == ((oop)val)->klass(), "Store type incorrect");
523
524 valueArrayOop varray = (valueArrayOop)array;
525 ValueArrayKlass* vaklass = ValueArrayKlass::cast(klass);
526 ValueKlass* vklass = vaklass->element_klass();
527 if (!vklass->is_empty_value()) {
528 const int lh = vaklass->layout_helper();
529 vklass->value_store(vklass->data_for_oop((oop)val), varray->value_at_addr(index, lh),
530 vaklass->element_byte_size(), true, false);
531 }
532 JRT_END
533
534 JRT_ENTRY(void, InterpreterRuntime::multianewarray(JavaThread* thread, jint* first_size_address))
535 // We may want to pass in more arguments - could make this slightly faster
536 LastFrameAccessor last_frame(thread);
537 ConstantPool* constants = last_frame.method()->constants();
538 int i = last_frame.get_index_u2(Bytecodes::_multianewarray);
539 Klass* klass = constants->klass_at(i, CHECK);
540 bool is_qtype = klass->name()->is_Q_array_signature();
541 int nof_dims = last_frame.number_of_dimensions();
542 assert(klass->is_klass(), "not a class");
543 assert(nof_dims >= 1, "multianewarray rank must be nonzero");
544
545 if (is_qtype) { // Logically creates elements, ensure klass init
546 klass->initialize(CHECK);
547 }
548
549 // We must create an array of jints to pass to multi_allocate.
550 ResourceMark rm(thread);
551 const int small_dims = 10;
|
31 #include "compiler/compileBroker.hpp"
32 #include "compiler/disassembler.hpp"
33 #include "gc/shared/barrierSetNMethod.hpp"
34 #include "gc/shared/collectedHeap.hpp"
35 #include "interpreter/interpreter.hpp"
36 #include "interpreter/interpreterRuntime.hpp"
37 #include "interpreter/linkResolver.hpp"
38 #include "interpreter/templateTable.hpp"
39 #include "logging/log.hpp"
40 #include "memory/oopFactory.hpp"
41 #include "memory/resourceArea.hpp"
42 #include "memory/universe.hpp"
43 #include "oops/constantPool.hpp"
44 #include "oops/cpCache.inline.hpp"
45 #include "oops/instanceKlass.hpp"
46 #include "oops/methodData.hpp"
47 #include "oops/objArrayKlass.hpp"
48 #include "oops/objArrayOop.inline.hpp"
49 #include "oops/oop.inline.hpp"
50 #include "oops/symbol.hpp"
51 #include "oops/valueArrayKlass.hpp"
52 #include "oops/valueArrayOop.inline.hpp"
53 #include "oops/valueKlass.inline.hpp"
54 #include "prims/jvmtiExport.hpp"
55 #include "prims/nativeLookup.hpp"
56 #include "runtime/atomic.hpp"
57 #include "runtime/biasedLocking.hpp"
58 #include "runtime/compilationPolicy.hpp"
59 #include "runtime/deoptimization.hpp"
60 #include "runtime/fieldDescriptor.inline.hpp"
61 #include "runtime/frame.inline.hpp"
62 #include "runtime/handles.inline.hpp"
63 #include "runtime/icache.hpp"
64 #include "runtime/interfaceSupport.inline.hpp"
65 #include "runtime/java.hpp"
66 #include "runtime/javaCalls.hpp"
67 #include "runtime/jfieldIDWorkaround.hpp"
68 #include "runtime/osThread.hpp"
69 #include "runtime/sharedRuntime.hpp"
70 #include "runtime/stubRoutines.hpp"
71 #include "runtime/synchronizer.hpp"
72 #include "runtime/threadCritical.hpp"
73 #include "utilities/align.hpp"
319 int offset = cp_entry->f2_as_index();
320 int field_index = cp_entry->field_index();
321 int field_offset = cp_entry->f2_as_offset();
322 Symbol* field_signature = vklass->field_signature(field_index);
323 ResourceMark rm(THREAD);
324 const char* signature = (const char *) field_signature->as_utf8();
325 BasicType field_type = char2type(signature[0]);
326
327 // Getting old value
328 frame& f = last_frame.get_frame();
329 jint tos_idx = f.interpreter_frame_expression_stack_size() - 1;
330 int vt_offset = type2size[field_type];
331 oop old_value = *(oop*)f.interpreter_frame_expression_stack_at(tos_idx - vt_offset);
332 assert(old_value != NULL && oopDesc::is_oop(old_value) && old_value->is_value(),"Verifying receiver");
333 Handle old_value_h(THREAD, old_value);
334
335 // Creating new value by copying the one passed in argument
336 instanceOop new_value = vklass->allocate_instance(
337 CHECK_((type2size[field_type]) * AbstractInterpreter::stackElementSize));
338 Handle new_value_h = Handle(THREAD, new_value);
339 vklass->value_copy_oop_to_new_oop(old_value_h(), new_value_h());
340
341 // Updating the field specified in arguments
342 if (field_type == T_ARRAY || field_type == T_OBJECT) {
343 oop aoop = *(oop*)f.interpreter_frame_expression_stack_at(tos_idx);
344 assert(aoop == NULL || oopDesc::is_oop(aoop),"argument must be a reference type");
345 new_value_h()->obj_field_put(field_offset, aoop);
346 } else if (field_type == T_VALUETYPE) {
347 if (cp_entry->is_flattened()) {
348 oop vt_oop = *(oop*)f.interpreter_frame_expression_stack_at(tos_idx);
349 if (vt_oop == NULL) {
350 THROW_(vmSymbols::java_lang_NullPointerException(),
351 (type2size[field_type] * AbstractInterpreter::stackElementSize));
352 }
353 assert(vt_oop != NULL && oopDesc::is_oop(vt_oop) && vt_oop->is_value(),"argument must be a value type");
354 Klass* field_k = vklass->get_value_field_klass(field_index);
355 ValueKlass* field_vk = ValueKlass::cast(field_k);
356 assert(field_vk == vt_oop->klass(), "Must match");
357 field_vk->value_copy_oop_to_new_payload(vt_oop, ((char*)(oopDesc*)new_value_h()) + field_offset);
358 } else { // not flattened
359 oop voop = *(oop*)f.interpreter_frame_expression_stack_at(tos_idx);
360 if (voop == NULL && cp_entry->is_flattenable()) {
361 THROW_(vmSymbols::java_lang_NullPointerException(),
362 (type2size[field_type] * AbstractInterpreter::stackElementSize));
363 }
364 assert(voop == NULL || oopDesc::is_oop(voop),"checking argument");
365 new_value_h()->obj_field_put(field_offset, voop);
366 }
367 } else { // not T_OBJECT nor T_ARRAY nor T_VALUETYPE
368 intptr_t* addr = f.interpreter_frame_expression_stack_at(tos_idx);
369 copy_primitive_argument(addr, new_value_h, field_offset, field_type);
370 }
371
372 // returning result
373 thread->set_vm_result(new_value_h());
374 return (type2size[field_type] + type2size[T_OBJECT]) * AbstractInterpreter::stackElementSize;
375 JRT_END
376
377 JRT_ENTRY(void, InterpreterRuntime::uninitialized_static_value_field(JavaThread* thread, oopDesc* mirror, int index))
424 JRT_END
425
426 JRT_ENTRY(void, InterpreterRuntime::uninitialized_instance_value_field(JavaThread* thread, oopDesc* obj, int index))
427 instanceHandle obj_h(THREAD, (instanceOop)obj);
428 InstanceKlass* klass = InstanceKlass::cast(obj_h()->klass());
429 Klass* field_k = klass->get_value_field_klass_or_null(index);
430 assert(field_k != NULL, "Must have been initialized");
431 ValueKlass* field_vklass = ValueKlass::cast(field_k);
432 assert(field_vklass->is_initialized(), "Must have been initialized at this point");
433 instanceOop res = (instanceOop)field_vklass->default_value();
434 thread->set_vm_result(res);
435 JRT_END
436
437 JRT_ENTRY(void, InterpreterRuntime::write_flattened_value(JavaThread* thread, oopDesc* value, int offset, oopDesc* rcv))
438 assert(oopDesc::is_oop(value), "Sanity check");
439 assert(oopDesc::is_oop(rcv), "Sanity check");
440 assert(value->is_value(), "Sanity check");
441
442 ValueKlass* vklass = ValueKlass::cast(value->klass());
443 if (!vklass->is_empty_value()) {
444 vklass->value_copy_oop_to_payload(value, ((char*)(oopDesc*)rcv) + offset);
445 }
446 JRT_END
447
448 JRT_ENTRY(void, InterpreterRuntime::read_flattened_field(JavaThread* thread, oopDesc* obj, int index, Klass* field_holder))
449 Handle obj_h(THREAD, obj);
450
451 assert(oopDesc::is_oop(obj), "Sanity check");
452
453 assert(field_holder->is_instance_klass(), "Sanity check");
454 InstanceKlass* klass = InstanceKlass::cast(field_holder);
455
456 assert(klass->field_is_flattened(index), "Sanity check");
457
458 ValueKlass* field_vklass = ValueKlass::cast(klass->get_value_field_klass(index));
459 assert(field_vklass->is_initialized(), "Must be initialized at this point");
460
461 instanceOop res = NULL;
462 if (field_vklass->is_empty_value()) {
463 res = (instanceOop)field_vklass->default_value();
464 } else {
465 res = field_vklass->allocate_instance(CHECK);
466 field_vklass->value_copy_payload_to_new_oop(((char*)(oopDesc*)obj_h()) + klass->field_offset(index), res);
467 }
468 assert(res != NULL, "Must be set in one of two paths above");
469 thread->set_vm_result(res);
470 JRT_END
471
472 JRT_ENTRY(void, InterpreterRuntime::newarray(JavaThread* thread, BasicType type, jint size))
473 oop obj = oopFactory::new_typeArray(type, size, CHECK);
474 thread->set_vm_result(obj);
475 JRT_END
476
477
478 JRT_ENTRY(void, InterpreterRuntime::anewarray(JavaThread* thread, ConstantPool* pool, int index, jint size))
479 Klass* klass = pool->klass_at(index, CHECK);
480 bool is_qtype_desc = pool->tag_at(index).is_Qdescriptor_klass();
481 arrayOop obj;
482 if ((!klass->is_array_klass()) && is_qtype_desc) { // Logically creates elements, ensure klass init
483 klass->initialize(CHECK);
484 obj = oopFactory::new_valueArray(klass, size, CHECK);
485 } else {
486 obj = oopFactory::new_objArray(klass, size, CHECK);
487 }
488 thread->set_vm_result(obj);
489 JRT_END
490
491 JRT_ENTRY(void, InterpreterRuntime::value_array_load(JavaThread* thread, arrayOopDesc* array, int index))
492 valueArrayHandle vah(thread, (valueArrayOop)array);
493 oop value_holder = valueArrayOopDesc::value_copy_from_index(vah, index, CHECK);
494 thread->set_vm_result(value_holder);
495 JRT_END
496
497 JRT_ENTRY(void, InterpreterRuntime::value_array_store(JavaThread* thread, void* val, arrayOopDesc* array, int index))
498 assert(val != NULL, "can't store null into flat array");
499 ((valueArrayOop)array)->value_copy_to_index((oop)val, index);
500 JRT_END
501
502 JRT_ENTRY(void, InterpreterRuntime::multianewarray(JavaThread* thread, jint* first_size_address))
503 // We may want to pass in more arguments - could make this slightly faster
504 LastFrameAccessor last_frame(thread);
505 ConstantPool* constants = last_frame.method()->constants();
506 int i = last_frame.get_index_u2(Bytecodes::_multianewarray);
507 Klass* klass = constants->klass_at(i, CHECK);
508 bool is_qtype = klass->name()->is_Q_array_signature();
509 int nof_dims = last_frame.number_of_dimensions();
510 assert(klass->is_klass(), "not a class");
511 assert(nof_dims >= 1, "multianewarray rank must be nonzero");
512
513 if (is_qtype) { // Logically creates elements, ensure klass init
514 klass->initialize(CHECK);
515 }
516
517 // We must create an array of jints to pass to multi_allocate.
518 ResourceMark rm(thread);
519 const int small_dims = 10;
|