1 /*
   2  * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 
  25 #ifndef CPU_X86_HFRAME_X86_HPP
  26 #define CPU_X86_HFRAME_X86_HPP
  27 
  28 class hframe : public HFrameBase<hframe> {
  29 private:
  30   // additional fields beyond _sp and _pc:
  31   intptr_t _fp;
  32 
  33 public:
  34 
  35   typedef intptr_t** callee_info;
  36 
  37 public:
  38   hframe() : HFrameBase(), _fp(0) {}
  39 
  40   hframe(const hframe& hf) : HFrameBase(hf), _fp(hf._fp) {}
  41 
  42   hframe(int sp, int ref_sp, intptr_t fp, address pc, const ContMirror& cont) // called by ContMirror::last_frame
  43     : HFrameBase(sp, ref_sp, pc, cont), _fp(fp) {}
  44   
  45 
  46   hframe(int sp, int ref_sp, intptr_t fp, address pc, void* cb_md, bool is_interpreted) 
  47     : HFrameBase(sp, ref_sp, pc, cb_md, is_interpreted), _fp(fp) {}
  48 
  49   inline bool operator==(const hframe& other) const;
  50 
  51   void copy_partial_pd(const hframe& other) {
  52     _fp = other._fp;
  53   } 
  54 
  55   inline intptr_t  fp()     const { return _fp; }
  56 
  57   inline void set_fp(intptr_t fp) { _fp = fp; }
  58 
  59   const CodeBlob* get_cb() const;
  60   const ImmutableOopMap* get_oop_map() const;
  61 
  62   inline int callee_link_index() const;
  63   inline int pc_index() const;
  64 
  65   inline address real_pc(const ContMirror& cont) const;
  66 
  67   inline intptr_t* interpreted_link_address() const { assert (Interpreter::contains(_pc), ""); return (intptr_t*)_cb_imd; }
  68 
  69   static intptr_t* interpreted_link_address(intptr_t fp, const ContMirror& cont);
  70 
  71   inline void patch_interpreter_metadata_offset(int offset, intptr_t value);
  72   inline intptr_t* interpreter_frame_metadata_at(int offset) const;
  73 
  74   inline void patch_interpreted_link(intptr_t value);
  75   inline void patch_interpreted_link_relative(intptr_t fp);
  76 
  77   inline void patch_callee_link(intptr_t value, const ContMirror& cont) const;
  78   inline void patch_callee_link_relative(intptr_t fp, const ContMirror& cont) const;
  79 
  80   inline void patch_sender_sp_relative(intptr_t* value);
  81 
  82   template<typename FKind> inline address* return_pc_address() const;
  83 
  84   template<typename FKind> int frame_bottom_index() const;
  85 
  86   using HFrameBase<hframe>::sender; // unhide overloaded
  87   template<typename FKind, op_mode mode> hframe sender(const ContMirror& cont, int num_oops) const;
  88 
  89   DEBUG_ONLY(int interpreted_frame_top_index() const;)
  90   int interpreted_frame_num_monitors() const;
  91   void interpreted_frame_oop_map(InterpreterOopMap* mask) const;
  92 
  93   address interpreter_frame_bcp() const;
  94   intptr_t* interpreter_frame_local_at(int index) const;
  95   intptr_t* interpreter_frame_expression_stack_at(int offset) const;
  96 
  97   template<typename FKind> Method* method() const;
  98 
  99   using HFrameBase<hframe>::to_frame; // unhide overloaded
 100   inline frame to_frame(ContMirror& cont, address pd, bool deopt) const;
 101 
 102   void print_on(const ContMirror& cont, outputStream* st) const;
 103   void print_on(outputStream* st) const ;
 104 };
 105 
 106 template<>
 107 Method* hframe::method<Interpreted>() const {
 108   assert (_is_interpreted, "");
 109   return *(Method**)interpreter_frame_metadata_at(frame::interpreter_frame_method_offset);
 110 }
 111 
 112 #ifdef CONT_DOUBLE_NOP
 113 
 114 // TODO R move to continuation_x86.inline.hpp once PD has been separated
 115 
 116 const int mdSizeBits    = 13;
 117 const int mdOopBits     = 14;
 118 const int mdArgsizeBits = 5;
 119 STATIC_ASSERT(mdSizeBits + mdOopBits + mdArgsizeBits == 32);
 120 
 121 class CachedCompiledMetadata {
 122 private:
 123   union {
 124     struct {
 125       uint _size    : mdSizeBits; // in DWORDS
 126       uint _oops    : mdOopBits;
 127       uint _argsize : mdArgsizeBits;
 128     };
 129     uint32_t _int1;
 130   };
 131 
 132 public:
 133   CachedCompiledMetadata() {}
 134   CachedCompiledMetadata(uint32_t int1) { _int1 = int1; }
 135   CachedCompiledMetadata(int size, int oops, int argsize) {
 136     assert (size % 8 == 0, "");
 137     size >>= LogBytesPerWord;
 138     if (size <= ((1 << mdSizeBits) - 1) && oops <= ((1 << mdOopBits) - 1) && argsize <= ((1 << mdArgsizeBits) - 1)) {
 139       _size = size;
 140       _oops = oops;
 141       _argsize = argsize;
 142     } else {
 143       tty->print_cr(">> metadata failed: size: %d oops: %d argsize: %d", size, oops, argsize);
 144       _int1 = 0;
 145     }
 146   }
 147 
 148   bool empty()        const { return _size == 0; }
 149   int size()          const { return ((int)_size) << LogBytesPerWord; }
 150   int size_words()    const { return (int)_size; }
 151   int num_oops()      const { return (int)_oops; }
 152   int stack_argsize() const { return (int)_argsize; }
 153 
 154   uint32_t int1() const { return _int1; }
 155 
 156   void print_on(outputStream* st) { st->print("size: %d args: %d oops: %d", size(), stack_argsize(), num_oops()); }
 157   void print() { print_on(tty); }
 158 };
 159 
 160 STATIC_ASSERT(sizeof(CachedCompiledMetadata) == 4);
 161 
 162 #endif
 163 
 164 #endif // CPU_X86_HFRAME_X86_HPP