< 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 >