1 /*
   2  * Copyright (c) 2018, 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 SHARE_VM_RUNTIME_CONTINUATION_HPP
  26 #define SHARE_VM_RUNTIME_CONTINUATION_HPP
  27 
  28 #include "oops/oopsHierarchy.hpp"
  29 #include "runtime/frame.hpp"
  30 #include "runtime/globals.hpp"
  31 #include "jni.h"
  32 
  33 // #define CONT_DOUBLE_NOP 1
  34 
  35 #define CONT_FULL_STACK (!UseContinuationLazyCopy)
  36 
  37 // The order of this struct matters as it's directly manipulated by assembly code (push/pop)
  38 struct FrameInfo {
  39   address pc;
  40   intptr_t* fp;
  41   intptr_t* sp;
  42 };
  43 
  44 class Continuations : public AllStatic {
  45 private:
  46   static volatile intptr_t _exploded_miss;
  47   static volatile intptr_t _exploded_hit;
  48   static volatile intptr_t _nmethod_hit;
  49   static volatile intptr_t _nmethod_miss;
  50 
  51   static int _flags;
  52 public:
  53   static void exploded_miss();
  54   static void exploded_hit();
  55   static void nmethod_miss();
  56   static void nmethod_hit();
  57 
  58   static void print_statistics();
  59   static void init();
  60 
  61   static void cleanup_keepalives();
  62 
  63   static int flags() { return _flags; }
  64 };
  65 
  66 void continuations_init();
  67 
  68 class javaVFrame;
  69 class JavaThread;
  70 class OopStorage;
  71 
  72 class Continuation : AllStatic {
  73 private:
  74   static OopStorage* _weak_handles;
  75 public:
  76   static void init();
  77 
  78   static OopStorage* weak_storage() { return _weak_handles; }
  79 
  80   static int freeze(JavaThread* thread, FrameInfo* fi, bool from_interpreter);
  81   static int prepare_thaw(FrameInfo* fi, bool return_barrier);
  82   static address thaw_leaf(FrameInfo* fi, bool return_barrier, bool exception);
  83   static address thaw(JavaThread* thread, FrameInfo* fi, bool return_barrier, bool exception);
  84   static int try_force_yield(JavaThread* thread, oop cont);
  85 
  86   static oop  get_continutation_for_frame(JavaThread* thread, const frame& f);
  87   static bool is_continuation_entry_frame(const frame& f, const RegisterMap* map);
  88   static bool is_cont_post_barrier_entry_frame(const frame& f);
  89   static bool is_cont_barrier_frame(const frame& f);
  90   static bool is_return_barrier_entry(const address pc);
  91   static bool is_frame_in_continuation(const frame& f, oop cont);
  92   static bool is_frame_in_continuation(JavaThread* thread, const frame& f);
  93   static bool fix_continuation_bottom_sender(JavaThread* thread, const frame& callee, address* sender_pc, intptr_t** sender_sp);
  94   static bool fix_continuation_bottom_sender(RegisterMap* map, const frame& callee, address* sender_pc, intptr_t** sender_sp);
  95   static frame fix_continuation_bottom_sender(const frame& callee, RegisterMap* map, frame f);
  96   static address* get_continuation_entry_pc_for_sender(Thread* thread, const frame& f, address* pc_addr);
  97   static address get_top_return_pc_post_barrier(JavaThread* thread, address pc);
  98 
  99   static frame top_frame(const frame& callee, RegisterMap* map);
 100   static frame sender_for_interpreter_frame(const frame& callee, RegisterMap* map);
 101   static frame sender_for_compiled_frame(const frame& callee, RegisterMap* map);
 102   static int frame_size(const frame& f, const RegisterMap* map);
 103 
 104   static bool has_last_Java_frame(Handle continuation);
 105   static frame last_frame(Handle continuation, RegisterMap *map);
 106   static javaVFrame* last_java_vframe(Handle continuation, RegisterMap *map);
 107 
 108   // access frame data
 109   static bool is_in_usable_stack(address addr, const RegisterMap* map);
 110   static int usp_offset_to_index(const frame& fr, const RegisterMap* map, const int usp_offset_in_bytes);
 111   static address usp_offset_to_location(const frame& fr, const RegisterMap* map, const int usp_offset_in_bytes);
 112   static address usp_offset_to_location(const frame& fr, const RegisterMap* map, const int usp_offset_in_bytes, bool is_oop);
 113   static address reg_to_location(const frame& fr, const RegisterMap* map, VMReg reg);
 114   static address reg_to_location(const frame& fr, const RegisterMap* map, VMReg reg, bool is_oop);
 115   static address reg_to_location(oop cont, const frame& fr, const RegisterMap* map, VMReg reg, bool is_oop);
 116   static address interpreter_frame_expression_stack_at(const frame& fr, const RegisterMap* map, const InterpreterOopMap& oop_mask, int index);
 117   static address interpreter_frame_local_at(const frame& fr, const RegisterMap* map, const InterpreterOopMap& oop_mask, int index);
 118 
 119   static Method* interpreter_frame_method(const frame& fr, const RegisterMap* map);
 120   static address interpreter_frame_bcp(const frame& fr, const RegisterMap* map);
 121 
 122   static oop continuation_scope(oop cont);
 123   static bool is_scope_bottom(oop cont_scope, const frame& fr, const RegisterMap* map);
 124 
 125 #ifndef PRODUCT
 126   static void describe(FrameValues &values);
 127 #endif
 128 
 129   static void nmethod_patched(nmethod* nm);
 130 
 131 private:
 132   // declared here as it's used in friend declarations
 133   static address oop_address(objArrayOop ref_stack, int ref_sp, int index);
 134   static address oop_address(objArrayOop ref_stack, int ref_sp, address stack_address);
 135 };
 136 
 137 void CONT_RegisterNativeMethods(JNIEnv *env, jclass cls);
 138 
 139 #endif // SHARE_VM_RUNTIME_CONTINUATION_HPP