--- old/src/share/vm/interpreter/bytecodeInterpreter.cpp 2015-12-05 15:20:04.482452265 +0100 +++ new/src/share/vm/interpreter/bytecodeInterpreter.cpp 2015-12-05 15:20:04.218452257 +0100 @@ -1947,93 +1947,143 @@ cache = cp->entry_at(index); } + if (cache->is_field_entry()) { #ifdef VM_JVMTI - if (_jvmti_interp_events) { - int *count_addr; - oop obj; - // Check to see if a field modification watch has been set - // before we take the time to call into the VM. - count_addr = (int *)JvmtiExport::get_field_access_count_addr(); - if ( *count_addr > 0 ) { - if ((Bytecodes::Code)opcode == Bytecodes::_getstatic) { - obj = (oop)NULL; - } else { - obj = (oop) STACK_OBJECT(-1); - VERIFY_OOP(obj); + if (_jvmti_interp_events) { + int *count_addr; + oop obj; + // Check to see if a field modification watch has been set + // before we take the time to call into the VM. + count_addr = (int *)JvmtiExport::get_field_access_count_addr(); + if ( *count_addr > 0 ) { + if ((Bytecodes::Code)opcode == Bytecodes::_getstatic) { + obj = (oop)NULL; + } else { + obj = (oop) STACK_OBJECT(-1); + VERIFY_OOP(obj); + } + CALL_VM(InterpreterRuntime::post_field_access(THREAD, + obj, + cache), + handle_exception); } - CALL_VM(InterpreterRuntime::post_field_access(THREAD, - obj, - cache), - handle_exception); } - } #endif /* VM_JVMTI */ - oop obj; - if ((Bytecodes::Code)opcode == Bytecodes::_getstatic) { - Klass* k = cache->f1_as_klass(); - obj = k->java_mirror(); - MORE_STACK(1); // Assume single slot push - } else { - obj = (oop) STACK_OBJECT(-1); - CHECK_NULL(obj); - } - - // - // Now store the result on the stack - // - TosState tos_type = cache->flag_state(); - int field_offset = cache->f2_as_index(); - if (cache->is_volatile()) { - if (support_IRIW_for_not_multiple_copy_atomic_cpu) { - OrderAccess::fence(); - } - if (tos_type == atos) { - VERIFY_OOP(obj->obj_field_acquire(field_offset)); - SET_STACK_OBJECT(obj->obj_field_acquire(field_offset), -1); - } else if (tos_type == itos) { - SET_STACK_INT(obj->int_field_acquire(field_offset), -1); - } else if (tos_type == ltos) { - SET_STACK_LONG(obj->long_field_acquire(field_offset), 0); - MORE_STACK(1); - } else if (tos_type == btos) { - SET_STACK_INT(obj->byte_field_acquire(field_offset), -1); - } else if (tos_type == ctos) { - SET_STACK_INT(obj->char_field_acquire(field_offset), -1); - } else if (tos_type == stos) { - SET_STACK_INT(obj->short_field_acquire(field_offset), -1); - } else if (tos_type == ftos) { - SET_STACK_FLOAT(obj->float_field_acquire(field_offset), -1); + oop obj; + if ((Bytecodes::Code)opcode == Bytecodes::_getstatic) { + Klass* k = cache->f1_as_klass(); + obj = k->java_mirror(); + MORE_STACK(1); // Assume single slot push } else { - SET_STACK_DOUBLE(obj->double_field_acquire(field_offset), 0); - MORE_STACK(1); + obj = (oop) STACK_OBJECT(-1); + CHECK_NULL(obj); } - } else { - if (tos_type == atos) { - VERIFY_OOP(obj->obj_field(field_offset)); - SET_STACK_OBJECT(obj->obj_field(field_offset), -1); - } else if (tos_type == itos) { - SET_STACK_INT(obj->int_field(field_offset), -1); - } else if (tos_type == ltos) { - SET_STACK_LONG(obj->long_field(field_offset), 0); - MORE_STACK(1); - } else if (tos_type == btos) { - SET_STACK_INT(obj->byte_field(field_offset), -1); - } else if (tos_type == ctos) { - SET_STACK_INT(obj->char_field(field_offset), -1); - } else if (tos_type == stos) { - SET_STACK_INT(obj->short_field(field_offset), -1); - } else if (tos_type == ftos) { - SET_STACK_FLOAT(obj->float_field(field_offset), -1); + + // + // Now store the result on the stack + // + TosState tos_type = cache->flag_state(); + int field_offset = cache->f2_as_index(); + if (cache->is_volatile()) { + if (support_IRIW_for_not_multiple_copy_atomic_cpu) { + OrderAccess::fence(); + } + if (tos_type == atos) { + VERIFY_OOP(obj->obj_field_acquire(field_offset)); + SET_STACK_OBJECT(obj->obj_field_acquire(field_offset), -1); + } else if (tos_type == itos) { + SET_STACK_INT(obj->int_field_acquire(field_offset), -1); + } else if (tos_type == ltos) { + SET_STACK_LONG(obj->long_field_acquire(field_offset), 0); + MORE_STACK(1); + } else if (tos_type == btos) { + SET_STACK_INT(obj->byte_field_acquire(field_offset), -1); + } else if (tos_type == ctos) { + SET_STACK_INT(obj->char_field_acquire(field_offset), -1); + } else if (tos_type == stos) { + SET_STACK_INT(obj->short_field_acquire(field_offset), -1); + } else if (tos_type == ftos) { + SET_STACK_FLOAT(obj->float_field_acquire(field_offset), -1); + } else { + SET_STACK_DOUBLE(obj->double_field_acquire(field_offset), 0); + MORE_STACK(1); + } } else { - SET_STACK_DOUBLE(obj->double_field(field_offset), 0); - MORE_STACK(1); + if (tos_type == atos) { + VERIFY_OOP(obj->obj_field(field_offset)); + SET_STACK_OBJECT(obj->obj_field(field_offset), -1); + } else if (tos_type == itos) { + SET_STACK_INT(obj->int_field(field_offset), -1); + } else if (tos_type == ltos) { + SET_STACK_LONG(obj->long_field(field_offset), 0); + MORE_STACK(1); + } else if (tos_type == btos) { + SET_STACK_INT(obj->byte_field(field_offset), -1); + } else if (tos_type == ctos) { + SET_STACK_INT(obj->char_field(field_offset), -1); + } else if (tos_type == stos) { + SET_STACK_INT(obj->short_field(field_offset), -1); + } else if (tos_type == ftos) { + SET_STACK_FLOAT(obj->float_field(field_offset), -1); + } else { + SET_STACK_DOUBLE(obj->double_field(field_offset), 0); + MORE_STACK(1); + } } - } + + UPDATE_PC_AND_CONTINUE(3); + }else { + // mostly copied from _invokevirtual and _invokestatic + istate->set_msg(call_method); + Method* callee; + if ((Bytecodes::Code)opcode == Bytecodes::_getstatic) { + callee = cache->f1_as_method(); - UPDATE_PC_AND_CONTINUE(3); - } + // Profile call. + BI_PROFILE_UPDATE_CALL(); + }else { + // get receiver + int parms = cache->parameter_size(); + // this works but needs a resourcemark and seems to create a vtable on every call: + // Method* callee = rcvr->klass()->vtable()->method_at(cache->f2_as_index()); + // + // this fails with an assert + // InstanceKlass* rcvrKlass = InstanceKlass::cast(STACK_OBJECT(-parms)->klass()); + // but this works + oop rcvr = STACK_OBJECT(-parms); + VERIFY_OOP(rcvr); + InstanceKlass* rcvrKlass = (InstanceKlass*)rcvr->klass(); + /* + Executing this code in java.lang.String: + public String(char value[]) { + this.count = value.length; + this.value = (char[])value.clone(); + } + a find on rcvr->klass() reports: + {type array char}{type array class} + - klass: {other class} + but using InstanceKlass::cast(STACK_OBJECT(-parms)->klass()) causes in assertion failure + because rcvr->klass()->is_instance_klass() == 0 + However it seems to have a vtable in the right location. Huh? + Because vtables have the same offset for ArrayKlass and InstanceKlass. + */ + callee = (Method*) rcvrKlass->start_of_vtable()[ cache->f2_as_index()]; + // Profile virtual call. + BI_PROFILE_UPDATE_VIRTUALCALL(rcvr->klass()); + } + istate->set_callee(callee); + istate->set_callee_entry_point(callee->from_interpreted_entry()); +#ifdef VM_JVMTI + if (JvmtiExport::can_post_interpreter_events() && THREAD->is_interp_only_mode()) { + istate->set_callee_entry_point(callee->interpreter_entry()); + } +#endif /* VM_JVMTI */ + istate->set_bcp_advance(3); + UPDATE_PC_AND_RETURN(0); // I'll be back... + } + } CASE(_putfield): CASE(_putstatic): {