1 /*
   2  * Copyright (c) 2011, 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 #ifndef SHARE_JVMCI_JVMCICOMPILERTOVM_HPP
  25 #define SHARE_JVMCI_JVMCICOMPILERTOVM_HPP
  26 
  27 #include "jni.h"
  28 #include "runtime/javaCalls.hpp"
  29 #include "jvmci/jvmciJavaClasses.hpp"
  30 
  31 // Helper class to ensure that references to Klass* are kept alive for G1
  32 class JVMCIKlassHandle : public StackObj {
  33  private:
  34   Klass*     _klass;
  35   Handle     _holder;
  36   Thread*    _thread;
  37 
  38   Klass*        klass() const                     { return _klass; }
  39   Klass*        non_null_klass() const            { assert(_klass != NULL, "resolving NULL _klass"); return _klass; }
  40 
  41  public:
  42   /* Constructors */
  43   JVMCIKlassHandle (Thread* thread) : _klass(NULL), _thread(thread) {}
  44   JVMCIKlassHandle (Thread* thread, Klass* klass);
  45 
  46   JVMCIKlassHandle (const JVMCIKlassHandle &h): _klass(h._klass), _holder(h._holder), _thread(h._thread) {}
  47   JVMCIKlassHandle& operator=(const JVMCIKlassHandle &s);
  48   JVMCIKlassHandle& operator=(Klass* klass);
  49 
  50   /* Operators for ease of use */
  51   Klass*        operator () () const            { return klass(); }
  52   Klass*        operator -> () const            { return non_null_klass(); }
  53 
  54   bool    operator == (Klass* o) const          { return klass() == o; }
  55   bool    operator == (const JVMCIKlassHandle& h) const  { return klass() == h.klass(); }
  56 
  57   /* Null checks */
  58   bool    is_null() const                      { return _klass == NULL; }
  59   bool    not_null() const                     { return _klass != NULL; }
  60 };
  61 
  62 class CompilerToVM {
  63  public:
  64   class Data {
  65     friend class JVMCIVMStructs;
  66 
  67    private:
  68     static int Klass_vtable_start_offset;
  69     static int Klass_vtable_length_offset;
  70 
  71     static int Method_extra_stack_entries;
  72 
  73     static address SharedRuntime_ic_miss_stub;
  74     static address SharedRuntime_handle_wrong_method_stub;
  75     static address SharedRuntime_deopt_blob_unpack;
  76     static address SharedRuntime_deopt_blob_uncommon_trap;
  77 
  78     static size_t ThreadLocalAllocBuffer_alignment_reserve;
  79 
  80     static CollectedHeap* Universe_collectedHeap;
  81     static int Universe_base_vtable_size;
  82     static address Universe_narrow_oop_base;
  83     static int Universe_narrow_oop_shift;
  84     static address Universe_narrow_klass_base;
  85     static int Universe_narrow_klass_shift;
  86     static uintptr_t Universe_verify_oop_mask;
  87     static uintptr_t Universe_verify_oop_bits;
  88     static void* Universe_non_oop_bits;
  89 
  90     static bool _supports_inline_contig_alloc;
  91     static HeapWord** _heap_end_addr;
  92     static HeapWord* volatile* _heap_top_addr;
  93     static int _max_oop_map_stack_offset;
  94     static int _fields_annotations_base_offset;
  95 
  96     static CardTable::CardValue* cardtable_start_address;
  97     static int cardtable_shift;
  98 
  99     static int vm_page_size;
 100 
 101     static int sizeof_vtableEntry;
 102     static int sizeof_ExceptionTableElement;
 103     static int sizeof_LocalVariableTableElement;
 104     static int sizeof_ConstantPool;
 105     static int sizeof_narrowKlass;
 106     static int sizeof_arrayOopDesc;
 107     static int sizeof_BasicLock;
 108 
 109     static address dsin;
 110     static address dcos;
 111     static address dtan;
 112     static address dexp;
 113     static address dlog;
 114     static address dlog10;
 115     static address dpow;
 116 
 117     static address symbol_init;
 118     static address symbol_clinit;
 119 
 120    public:
 121     static void initialize(TRAPS);
 122 
 123     static int max_oop_map_stack_offset() {
 124       assert(_max_oop_map_stack_offset > 0, "must be initialized");
 125       return Data::_max_oop_map_stack_offset;
 126     }
 127   };
 128 
 129   static bool cstring_equals(const char* const& s0, const char* const& s1) {
 130     return strcmp(s0, s1) == 0;
 131   }
 132 
 133   static unsigned cstring_hash(const char* const& s) {
 134     int h = 0;
 135     const char* p = s;
 136     while (*p != '\0') {
 137       h = 31 * h + *p;
 138       p++;
 139     }
 140     return h;
 141   }
 142 
 143   static JNINativeMethod methods[];
 144 
 145   static objArrayHandle initialize_intrinsics(TRAPS);
 146  public:
 147   static int methods_count();
 148 
 149   static inline Method* asMethod(jobject jvmci_method) {
 150     return (Method*) (address) HotSpotResolvedJavaMethodImpl::metaspaceMethod(jvmci_method);
 151   }
 152 
 153   static inline Method* asMethod(Handle jvmci_method) {
 154     return (Method*) (address) HotSpotResolvedJavaMethodImpl::metaspaceMethod(jvmci_method);
 155   }
 156 
 157   static inline Method* asMethod(oop jvmci_method) {
 158     return (Method*) (address) HotSpotResolvedJavaMethodImpl::metaspaceMethod(jvmci_method);
 159   }
 160 
 161   static inline ConstantPool* asConstantPool(jobject jvmci_constant_pool) {
 162     return (ConstantPool*) (address) HotSpotConstantPool::metaspaceConstantPool(jvmci_constant_pool);
 163   }
 164 
 165   static inline ConstantPool* asConstantPool(Handle jvmci_constant_pool) {
 166     return (ConstantPool*) (address) HotSpotConstantPool::metaspaceConstantPool(jvmci_constant_pool);
 167   }
 168 
 169   static inline ConstantPool* asConstantPool(oop jvmci_constant_pool) {
 170     return (ConstantPool*) (address) HotSpotConstantPool::metaspaceConstantPool(jvmci_constant_pool);
 171   }
 172 
 173   static inline Klass* asKlass(jobject jvmci_type) {
 174     return java_lang_Class::as_Klass(HotSpotResolvedObjectTypeImpl::javaClass(jvmci_type));
 175   }
 176 
 177   static inline Klass* asKlass(Handle jvmci_type) {
 178     return java_lang_Class::as_Klass(HotSpotResolvedObjectTypeImpl::javaClass(jvmci_type));
 179   }
 180 
 181   static inline Klass* asKlass(oop jvmci_type) {
 182     return java_lang_Class::as_Klass(HotSpotResolvedObjectTypeImpl::javaClass(jvmci_type));
 183   }
 184 
 185   static inline Klass* asKlass(jlong metaspaceKlass) {
 186     return (Klass*) (address) metaspaceKlass;
 187   }
 188 
 189   static inline MethodData* asMethodData(jlong metaspaceMethodData) {
 190     return (MethodData*) (address) metaspaceMethodData;
 191   }
 192 
 193   static oop get_jvmci_method(const methodHandle& method, TRAPS);
 194 
 195   static oop get_jvmci_type(JVMCIKlassHandle& klass, TRAPS);
 196 };
 197 
 198 class JavaArgumentUnboxer : public SignatureIterator {
 199  protected:
 200   JavaCallArguments*  _jca;
 201   arrayOop _args;
 202   int _index;
 203 
 204   Handle next_arg(BasicType expectedType);
 205 
 206  public:
 207   JavaArgumentUnboxer(Symbol* signature, JavaCallArguments*  jca, arrayOop args, bool is_static) : SignatureIterator(signature) {
 208     this->_return_type = T_ILLEGAL;
 209     _jca = jca;
 210     _index = 0;
 211     _args = args;
 212     if (!is_static) {
 213       _jca->push_oop(next_arg(T_OBJECT));
 214     }
 215     iterate();
 216     assert(_index == args->length(), "arg count mismatch with signature");
 217   }
 218 
 219   inline void do_bool()   { if (!is_return_type()) _jca->push_int(next_arg(T_BOOLEAN)->bool_field(java_lang_boxing_object::value_offset_in_bytes(T_BOOLEAN))); }
 220   inline void do_char()   { if (!is_return_type()) _jca->push_int(next_arg(T_CHAR)->char_field(java_lang_boxing_object::value_offset_in_bytes(T_CHAR))); }
 221   inline void do_short()  { if (!is_return_type()) _jca->push_int(next_arg(T_SHORT)->short_field(java_lang_boxing_object::value_offset_in_bytes(T_SHORT))); }
 222   inline void do_byte()   { if (!is_return_type()) _jca->push_int(next_arg(T_BYTE)->byte_field(java_lang_boxing_object::value_offset_in_bytes(T_BYTE))); }
 223   inline void do_int()    { if (!is_return_type()) _jca->push_int(next_arg(T_INT)->int_field(java_lang_boxing_object::value_offset_in_bytes(T_INT))); }
 224 
 225   inline void do_long()   { if (!is_return_type()) _jca->push_long(next_arg(T_LONG)->long_field(java_lang_boxing_object::value_offset_in_bytes(T_LONG))); }
 226   inline void do_float()  { if (!is_return_type()) _jca->push_float(next_arg(T_FLOAT)->float_field(java_lang_boxing_object::value_offset_in_bytes(T_FLOAT))); }
 227   inline void do_double() { if (!is_return_type()) _jca->push_double(next_arg(T_DOUBLE)->double_field(java_lang_boxing_object::value_offset_in_bytes(T_DOUBLE))); }
 228 
 229   inline void do_object() { _jca->push_oop(next_arg(T_OBJECT)); }
 230   inline void do_object(int begin, int end) { if (!is_return_type()) _jca->push_oop(next_arg(T_OBJECT)); }
 231   inline void do_array(int begin, int end)  { if (!is_return_type()) _jca->push_oop(next_arg(T_OBJECT)); }
 232   inline void do_void()                     { }
 233 };
 234 
 235 class JNIHandleMark : public StackObj {
 236   public:
 237     JNIHandleMark() { push_jni_handle_block(); }
 238     ~JNIHandleMark() { pop_jni_handle_block(); }
 239 
 240   private:
 241     static void push_jni_handle_block();
 242     static void pop_jni_handle_block();
 243 };
 244 
 245 #endif // SHARE_JVMCI_JVMCICOMPILERTOVM_HPP