21 * questions.
22 *
23 */
24
25 #include "precompiled.hpp"
26 #include "classfile/javaClasses.inline.hpp"
27 #include "classfile/systemDictionary.hpp"
28 #include "classfile/vmSymbols.hpp"
29 #include "code/codeCache.hpp"
30 #include "compiler/compileBroker.hpp"
31 #include "compiler/disassembler.hpp"
32 #include "gc/shared/collectedHeap.hpp"
33 #include "interpreter/interpreter.hpp"
34 #include "interpreter/interpreterRuntime.hpp"
35 #include "interpreter/linkResolver.hpp"
36 #include "interpreter/templateTable.hpp"
37 #include "logging/log.hpp"
38 #include "memory/oopFactory.hpp"
39 #include "memory/resourceArea.hpp"
40 #include "memory/universe.hpp"
41 #include "memory/vtBuffer.hpp"
42 #include "oops/constantPool.hpp"
43 #include "oops/cpCache.inline.hpp"
44 #include "oops/instanceKlass.hpp"
45 #include "oops/methodData.hpp"
46 #include "oops/objArrayKlass.hpp"
47 #include "oops/objArrayOop.inline.hpp"
48 #include "oops/oop.inline.hpp"
49 #include "oops/symbol.hpp"
50 #include "oops/valueKlass.hpp"
51 #include "oops/valueArrayKlass.hpp"
52 #include "oops/valueArrayOop.hpp"
53 #include "oops/valueArrayOop.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"
320 ValueKlass* vklass = ValueKlass::cast(klass);
321
322 // Getting Field information
323 int offset = cp_entry->f2_as_index();
324 int field_index = cp_entry->field_index();
325 int field_offset = cp_entry->f2_as_offset();
326 Symbol* field_signature = vklass->field_signature(field_index);
327 ResourceMark rm(THREAD);
328 const char* signature = (const char *) field_signature->as_utf8();
329 BasicType field_type = char2type(signature[0]);
330
331 // Getting old value
332 frame& f = last_frame.get_frame();
333 jint tos_idx = f.interpreter_frame_expression_stack_size() - 1;
334 int vt_offset = type2size[field_type];
335 oop old_value = *(oop*)f.interpreter_frame_expression_stack_at(tos_idx - vt_offset);
336 assert(old_value != NULL && oopDesc::is_oop(old_value) && old_value->is_value(),"Verifying receiver");
337 Handle old_value_h(THREAD, old_value);
338
339 // Creating new value by copying the one passed in argument
340 bool in_heap;
341 instanceOop new_value = vklass->allocate_buffered_or_heap_instance(&in_heap,
342 CHECK_((type2size[field_type]) * AbstractInterpreter::stackElementSize));
343 Handle new_value_h = Handle(THREAD, new_value);
344 int first_offset = vklass->first_field_offset();
345 vklass->value_store(vklass->data_for_oop(old_value_h()),
346 vklass->data_for_oop(new_value_h()), in_heap, false);
347
348 // Updating the field specified in arguments
349 if (field_type == T_ARRAY) {
350 oop aoop = *(oop*)f.interpreter_frame_expression_stack_at(tos_idx);
351 assert(aoop == NULL || oopDesc::is_oop(aoop),"argument must be a reference type");
352 if (in_heap) {
353 new_value_h()->obj_field_put(field_offset, aoop);
354 } else {
355 new_value_h()->obj_field_put_raw(field_offset, aoop);
356 }
357 } else if (field_type == T_OBJECT) {
358 if (cp_entry->is_flattened()) {
359 oop vt_oop = *(oop*)f.interpreter_frame_expression_stack_at(tos_idx);
360 if (vt_oop == NULL) {
361 THROW_(vmSymbols::java_lang_NullPointerException(),
362 (type2size[field_type] * AbstractInterpreter::stackElementSize));
363 }
364 assert(vt_oop != NULL && oopDesc::is_oop(vt_oop) && vt_oop->is_value(),"argument must be a value type");
365 Klass* field_k = vklass->get_value_field_klass(field_index);
366 ValueKlass* field_vk = ValueKlass::cast(field_k);
367 assert(field_vk == vt_oop->klass(), "Must match");
368 field_vk->value_store(field_vk->data_for_oop(vt_oop),
369 ((char*)(oopDesc*)new_value_h()) + field_offset, in_heap, false);
370 } else { // not flattened
371 oop voop = *(oop*)f.interpreter_frame_expression_stack_at(tos_idx);
372 if (voop == NULL && cp_entry->is_flattenable()) {
373 THROW_(vmSymbols::java_lang_NullPointerException(),
374 (type2size[field_type] * AbstractInterpreter::stackElementSize));
375 }
376 assert(voop == NULL || oopDesc::is_oop(voop),"checking argument");
377 if (VTBuffer::is_in_vt_buffer(voop)) {
378 // new value field is currently allocated in a TLVB, a heap allocated
379 // copy must be created because a field must never point to a TLVB allocated value
380 Handle voop_h = Handle(THREAD, voop);
381 ValueKlass* field_vk = ValueKlass::cast(voop->klass());
382 assert(!cp_entry->is_flattenable() || field_vk == vklass->get_value_field_klass(field_index), "Sanity check");
383 instanceOop field_copy = field_vk->allocate_instance(CHECK_((type2size[field_type]) * AbstractInterpreter::stackElementSize));
384 Handle field_copy_h = Handle(THREAD, field_copy);
385 field_vk->value_store(field_vk->data_for_oop(voop_h()), field_vk->data_for_oop(field_copy_h()), true, false);
386 if (in_heap) {
387 new_value_h()->obj_field_put(field_offset, field_copy_h());
388 } else {
389 new_value_h()->obj_field_put_raw(field_offset, field_copy_h());
390 }
391 } else { // not buffered
392 if (in_heap) {
393 new_value_h()->obj_field_put(field_offset, voop);
394 } else {
395 new_value_h()->obj_field_put_raw(field_offset, voop);
396 }
397 }
398 }
399 } else { // not T_OBJECT nor T_ARRAY
400 intptr_t* addr = f.interpreter_frame_expression_stack_at(tos_idx);
401 copy_primitive_argument(addr, new_value_h, field_offset, field_type);
402 }
403
404 // returning result
405 thread->set_vm_result(new_value_h());
406 return (type2size[field_type] + type2size[T_OBJECT]) * AbstractInterpreter::stackElementSize;
407 IRT_END
408
409 IRT_ENTRY(void, InterpreterRuntime::uninitialized_static_value_field(JavaThread* thread, oopDesc* mirror, int index))
410 instanceHandle mirror_h(THREAD, (instanceOop)mirror);
411 InstanceKlass* klass = InstanceKlass::cast(java_lang_Class::as_Klass(mirror));
412 int offset = klass->field_offset(index);
413 Klass* field_k = klass->get_value_field_klass_or_null(index);
414 assert(field_k != NULL, "Must have been initialized");
415 ValueKlass* field_vklass = ValueKlass::cast(field_k);
416 instanceOop res = (instanceOop)field_vklass->default_value();
417 thread->set_vm_result(res);
418 IRT_END
419
420 IRT_ENTRY(void, InterpreterRuntime::uninitialized_instance_value_field(JavaThread* thread, oopDesc* obj, int index))
421 instanceHandle obj_h(THREAD, (instanceOop)obj);
422 InstanceKlass* klass = InstanceKlass::cast(obj_h()->klass());
423 Klass* field_k = klass->get_value_field_klass_or_null(index);
424 assert(field_k != NULL, "Must have been initialized");
425 ValueKlass* field_vklass = ValueKlass::cast(field_k);
426 assert(field_vklass->is_initialized(), "Must have been initialized at this point");
427 instanceOop res = (instanceOop)field_vklass->default_value();
428 thread->set_vm_result(res);
429 IRT_END
430
431 IRT_ENTRY(void, InterpreterRuntime::write_heap_copy(JavaThread* thread, oopDesc* value, int offset, oopDesc* rcv))
432 assert(oopDesc::is_oop(value), "Sanity check");
433 assert(oopDesc::is_oop(rcv) ,"Sanity check");
434 assert(value->is_value(), "Sanity check");
435 assert(rcv->is_instance(), "Sanity check");
436 assert(VTBuffer::is_in_vt_buffer(value), "Should only be called for buffered values");
437
438 ValueKlass* vk = ValueKlass::cast(value->klass());
439 Handle val_h(THREAD, value);
440 Handle rcv_h(THREAD, rcv);
441 instanceOop res = vk->allocate_instance(CHECK);
442 // copy value
443 vk->value_store(vk->data_for_oop(val_h()),
444 vk->data_for_oop(res), true, false);
445 ((instanceOop)rcv_h())->obj_field_put(offset, res);
446 IRT_END
447
448 IRT_ENTRY(void, InterpreterRuntime::write_flattened_value(JavaThread* thread, oopDesc* value, int offset, oopDesc* rcv))
449 assert(oopDesc::is_oop(value), "Sanity check");
450 assert(oopDesc::is_oop(rcv), "Sanity check");
451 assert(value->is_value(), "Sanity check");
452
453 ValueKlass* vklass = ValueKlass::cast(value->klass());
454 vklass->value_store(vklass->data_for_oop(value), ((char*)(oopDesc*)rcv) + offset, true, true);
455 IRT_END
456
457 IRT_ENTRY(void, InterpreterRuntime::read_flattened_field(JavaThread* thread, oopDesc* obj, int index, Klass* field_holder))
458 Handle obj_h(THREAD, obj);
459
460 assert(oopDesc::is_oop(obj), "Sanity check");
461
462 assert(field_holder->is_instance_klass(), "Sanity check");
463 InstanceKlass* klass = InstanceKlass::cast(field_holder);
464
465 assert(klass->field_is_flattened(index), "Sanity check");
466
467 ValueKlass* field_vklass = ValueKlass::cast(klass->get_value_field_klass(index));
468 assert(field_vklass->is_initialized(), "Must be initialized at this point");
469
470 bool in_heap;
471 // allocate instance
472 instanceOop res = field_vklass->allocate_buffered_or_heap_instance(&in_heap, CHECK);
473 // copy value
474 field_vklass->value_store(((char*)(oopDesc*)obj_h()) + klass->field_offset(index),
475 field_vklass->data_for_oop(res), in_heap, true);
476 thread->set_vm_result(res);
477 IRT_END
478
479 IRT_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 IRT_END
483
484
485 IRT_ENTRY(void, InterpreterRuntime::anewarray(JavaThread* thread, ConstantPool* pool, int index, jint size))
486 Klass* klass = pool->klass_at(index, CHECK);
487 if (klass->is_value()) { // Logically creates elements, ensure klass init
488 klass->initialize(CHECK);
489 }
490 arrayOop obj = oopFactory::new_array(klass, size, CHECK);
491 thread->set_vm_result(obj);
492 IRT_END
493
494 IRT_ENTRY(void, InterpreterRuntime::value_array_load(JavaThread* thread, arrayOopDesc* array, int index))
495 Klass* klass = array->klass();
496 assert(klass->is_valueArray_klass(), "expected value array oop");
497
498 ValueArrayKlass* vaklass = ValueArrayKlass::cast(klass);
499 ValueKlass* vklass = vaklass->element_klass();
500 arrayHandle ah(THREAD, array);
501 bool in_heap;
502 instanceOop value_holder = vklass->allocate_buffered_or_heap_instance(&in_heap, CHECK);
503 void* src = ((valueArrayOop)ah())->value_at_addr(index, vaklass->layout_helper());
504 vklass->value_store(src, vklass->data_for_oop(value_holder),
505 vaklass->element_byte_size(), in_heap, false);
506 thread->set_vm_result(value_holder);
507 IRT_END
508
509 IRT_ENTRY(void, InterpreterRuntime::value_array_store(JavaThread* thread, void* val, arrayOopDesc* array, int index))
510 assert(val != NULL, "can't store null into flat array");
511 Klass* klass = array->klass();
512 assert(klass->is_valueArray_klass(), "expected value array");
513 assert(ArrayKlass::cast(klass)->element_klass() == ((oop)val)->klass(), "Store type incorrect");
514
515 valueArrayOop varray = (valueArrayOop)array;
516 ValueArrayKlass* vaklass = ValueArrayKlass::cast(klass);
517 ValueKlass* vklass = vaklass->element_klass();
518 const int lh = vaklass->layout_helper();
519 vklass->value_store(vklass->data_for_oop((oop)val), varray->value_at_addr(index, lh),
520 vaklass->element_byte_size(), true, false);
521 IRT_END
522
523 IRT_ENTRY(void, InterpreterRuntime::multianewarray(JavaThread* thread, jint* first_size_address))
524 // We may want to pass in more arguments - could make this slightly faster
525 LastFrameAccessor last_frame(thread);
534 klass->initialize(CHECK);
535 }
536
537 // We must create an array of jints to pass to multi_allocate.
538 ResourceMark rm(thread);
539 const int small_dims = 10;
540 jint dim_array[small_dims];
541 jint *dims = &dim_array[0];
542 if (nof_dims > small_dims) {
543 dims = (jint*) NEW_RESOURCE_ARRAY(jint, nof_dims);
544 }
545 for (int index = 0; index < nof_dims; index++) {
546 // offset from first_size_address is addressed as local[index]
547 int n = Interpreter::local_offset_in_bytes(index)/jintSize;
548 dims[index] = first_size_address[n];
549 }
550 oop obj = ArrayKlass::cast(klass)->multi_allocate(nof_dims, dims, CHECK);
551 thread->set_vm_result(obj);
552 IRT_END
553
554 IRT_ENTRY(void, InterpreterRuntime::value_heap_copy(JavaThread* thread, oopDesc* value))
555 assert(VTBuffer::is_in_vt_buffer(value), "Must only be called for buffered values");
556 ValueKlass* vk = ValueKlass::cast(value->klass());
557 Handle val_h(THREAD, value);
558 instanceOop obj = vk->allocate_instance(CHECK);
559 Handle obj_h(THREAD, obj);
560 vk->value_store(vk->data_for_oop(val_h()), vk->data_for_oop(obj_h()), true, false);
561 thread->set_vm_result(obj_h());
562 IRT_END
563
564 IRT_LEAF(void, InterpreterRuntime::recycle_vtbuffer(void* alloc_ptr))
565 JavaThread* thread = (JavaThread*)Thread::current();
566 VTBuffer::recycle_vtbuffer(thread, alloc_ptr);
567 IRT_END
568
569 IRT_ENTRY(void, InterpreterRuntime::recycle_buffered_values(JavaThread* thread))
570 frame f = thread->last_frame();
571 assert(f.is_interpreted_frame(), "recycling can only be triggered from interpreted frames");
572 VTBuffer::recycle_vt_in_frame(thread, &f);
573 IRT_END
574
575 IRT_ENTRY(void, InterpreterRuntime::fix_frame_vt_alloc_ptr(JavaThread* thread))
576 frame f = thread->last_frame();
577 VTBuffer::fix_frame_vt_alloc_ptr(f, VTBufferChunk::chunk(thread->vt_alloc_ptr()));
578 IRT_END
579
580 IRT_ENTRY(void, InterpreterRuntime::return_value(JavaThread* thread, oopDesc* obj))
581 assert(VTBuffer::is_in_vt_buffer(obj), "Must only be called for buffered values");
582 assert(obj->klass()->is_value(), "Sanity check");
583 ValueKlass* vk = ValueKlass::cast(obj->klass());
584 RegisterMap reg_map(thread, false);
585 frame current_frame = thread->last_frame();
586 frame caller_frame = current_frame.sender(®_map);
587 if (!caller_frame.is_interpreted_frame()) {
588 // caller is not an interpreted frame, creating a new value in Java heap
589 Handle obj_h(THREAD, obj);
590 instanceOop res = vk->allocate_instance(CHECK);
591 Handle res_h(THREAD, res);
592 // copy value
593 vk->value_store(vk->data_for_oop(obj_h()),
594 vk->data_for_oop(res_h()), true, false);
595 thread->set_vm_result(res_h());
596 return;
597 } else {
598 // A buffered value is being returned to an interpreted frame,
599 // but the work has to be delayed to remove_activation() because
600 // the frame cannot be modified now (GC can run at the safepoint
601 // when exiting runtime, and frame layout must be kept consistent
602 // with the OopMap).
603 thread->set_return_buffered_value(obj);
604 thread->set_vm_result(obj);
605 }
606 IRT_END
607
608 IRT_LEAF(void, InterpreterRuntime::return_value_step2(oopDesc* obj, void* alloc_ptr))
609
610 JavaThread* thread = (JavaThread*)Thread::current();
611 assert(obj == thread->return_buffered_value(), "Consistency check");
612 assert(!Universe::heap()->is_in_reserved(obj), "Should only apply to buffered values");
613
614 oop dest = VTBuffer::relocate_return_value(thread, alloc_ptr, obj);
615 thread->set_return_buffered_value(NULL);
616 thread->set_vm_result(dest);
617 IRT_END
618
619 IRT_ENTRY(void, InterpreterRuntime::register_finalizer(JavaThread* thread, oopDesc* obj))
620 assert(oopDesc::is_oop(obj), "must be a valid oop");
621 assert(obj->klass()->has_finalizer(), "shouldn't be here otherwise");
622 InstanceKlass::register_finalizer(instanceOop(obj), CHECK);
623 IRT_END
624
625
626 // Quicken instance-of and check-cast bytecodes
627 IRT_ENTRY(void, InterpreterRuntime::quicken_io_cc(JavaThread* thread))
628 // Force resolving; quicken the bytecode
629 LastFrameAccessor last_frame(thread);
630 int which = last_frame.get_index_u2(Bytecodes::_checkcast);
631 ConstantPool* cpool = last_frame.method()->constants();
632 // We'd expect to assert that we're only here to quicken bytecodes, but in a multithreaded
633 // program we might have seen an unquick'd bytecode in the interpreter but have another
634 // thread quicken the bytecode before we get here.
635 // assert( cpool->tag_at(which).is_unresolved_klass(), "should only come here to quicken bytecodes" );
636 Klass* klass = cpool->klass_at(which, CHECK);
637 thread->set_vm_result_2(klass);
1170 method->set_orig_bytecode_at(method->bci_from(bcp), new_code);
1171 IRT_END
1172
1173 IRT_ENTRY(void, InterpreterRuntime::_breakpoint(JavaThread* thread, Method* method, address bcp))
1174 JvmtiExport::post_raw_breakpoint(thread, method, bcp);
1175 IRT_END
1176
1177 void InterpreterRuntime::resolve_invoke(JavaThread* thread, Bytecodes::Code bytecode) {
1178 Thread* THREAD = thread;
1179 LastFrameAccessor last_frame(thread);
1180 // extract receiver from the outgoing argument list if necessary
1181 Handle receiver(thread, NULL);
1182 if (bytecode == Bytecodes::_invokevirtual || bytecode == Bytecodes::_invokeinterface ||
1183 bytecode == Bytecodes::_invokespecial) {
1184 ResourceMark rm(thread);
1185 methodHandle m (thread, last_frame.method());
1186 Bytecode_invoke call(m, last_frame.bci());
1187 Symbol* signature = call.signature();
1188 receiver = Handle(thread, last_frame.callee_receiver(signature));
1189
1190 assert(Universe::heap()->is_in_reserved_or_null(receiver())
1191 || VTBuffer::is_in_vt_buffer(receiver()),
1192 "sanity check");
1193 assert(receiver.is_null() ||
1194 !Universe::heap()->is_in_reserved(receiver->klass()),
1195 "sanity check");
1196 }
1197
1198 // resolve method
1199 CallInfo info;
1200 constantPoolHandle pool(thread, last_frame.method()->constants());
1201
1202 {
1203 JvmtiHideSingleStepping jhss(thread);
1204 LinkResolver::resolve_invoke(info, receiver, pool,
1205 last_frame.get_index_u2_cpcache(bytecode), bytecode,
1206 CHECK);
1207 if (JvmtiExport::can_hotswap_or_post_breakpoint()) {
1208 int retry_count = 0;
1209 while (info.resolved_method()->is_old()) {
1210 // It is very unlikely that method is redefined more than 100 times
1211 // in the middle of resolve. If it is looping here more than 100 times
1212 // means then there could be a bug here.
|
21 * questions.
22 *
23 */
24
25 #include "precompiled.hpp"
26 #include "classfile/javaClasses.inline.hpp"
27 #include "classfile/systemDictionary.hpp"
28 #include "classfile/vmSymbols.hpp"
29 #include "code/codeCache.hpp"
30 #include "compiler/compileBroker.hpp"
31 #include "compiler/disassembler.hpp"
32 #include "gc/shared/collectedHeap.hpp"
33 #include "interpreter/interpreter.hpp"
34 #include "interpreter/interpreterRuntime.hpp"
35 #include "interpreter/linkResolver.hpp"
36 #include "interpreter/templateTable.hpp"
37 #include "logging/log.hpp"
38 #include "memory/oopFactory.hpp"
39 #include "memory/resourceArea.hpp"
40 #include "memory/universe.hpp"
41 #include "oops/constantPool.hpp"
42 #include "oops/cpCache.inline.hpp"
43 #include "oops/instanceKlass.hpp"
44 #include "oops/methodData.hpp"
45 #include "oops/objArrayKlass.hpp"
46 #include "oops/objArrayOop.inline.hpp"
47 #include "oops/oop.inline.hpp"
48 #include "oops/symbol.hpp"
49 #include "oops/valueKlass.hpp"
50 #include "oops/valueArrayKlass.hpp"
51 #include "oops/valueArrayOop.hpp"
52 #include "oops/valueArrayOop.inline.hpp"
53 #include "prims/jvmtiExport.hpp"
54 #include "prims/nativeLookup.hpp"
55 #include "runtime/atomic.hpp"
56 #include "runtime/biasedLocking.hpp"
57 #include "runtime/compilationPolicy.hpp"
58 #include "runtime/deoptimization.hpp"
59 #include "runtime/fieldDescriptor.inline.hpp"
60 #include "runtime/frame.inline.hpp"
319 ValueKlass* vklass = ValueKlass::cast(klass);
320
321 // Getting Field information
322 int offset = cp_entry->f2_as_index();
323 int field_index = cp_entry->field_index();
324 int field_offset = cp_entry->f2_as_offset();
325 Symbol* field_signature = vklass->field_signature(field_index);
326 ResourceMark rm(THREAD);
327 const char* signature = (const char *) field_signature->as_utf8();
328 BasicType field_type = char2type(signature[0]);
329
330 // Getting old value
331 frame& f = last_frame.get_frame();
332 jint tos_idx = f.interpreter_frame_expression_stack_size() - 1;
333 int vt_offset = type2size[field_type];
334 oop old_value = *(oop*)f.interpreter_frame_expression_stack_at(tos_idx - vt_offset);
335 assert(old_value != NULL && oopDesc::is_oop(old_value) && old_value->is_value(),"Verifying receiver");
336 Handle old_value_h(THREAD, old_value);
337
338 // Creating new value by copying the one passed in argument
339 instanceOop new_value = vklass->allocate_instance(
340 CHECK_((type2size[field_type]) * AbstractInterpreter::stackElementSize));
341 Handle new_value_h = Handle(THREAD, new_value);
342 int first_offset = vklass->first_field_offset();
343 vklass->value_store(vklass->data_for_oop(old_value_h()),
344 vklass->data_for_oop(new_value_h()), true, false);
345
346 // Updating the field specified in arguments
347 if (field_type == T_ARRAY) {
348 oop aoop = *(oop*)f.interpreter_frame_expression_stack_at(tos_idx);
349 assert(aoop == NULL || oopDesc::is_oop(aoop),"argument must be a reference type");
350 new_value_h()->obj_field_put(field_offset, aoop);
351 } else if (field_type == T_OBJECT) {
352 if (cp_entry->is_flattened()) {
353 oop vt_oop = *(oop*)f.interpreter_frame_expression_stack_at(tos_idx);
354 if (vt_oop == NULL) {
355 THROW_(vmSymbols::java_lang_NullPointerException(),
356 (type2size[field_type] * AbstractInterpreter::stackElementSize));
357 }
358 assert(vt_oop != NULL && oopDesc::is_oop(vt_oop) && vt_oop->is_value(),"argument must be a value type");
359 Klass* field_k = vklass->get_value_field_klass(field_index);
360 ValueKlass* field_vk = ValueKlass::cast(field_k);
361 assert(field_vk == vt_oop->klass(), "Must match");
362 field_vk->value_store(field_vk->data_for_oop(vt_oop),
363 ((char*)(oopDesc*)new_value_h()) + field_offset, false, false);
364 } else { // not flattened
365 oop voop = *(oop*)f.interpreter_frame_expression_stack_at(tos_idx);
366 if (voop == NULL && cp_entry->is_flattenable()) {
367 THROW_(vmSymbols::java_lang_NullPointerException(),
368 (type2size[field_type] * AbstractInterpreter::stackElementSize));
369 }
370 assert(voop == NULL || oopDesc::is_oop(voop),"checking argument");
371 new_value_h()->obj_field_put(field_offset, voop);
372 }
373 } else { // not T_OBJECT nor T_ARRAY
374 intptr_t* addr = f.interpreter_frame_expression_stack_at(tos_idx);
375 copy_primitive_argument(addr, new_value_h, field_offset, field_type);
376 }
377
378 // returning result
379 thread->set_vm_result(new_value_h());
380 return (type2size[field_type] + type2size[T_OBJECT]) * AbstractInterpreter::stackElementSize;
381 IRT_END
382
383 IRT_ENTRY(void, InterpreterRuntime::uninitialized_static_value_field(JavaThread* thread, oopDesc* mirror, int index))
384 instanceHandle mirror_h(THREAD, (instanceOop)mirror);
385 InstanceKlass* klass = InstanceKlass::cast(java_lang_Class::as_Klass(mirror));
386 int offset = klass->field_offset(index);
387 Klass* field_k = klass->get_value_field_klass_or_null(index);
388 assert(field_k != NULL, "Must have been initialized");
389 ValueKlass* field_vklass = ValueKlass::cast(field_k);
390 instanceOop res = (instanceOop)field_vklass->default_value();
391 thread->set_vm_result(res);
392 IRT_END
393
394 IRT_ENTRY(void, InterpreterRuntime::uninitialized_instance_value_field(JavaThread* thread, oopDesc* obj, int index))
395 instanceHandle obj_h(THREAD, (instanceOop)obj);
396 InstanceKlass* klass = InstanceKlass::cast(obj_h()->klass());
397 Klass* field_k = klass->get_value_field_klass_or_null(index);
398 assert(field_k != NULL, "Must have been initialized");
399 ValueKlass* field_vklass = ValueKlass::cast(field_k);
400 assert(field_vklass->is_initialized(), "Must have been initialized at this point");
401 instanceOop res = (instanceOop)field_vklass->default_value();
402 thread->set_vm_result(res);
403 IRT_END
404
405 IRT_ENTRY(void, InterpreterRuntime::write_flattened_value(JavaThread* thread, oopDesc* value, int offset, oopDesc* rcv))
406 assert(oopDesc::is_oop(value), "Sanity check");
407 assert(oopDesc::is_oop(rcv), "Sanity check");
408 assert(value->is_value(), "Sanity check");
409
410 ValueKlass* vklass = ValueKlass::cast(value->klass());
411 vklass->value_store(vklass->data_for_oop(value), ((char*)(oopDesc*)rcv) + offset, true, true);
412 IRT_END
413
414 IRT_ENTRY(void, InterpreterRuntime::read_flattened_field(JavaThread* thread, oopDesc* obj, int index, Klass* field_holder))
415 Handle obj_h(THREAD, obj);
416
417 assert(oopDesc::is_oop(obj), "Sanity check");
418
419 assert(field_holder->is_instance_klass(), "Sanity check");
420 InstanceKlass* klass = InstanceKlass::cast(field_holder);
421
422 assert(klass->field_is_flattened(index), "Sanity check");
423
424 ValueKlass* field_vklass = ValueKlass::cast(klass->get_value_field_klass(index));
425 assert(field_vklass->is_initialized(), "Must be initialized at this point");
426
427 // allocate instance
428 instanceOop res = field_vklass->allocate_instance(CHECK);
429 // copy value
430 field_vklass->value_store(((char*)(oopDesc*)obj_h()) + klass->field_offset(index),
431 field_vklass->data_for_oop(res), true, true);
432 thread->set_vm_result(res);
433 IRT_END
434
435 IRT_ENTRY(void, InterpreterRuntime::newarray(JavaThread* thread, BasicType type, jint size))
436 oop obj = oopFactory::new_typeArray(type, size, CHECK);
437 thread->set_vm_result(obj);
438 IRT_END
439
440
441 IRT_ENTRY(void, InterpreterRuntime::anewarray(JavaThread* thread, ConstantPool* pool, int index, jint size))
442 Klass* klass = pool->klass_at(index, CHECK);
443 if (klass->is_value()) { // Logically creates elements, ensure klass init
444 klass->initialize(CHECK);
445 }
446 arrayOop obj = oopFactory::new_array(klass, size, CHECK);
447 thread->set_vm_result(obj);
448 IRT_END
449
450 IRT_ENTRY(void, InterpreterRuntime::value_array_load(JavaThread* thread, arrayOopDesc* array, int index))
451 Klass* klass = array->klass();
452 assert(klass->is_valueArray_klass(), "expected value array oop");
453
454 ValueArrayKlass* vaklass = ValueArrayKlass::cast(klass);
455 ValueKlass* vklass = vaklass->element_klass();
456 arrayHandle ah(THREAD, array);
457 instanceOop value_holder = vklass->allocate_instance(CHECK);
458 void* src = ((valueArrayOop)ah())->value_at_addr(index, vaklass->layout_helper());
459 vklass->value_store(src, vklass->data_for_oop(value_holder),
460 vaklass->element_byte_size(), true, false);
461 thread->set_vm_result(value_holder);
462 IRT_END
463
464 IRT_ENTRY(void, InterpreterRuntime::value_array_store(JavaThread* thread, void* val, arrayOopDesc* array, int index))
465 assert(val != NULL, "can't store null into flat array");
466 Klass* klass = array->klass();
467 assert(klass->is_valueArray_klass(), "expected value array");
468 assert(ArrayKlass::cast(klass)->element_klass() == ((oop)val)->klass(), "Store type incorrect");
469
470 valueArrayOop varray = (valueArrayOop)array;
471 ValueArrayKlass* vaklass = ValueArrayKlass::cast(klass);
472 ValueKlass* vklass = vaklass->element_klass();
473 const int lh = vaklass->layout_helper();
474 vklass->value_store(vklass->data_for_oop((oop)val), varray->value_at_addr(index, lh),
475 vaklass->element_byte_size(), true, false);
476 IRT_END
477
478 IRT_ENTRY(void, InterpreterRuntime::multianewarray(JavaThread* thread, jint* first_size_address))
479 // We may want to pass in more arguments - could make this slightly faster
480 LastFrameAccessor last_frame(thread);
489 klass->initialize(CHECK);
490 }
491
492 // We must create an array of jints to pass to multi_allocate.
493 ResourceMark rm(thread);
494 const int small_dims = 10;
495 jint dim_array[small_dims];
496 jint *dims = &dim_array[0];
497 if (nof_dims > small_dims) {
498 dims = (jint*) NEW_RESOURCE_ARRAY(jint, nof_dims);
499 }
500 for (int index = 0; index < nof_dims; index++) {
501 // offset from first_size_address is addressed as local[index]
502 int n = Interpreter::local_offset_in_bytes(index)/jintSize;
503 dims[index] = first_size_address[n];
504 }
505 oop obj = ArrayKlass::cast(klass)->multi_allocate(nof_dims, dims, CHECK);
506 thread->set_vm_result(obj);
507 IRT_END
508
509
510 IRT_ENTRY(void, InterpreterRuntime::register_finalizer(JavaThread* thread, oopDesc* obj))
511 assert(oopDesc::is_oop(obj), "must be a valid oop");
512 assert(obj->klass()->has_finalizer(), "shouldn't be here otherwise");
513 InstanceKlass::register_finalizer(instanceOop(obj), CHECK);
514 IRT_END
515
516
517 // Quicken instance-of and check-cast bytecodes
518 IRT_ENTRY(void, InterpreterRuntime::quicken_io_cc(JavaThread* thread))
519 // Force resolving; quicken the bytecode
520 LastFrameAccessor last_frame(thread);
521 int which = last_frame.get_index_u2(Bytecodes::_checkcast);
522 ConstantPool* cpool = last_frame.method()->constants();
523 // We'd expect to assert that we're only here to quicken bytecodes, but in a multithreaded
524 // program we might have seen an unquick'd bytecode in the interpreter but have another
525 // thread quicken the bytecode before we get here.
526 // assert( cpool->tag_at(which).is_unresolved_klass(), "should only come here to quicken bytecodes" );
527 Klass* klass = cpool->klass_at(which, CHECK);
528 thread->set_vm_result_2(klass);
1061 method->set_orig_bytecode_at(method->bci_from(bcp), new_code);
1062 IRT_END
1063
1064 IRT_ENTRY(void, InterpreterRuntime::_breakpoint(JavaThread* thread, Method* method, address bcp))
1065 JvmtiExport::post_raw_breakpoint(thread, method, bcp);
1066 IRT_END
1067
1068 void InterpreterRuntime::resolve_invoke(JavaThread* thread, Bytecodes::Code bytecode) {
1069 Thread* THREAD = thread;
1070 LastFrameAccessor last_frame(thread);
1071 // extract receiver from the outgoing argument list if necessary
1072 Handle receiver(thread, NULL);
1073 if (bytecode == Bytecodes::_invokevirtual || bytecode == Bytecodes::_invokeinterface ||
1074 bytecode == Bytecodes::_invokespecial) {
1075 ResourceMark rm(thread);
1076 methodHandle m (thread, last_frame.method());
1077 Bytecode_invoke call(m, last_frame.bci());
1078 Symbol* signature = call.signature();
1079 receiver = Handle(thread, last_frame.callee_receiver(signature));
1080
1081 assert(Universe::heap()->is_in_reserved_or_null(receiver()), "sanity check");
1082 assert(receiver.is_null() ||
1083 !Universe::heap()->is_in_reserved(receiver->klass()),
1084 "sanity check");
1085 }
1086
1087 // resolve method
1088 CallInfo info;
1089 constantPoolHandle pool(thread, last_frame.method()->constants());
1090
1091 {
1092 JvmtiHideSingleStepping jhss(thread);
1093 LinkResolver::resolve_invoke(info, receiver, pool,
1094 last_frame.get_index_u2_cpcache(bytecode), bytecode,
1095 CHECK);
1096 if (JvmtiExport::can_hotswap_or_post_breakpoint()) {
1097 int retry_count = 0;
1098 while (info.resolved_method()->is_old()) {
1099 // It is very unlikely that method is redefined more than 100 times
1100 // in the middle of resolve. If it is looping here more than 100 times
1101 // means then there could be a bug here.
|