src/cpu/zero/vm/frame_zero.cpp

Tue, 20 Aug 2013 10:57:50 -0700

author
twisti
date
Tue, 20 Aug 2013 10:57:50 -0700
changeset 5545
e16282db4946
parent 4442
c566b81b3323
child 6198
55fb97c4c58d
permissions
-rw-r--r--

8022956: Clang: enable return type warnings on BSD
Reviewed-by: coleenp, sla

     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   return false;
   120 }
   122 void frame::pd_gc_epilog() {
   123 }
   125 bool frame::is_interpreted_frame_valid(JavaThread *thread) const {
   126   ShouldNotCallThis();
   127   return false;
   128 }
   130 BasicType frame::interpreter_frame_result(oop* oop_result,
   131                                           jvalue* value_result) {
   132   assert(is_interpreted_frame(), "interpreted frame expected");
   133   Method* method = interpreter_frame_method();
   134   BasicType type = method->result_type();
   135   intptr_t* tos_addr = (intptr_t *) interpreter_frame_tos_address();
   136   oop obj;
   138   switch (type) {
   139   case T_VOID:
   140     break;
   141   case T_BOOLEAN:
   142     value_result->z = *(jboolean *) tos_addr;
   143     break;
   144   case T_BYTE:
   145     value_result->b = *(jbyte *) tos_addr;
   146     break;
   147   case T_CHAR:
   148     value_result->c = *(jchar *) tos_addr;
   149     break;
   150   case T_SHORT:
   151     value_result->s = *(jshort *) tos_addr;
   152     break;
   153   case T_INT:
   154     value_result->i = *(jint *) tos_addr;
   155     break;
   156   case T_LONG:
   157     value_result->j = *(jlong *) tos_addr;
   158     break;
   159   case T_FLOAT:
   160     value_result->f = *(jfloat *) tos_addr;
   161     break;
   162   case T_DOUBLE:
   163     value_result->d = *(jdouble *) tos_addr;
   164     break;
   166   case T_OBJECT:
   167   case T_ARRAY:
   168     if (method->is_native()) {
   169       obj = get_interpreterState()->oop_temp();
   170     }
   171     else {
   172       oop* obj_p = (oop *) tos_addr;
   173       obj = (obj_p == NULL) ? (oop) NULL : *obj_p;
   174     }
   175     assert(obj == NULL || Universe::heap()->is_in(obj), "sanity check");
   176     *oop_result = obj;
   177     break;
   179   default:
   180     ShouldNotReachHere();
   181   }
   183   return type;
   184 }
   186 int frame::frame_size(RegisterMap* map) const {
   187 #ifdef PRODUCT
   188   ShouldNotCallThis();
   189 #endif // PRODUCT
   190   return 0; // make javaVFrame::print_value work
   191 }
   193 intptr_t* frame::interpreter_frame_tos_at(jint offset) const {
   194   int index = (Interpreter::expr_offset_in_bytes(offset) / wordSize);
   195   return &interpreter_frame_tos_address()[index];
   196 }
   198 void frame::zero_print_on_error(int           frame_index,
   199                                 outputStream* st,
   200                                 char*         buf,
   201                                 int           buflen) const {
   202   // Divide the buffer between the field and the value
   203   buflen >>= 1;
   204   char *fieldbuf = buf;
   205   char *valuebuf = buf + buflen;
   207   // Print each word of the frame
   208   for (intptr_t *addr = sp(); addr <= fp(); addr++) {
   209     int offset = fp() - addr;
   211     // Fill in default values, then try and improve them
   212     snprintf(fieldbuf, buflen, "word[%d]", offset);
   213     snprintf(valuebuf, buflen, PTR_FORMAT, *addr);
   214     zeroframe()->identify_word(frame_index, offset, fieldbuf, valuebuf, buflen);
   215     fieldbuf[buflen - 1] = '\0';
   216     valuebuf[buflen - 1] = '\0';
   218     // Print the result
   219     st->print_cr(" " PTR_FORMAT ": %-21s = %s", addr, fieldbuf, valuebuf);
   220   }
   221 }
   223 void ZeroFrame::identify_word(int   frame_index,
   224                               int   offset,
   225                               char* fieldbuf,
   226                               char* valuebuf,
   227                               int   buflen) const {
   228   switch (offset) {
   229   case next_frame_off:
   230     strncpy(fieldbuf, "next_frame", buflen);
   231     break;
   233   case frame_type_off:
   234     strncpy(fieldbuf, "frame_type", buflen);
   235     if (is_entry_frame())
   236       strncpy(valuebuf, "ENTRY_FRAME", buflen);
   237     else if (is_interpreter_frame())
   238       strncpy(valuebuf, "INTERPRETER_FRAME", buflen);
   239     else if (is_shark_frame())
   240       strncpy(valuebuf, "SHARK_FRAME", buflen);
   241     else if (is_fake_stub_frame())
   242       strncpy(valuebuf, "FAKE_STUB_FRAME", buflen);
   243     break;
   245   default:
   246     if (is_entry_frame()) {
   247       as_entry_frame()->identify_word(
   248         frame_index, offset, fieldbuf, valuebuf, buflen);
   249     }
   250     else if (is_interpreter_frame()) {
   251       as_interpreter_frame()->identify_word(
   252         frame_index, offset, fieldbuf, valuebuf, buflen);
   253     }
   254     else if (is_shark_frame()) {
   255       as_shark_frame()->identify_word(
   256         frame_index, offset, fieldbuf, valuebuf, buflen);
   257     }
   258     else if (is_fake_stub_frame()) {
   259       as_fake_stub_frame()->identify_word(
   260         frame_index, offset, fieldbuf, valuebuf, buflen);
   261     }
   262   }
   263 }
   265 void EntryFrame::identify_word(int   frame_index,
   266                                int   offset,
   267                                char* fieldbuf,
   268                                char* valuebuf,
   269                                int   buflen) const {
   270   switch (offset) {
   271   case call_wrapper_off:
   272     strncpy(fieldbuf, "call_wrapper", buflen);
   273     break;
   275   default:
   276     snprintf(fieldbuf, buflen, "local[%d]", offset - 3);
   277   }
   278 }
   280 void InterpreterFrame::identify_word(int   frame_index,
   281                                      int   offset,
   282                                      char* fieldbuf,
   283                                      char* valuebuf,
   284                                      int   buflen) const {
   285   interpreterState istate = interpreter_state();
   286   bool is_valid = istate->self_link() == istate;
   287   intptr_t *addr = addr_of_word(offset);
   289   // Fixed part
   290   if (addr >= (intptr_t *) istate) {
   291     const char *field = istate->name_of_field_at_address((address) addr);
   292     if (field) {
   293       if (is_valid && !strcmp(field, "_method")) {
   294         istate->method()->name_and_sig_as_C_string(valuebuf, buflen);
   295       }
   296       else if (is_valid && !strcmp(field, "_bcp") && istate->bcp()) {
   297         snprintf(valuebuf, buflen, PTR_FORMAT " (bci %d)",
   298                  (intptr_t) istate->bcp(),
   299                  istate->method()->bci_from(istate->bcp()));
   300       }
   301       snprintf(fieldbuf, buflen, "%sistate->%s",
   302                field[strlen(field) - 1] == ')' ? "(": "", field);
   303     }
   304     else if (addr == (intptr_t *) istate) {
   305       strncpy(fieldbuf, "(vtable for istate)", buflen);
   306     }
   307     return;
   308   }
   310   // Variable part
   311   if (!is_valid)
   312     return;
   314   // JNI stuff
   315   if (istate->method()->is_native() && addr < istate->stack_base()) {
   316     address hA = istate->method()->signature_handler();
   317     if (hA != NULL) {
   318       if (hA != (address) InterpreterRuntime::slow_signature_handler) {
   319         InterpreterRuntime::SignatureHandler *handler =
   320           InterpreterRuntime::SignatureHandler::from_handlerAddr(hA);
   322         intptr_t *params = istate->stack_base() - handler->argument_count();
   323         if (addr >= params) {
   324           int param = addr - params;
   325           const char *desc = "";
   326           if (param == 0)
   327             desc = " (JNIEnv)";
   328           else if (param == 1) {
   329             if (istate->method()->is_static())
   330               desc = " (mirror)";
   331             else
   332               desc = " (this)";
   333           }
   334           snprintf(fieldbuf, buflen, "parameter[%d]%s", param, desc);
   335           return;
   336         }
   338         for (int i = 0; i < handler->argument_count(); i++) {
   339           if (params[i] == (intptr_t) addr) {
   340             snprintf(fieldbuf, buflen, "unboxed parameter[%d]", i);
   341             return;
   342           }
   343         }
   344       }
   345     }
   346     return;
   347   }
   349   // Monitors and stack
   350   identify_vp_word(frame_index, addr,
   351                    (intptr_t *) istate->monitor_base(),
   352                    istate->stack_base(),
   353                    fieldbuf, buflen);
   354 }
   356 void SharkFrame::identify_word(int   frame_index,
   357                                int   offset,
   358                                char* fieldbuf,
   359                                char* valuebuf,
   360                                int   buflen) const {
   361   // Fixed part
   362   switch (offset) {
   363   case pc_off:
   364     strncpy(fieldbuf, "pc", buflen);
   365     if (method()->is_method()) {
   366       nmethod *code = method()->code();
   367       if (code && code->pc_desc_at(pc())) {
   368         SimpleScopeDesc ssd(code, pc());
   369         snprintf(valuebuf, buflen, PTR_FORMAT " (bci %d)",
   370                  (intptr_t) pc(), ssd.bci());
   371       }
   372     }
   373     return;
   375   case unextended_sp_off:
   376     strncpy(fieldbuf, "unextended_sp", buflen);
   377     return;
   379   case method_off:
   380     strncpy(fieldbuf, "method", buflen);
   381     if (method()->is_method()) {
   382       method()->name_and_sig_as_C_string(valuebuf, buflen);
   383     }
   384     return;
   386   case oop_tmp_off:
   387     strncpy(fieldbuf, "oop_tmp", buflen);
   388     return;
   389   }
   391   // Variable part
   392   if (method()->is_method()) {
   393     identify_vp_word(frame_index, addr_of_word(offset),
   394                      addr_of_word(header_words + 1),
   395                      unextended_sp() + method()->max_stack(),
   396                      fieldbuf, buflen);
   397   }
   398 }
   400 void ZeroFrame::identify_vp_word(int       frame_index,
   401                                  intptr_t* addr,
   402                                  intptr_t* monitor_base,
   403                                  intptr_t* stack_base,
   404                                  char*     fieldbuf,
   405                                  int       buflen) const {
   406   // Monitors
   407   if (addr >= stack_base && addr < monitor_base) {
   408     int monitor_size = frame::interpreter_frame_monitor_size();
   409     int last_index = (monitor_base - stack_base) / monitor_size - 1;
   410     int index = last_index - (addr - stack_base) / monitor_size;
   411     intptr_t monitor = (intptr_t) (
   412       (BasicObjectLock *) monitor_base - 1 - index);
   413     intptr_t offset = (intptr_t) addr - monitor;
   415     if (offset == BasicObjectLock::obj_offset_in_bytes())
   416       snprintf(fieldbuf, buflen, "monitor[%d]->_obj", index);
   417     else if (offset ==  BasicObjectLock::lock_offset_in_bytes())
   418       snprintf(fieldbuf, buflen, "monitor[%d]->_lock", index);
   420     return;
   421   }
   423   // Expression stack
   424   if (addr < stack_base) {
   425     snprintf(fieldbuf, buflen, "%s[%d]",
   426              frame_index == 0 ? "stack_word" : "local",
   427              (int) (stack_base - addr - 1));
   428     return;
   429   }
   430 }
   432 #ifndef PRODUCT
   434 void frame::describe_pd(FrameValues& values, int frame_no) {
   436 }
   438 #endif
   440 intptr_t *frame::initial_deoptimization_info() {
   441   // unused... but returns fp() to minimize changes introduced by 7087445
   442   return fp();
   443 }

mercurial