< prev index next >
src/share/vm/interpreter/bytecodeInterpreter.cpp
Print this page
@@ -1945,10 +1945,11 @@
CALL_VM(InterpreterRuntime::resolve_from_cache(THREAD, (Bytecodes::Code)opcode),
handle_exception);
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
@@ -2030,12 +2031,61 @@
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();
+ // 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):
{
u2 index = Bytes::get_native_u2(pc+1);
ConstantPoolCacheEntry* cache = cp->entry_at(index);
< prev index next >