src/cpu/zero/vm/frame_zero.cpp

Fri, 11 Jan 2013 16:47:23 -0800

author
twisti
date
Fri, 11 Jan 2013 16:47:23 -0800
changeset 4442
c566b81b3323
parent 4237
a3e2f723f2a5
child 5545
e16282db4946
permissions
-rw-r--r--

8005817: Shark: implement deoptimization support
Reviewed-by: twisti
Contributed-by: Roman Kennke <rkennke@redhat.com>

     1 /*
     2  * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
     3  * Copyright 2007, 2008, 2009, 2010, 2011 Red Hat, Inc.
     4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     5  *
     6  * This code is free software; you can redistribute it and/or modify it
     7  * under the terms of the GNU General Public License version 2 only, as
     8  * published by the Free Software Foundation.
     9  *
    10  * This code is distributed in the hope that it will be useful, but WITHOUT
    11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    12  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    13  * version 2 for more details (a copy is included in the LICENSE file that
    14  * accompanied this code).
    15  *
    16  * You should have received a copy of the GNU General Public License version
    17  * 2 along with this work; if not, write to the Free Software Foundation,
    18  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    19  *
    20  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    21  * or visit www.oracle.com if you need additional information or have any
    22  * questions.
    23  *
    24  */
    26 #include "precompiled.hpp"
    27 #include "code/scopeDesc.hpp"
    28 #include "interpreter/interpreter.hpp"
    29 #include "interpreter/interpreterRuntime.hpp"
    30 #include "memory/resourceArea.hpp"
    31 #include "oops/markOop.hpp"
    32 #include "oops/method.hpp"
    33 #include "oops/oop.inline.hpp"
    34 #include "runtime/frame.inline.hpp"
    35 #include "runtime/handles.inline.hpp"
    36 #include "runtime/javaCalls.hpp"
    37 #include "runtime/monitorChunk.hpp"
    38 #include "runtime/signature.hpp"
    39 #include "runtime/stubCodeGenerator.hpp"
    40 #include "runtime/stubRoutines.hpp"
    41 #include "vmreg_zero.inline.hpp"
    42 #ifdef COMPILER1
    43 #include "c1/c1_Runtime1.hpp"
    44 #include "runtime/vframeArray.hpp"
    45 #endif
    47 #ifdef ASSERT
    48 void RegisterMap::check_location_valid() {
    49   ShouldNotCallThis();
    50 }
    51 #endif
    53 bool frame::is_interpreted_frame() const {
    54   return zeroframe()->is_interpreter_frame();
    55 }
    57 bool frame::is_fake_stub_frame() const {
    58   return zeroframe()->is_fake_stub_frame();
    59 }
    61 frame frame::sender_for_entry_frame(RegisterMap *map) const {
    62   assert(zeroframe()->is_entry_frame(), "wrong type of frame");
    63   assert(map != NULL, "map must be set");
    64   assert(!entry_frame_is_first(), "next Java fp must be non zero");
    65   assert(entry_frame_call_wrapper()->anchor()->last_Java_sp() == sender_sp(),
    66          "sender should be next Java frame");
    67   map->clear();
    68   assert(map->include_argument_oops(), "should be set by clear");
    69   return frame(zeroframe()->next(), sender_sp());
    70 }
    72 frame frame::sender_for_nonentry_frame(RegisterMap *map) const {
    73   assert(zeroframe()->is_interpreter_frame() ||
    74          zeroframe()->is_shark_frame() ||
    75          zeroframe()->is_fake_stub_frame(), "wrong type of frame");
    76   return frame(zeroframe()->next(), sender_sp());
    77 }
    79 frame frame::sender(RegisterMap* map) const {
    80   // Default is not to follow arguments; the various
    81   // sender_for_xxx methods update this accordingly.
    82   map->set_include_argument_oops(false);
    84   if (is_entry_frame())
    85     return sender_for_entry_frame(map);
    86   else
    87     return sender_for_nonentry_frame(map);
    88 }
    90 #ifdef CC_INTERP
    91 BasicObjectLock* frame::interpreter_frame_monitor_begin() const {
    92   return get_interpreterState()->monitor_base();
    93 }
    95 BasicObjectLock* frame::interpreter_frame_monitor_end() const {
    96   return (BasicObjectLock*) get_interpreterState()->stack_base();
    97 }
    98 #endif // CC_INTERP
   100 void frame::patch_pc(Thread* thread, address pc) {
   102   if (pc != NULL) {
   103     _cb = CodeCache::find_blob(pc);
   104     SharkFrame* sharkframe = zeroframe()->as_shark_frame();
   105     sharkframe->set_pc(pc);
   106     _pc = pc;
   107     _deopt_state = is_deoptimized;
   109   } else {
   110     // We borrow this call to set the thread pointer in the interpreter
   111     // state; the hook to set up deoptimized frames isn't supplied it.
   112     assert(pc == NULL, "should be");
   113     get_interpreterState()->set_thread((JavaThread *) thread);
   114   }
   115 }
   117 bool frame::safe_for_sender(JavaThread *thread) {
   118   ShouldNotCallThis();
   119 }
   121 void frame::pd_gc_epilog() {
   122 }
   124 bool frame::is_interpreted_frame_valid(JavaThread *thread) const {
   125   ShouldNotCallThis();
   126 }
   128 BasicType frame::interpreter_frame_result(oop* oop_result,
   129                                           jvalue* value_result) {
   130   assert(is_interpreted_frame(), "interpreted frame expected");
   131   Method* method = interpreter_frame_method();
   132   BasicType type = method->result_type();
   133   intptr_t* tos_addr = (intptr_t *) interpreter_frame_tos_address();
   134   oop obj;
   136   switch (type) {
   137   case T_VOID:
   138     break;
   139   case T_BOOLEAN:
   140     value_result->z = *(jboolean *) tos_addr;
   141     break;
   142   case T_BYTE:
   143     value_result->b = *(jbyte *) tos_addr;
   144     break;
   145   case T_CHAR:
   146     value_result->c = *(jchar *) tos_addr;
   147     break;
   148   case T_SHORT:
   149     value_result->s = *(jshort *) tos_addr;
   150     break;
   151   case T_INT:
   152     value_result->i = *(jint *) tos_addr;
   153     break;
   154   case T_LONG:
   155     value_result->j = *(jlong *) tos_addr;
   156     break;
   157   case T_FLOAT:
   158     value_result->f = *(jfloat *) tos_addr;
   159     break;
   160   case T_DOUBLE:
   161     value_result->d = *(jdouble *) tos_addr;
   162     break;
   164   case T_OBJECT:
   165   case T_ARRAY:
   166     if (method->is_native()) {
   167       obj = get_interpreterState()->oop_temp();
   168     }
   169     else {
   170       oop* obj_p = (oop *) tos_addr;
   171       obj = (obj_p == NULL) ? (oop) NULL : *obj_p;
   172     }
   173     assert(obj == NULL || Universe::heap()->is_in(obj), "sanity check");
   174     *oop_result = obj;
   175     break;
   177   default:
   178     ShouldNotReachHere();
   179   }
   181   return type;
   182 }
   184 int frame::frame_size(RegisterMap* map) const {
   185 #ifdef PRODUCT
   186   ShouldNotCallThis();
   187 #else
   188   return 0; // make javaVFrame::print_value work
   189 #endif // PRODUCT
   190 }
   192 intptr_t* frame::interpreter_frame_tos_at(jint offset) const {
   193   int index = (Interpreter::expr_offset_in_bytes(offset) / wordSize);
   194   return &interpreter_frame_tos_address()[index];
   195 }
   197 void frame::zero_print_on_error(int           frame_index,
   198                                 outputStream* st,
   199                                 char*         buf,
   200                                 int           buflen) const {
   201   // Divide the buffer between the field and the value
   202   buflen >>= 1;
   203   char *fieldbuf = buf;
   204   char *valuebuf = buf + buflen;
   206   // Print each word of the frame
   207   for (intptr_t *addr = sp(); addr <= fp(); addr++) {
   208     int offset = fp() - addr;
   210     // Fill in default values, then try and improve them
   211     snprintf(fieldbuf, buflen, "word[%d]", offset);
   212     snprintf(valuebuf, buflen, PTR_FORMAT, *addr);
   213     zeroframe()->identify_word(frame_index, offset, fieldbuf, valuebuf, buflen);
   214     fieldbuf[buflen - 1] = '\0';
   215     valuebuf[buflen - 1] = '\0';
   217     // Print the result
   218     st->print_cr(" " PTR_FORMAT ": %-21s = %s", addr, fieldbuf, valuebuf);
   219   }
   220 }
   222 void ZeroFrame::identify_word(int   frame_index,
   223                               int   offset,
   224                               char* fieldbuf,
   225                               char* valuebuf,
   226                               int   buflen) const {
   227   switch (offset) {
   228   case next_frame_off:
   229     strncpy(fieldbuf, "next_frame", buflen);
   230     break;
   232   case frame_type_off:
   233     strncpy(fieldbuf, "frame_type", buflen);
   234     if (is_entry_frame())
   235       strncpy(valuebuf, "ENTRY_FRAME", buflen);
   236     else if (is_interpreter_frame())
   237       strncpy(valuebuf, "INTERPRETER_FRAME", buflen);
   238     else if (is_shark_frame())
   239       strncpy(valuebuf, "SHARK_FRAME", buflen);
   240     else if (is_fake_stub_frame())
   241       strncpy(valuebuf, "FAKE_STUB_FRAME", buflen);
   242     break;
   244   default:
   245     if (is_entry_frame()) {
   246       as_entry_frame()->identify_word(
   247         frame_index, offset, fieldbuf, valuebuf, buflen);
   248     }
   249     else if (is_interpreter_frame()) {
   250       as_interpreter_frame()->identify_word(
   251         frame_index, offset, fieldbuf, valuebuf, buflen);
   252     }
   253     else if (is_shark_frame()) {
   254       as_shark_frame()->identify_word(
   255         frame_index, offset, fieldbuf, valuebuf, buflen);
   256     }
   257     else if (is_fake_stub_frame()) {
   258       as_fake_stub_frame()->identify_word(
   259         frame_index, offset, fieldbuf, valuebuf, buflen);
   260     }
   261   }
   262 }
   264 void EntryFrame::identify_word(int   frame_index,
   265                                int   offset,
   266                                char* fieldbuf,
   267                                char* valuebuf,
   268                                int   buflen) const {
   269   switch (offset) {
   270   case call_wrapper_off:
   271     strncpy(fieldbuf, "call_wrapper", buflen);
   272     break;
   274   default:
   275     snprintf(fieldbuf, buflen, "local[%d]", offset - 3);
   276   }
   277 }
   279 void InterpreterFrame::identify_word(int   frame_index,
   280                                      int   offset,
   281                                      char* fieldbuf,
   282                                      char* valuebuf,
   283                                      int   buflen) const {
   284   interpreterState istate = interpreter_state();
   285   bool is_valid = istate->self_link() == istate;
   286   intptr_t *addr = addr_of_word(offset);
   288   // Fixed part
   289   if (addr >= (intptr_t *) istate) {
   290     const char *field = istate->name_of_field_at_address((address) addr);
   291     if (field) {
   292       if (is_valid && !strcmp(field, "_method")) {
   293         istate->method()->name_and_sig_as_C_string(valuebuf, buflen);
   294       }
   295       else if (is_valid && !strcmp(field, "_bcp") && istate->bcp()) {
   296         snprintf(valuebuf, buflen, PTR_FORMAT " (bci %d)",
   297                  (intptr_t) istate->bcp(),
   298                  istate->method()->bci_from(istate->bcp()));
   299       }
   300       snprintf(fieldbuf, buflen, "%sistate->%s",
   301                field[strlen(field) - 1] == ')' ? "(": "", field);
   302     }
   303     else if (addr == (intptr_t *) istate) {
   304       strncpy(fieldbuf, "(vtable for istate)", buflen);
   305     }
   306     return;
   307   }
   309   // Variable part
   310   if (!is_valid)
   311     return;
   313   // JNI stuff
   314   if (istate->method()->is_native() && addr < istate->stack_base()) {
   315     address hA = istate->method()->signature_handler();
   316     if (hA != NULL) {
   317       if (hA != (address) InterpreterRuntime::slow_signature_handler) {
   318         InterpreterRuntime::SignatureHandler *handler =
   319           InterpreterRuntime::SignatureHandler::from_handlerAddr(hA);
   321         intptr_t *params = istate->stack_base() - handler->argument_count();
   322         if (addr >= params) {
   323           int param = addr - params;
   324           const char *desc = "";
   325           if (param == 0)
   326             desc = " (JNIEnv)";
   327           else if (param == 1) {
   328             if (istate->method()->is_static())
   329               desc = " (mirror)";
   330             else
   331               desc = " (this)";
   332           }
   333           snprintf(fieldbuf, buflen, "parameter[%d]%s", param, desc);
   334           return;
   335         }
   337         for (int i = 0; i < handler->argument_count(); i++) {
   338           if (params[i] == (intptr_t) addr) {
   339             snprintf(fieldbuf, buflen, "unboxed parameter[%d]", i);
   340             return;
   341           }
   342         }
   343       }
   344     }
   345     return;
   346   }
   348   // Monitors and stack
   349   identify_vp_word(frame_index, addr,
   350                    (intptr_t *) istate->monitor_base(),
   351                    istate->stack_base(),
   352                    fieldbuf, buflen);
   353 }
   355 void SharkFrame::identify_word(int   frame_index,
   356                                int   offset,
   357                                char* fieldbuf,
   358                                char* valuebuf,
   359                                int   buflen) const {
   360   // Fixed part
   361   switch (offset) {
   362   case pc_off:
   363     strncpy(fieldbuf, "pc", buflen);
   364     if (method()->is_method()) {
   365       nmethod *code = method()->code();
   366       if (code && code->pc_desc_at(pc())) {
   367         SimpleScopeDesc ssd(code, pc());
   368         snprintf(valuebuf, buflen, PTR_FORMAT " (bci %d)",
   369                  (intptr_t) pc(), ssd.bci());
   370       }
   371     }
   372     return;
   374   case unextended_sp_off:
   375     strncpy(fieldbuf, "unextended_sp", buflen);
   376     return;
   378   case method_off:
   379     strncpy(fieldbuf, "method", buflen);
   380     if (method()->is_method()) {
   381       method()->name_and_sig_as_C_string(valuebuf, buflen);
   382     }
   383     return;
   385   case oop_tmp_off:
   386     strncpy(fieldbuf, "oop_tmp", buflen);
   387     return;
   388   }
   390   // Variable part
   391   if (method()->is_method()) {
   392     identify_vp_word(frame_index, addr_of_word(offset),
   393                      addr_of_word(header_words + 1),
   394                      unextended_sp() + method()->max_stack(),
   395                      fieldbuf, buflen);
   396   }
   397 }
   399 void ZeroFrame::identify_vp_word(int       frame_index,
   400                                  intptr_t* addr,
   401                                  intptr_t* monitor_base,
   402                                  intptr_t* stack_base,
   403                                  char*     fieldbuf,
   404                                  int       buflen) const {
   405   // Monitors
   406   if (addr >= stack_base && addr < monitor_base) {
   407     int monitor_size = frame::interpreter_frame_monitor_size();
   408     int last_index = (monitor_base - stack_base) / monitor_size - 1;
   409     int index = last_index - (addr - stack_base) / monitor_size;
   410     intptr_t monitor = (intptr_t) (
   411       (BasicObjectLock *) monitor_base - 1 - index);
   412     intptr_t offset = (intptr_t) addr - monitor;
   414     if (offset == BasicObjectLock::obj_offset_in_bytes())
   415       snprintf(fieldbuf, buflen, "monitor[%d]->_obj", index);
   416     else if (offset ==  BasicObjectLock::lock_offset_in_bytes())
   417       snprintf(fieldbuf, buflen, "monitor[%d]->_lock", index);
   419     return;
   420   }
   422   // Expression stack
   423   if (addr < stack_base) {
   424     snprintf(fieldbuf, buflen, "%s[%d]",
   425              frame_index == 0 ? "stack_word" : "local",
   426              (int) (stack_base - addr - 1));
   427     return;
   428   }
   429 }
   431 #ifndef PRODUCT
   433 void frame::describe_pd(FrameValues& values, int frame_no) {
   435 }
   437 #endif
   439 intptr_t *frame::initial_deoptimization_info() {
   440   // unused... but returns fp() to minimize changes introduced by 7087445
   441   return fp();
   442 }

mercurial