| 1 | /* | 
|---|
| 2 | * Copyright (c) 1999, 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 SHARE_C1_C1_RUNTIME1_HPP | 
|---|
| 26 | #define SHARE_C1_C1_RUNTIME1_HPP | 
|---|
| 27 |  | 
|---|
| 28 | #include "c1/c1_FrameMap.hpp" | 
|---|
| 29 | #include "code/stubs.hpp" | 
|---|
| 30 | #include "interpreter/interpreter.hpp" | 
|---|
| 31 | #include "memory/allocation.hpp" | 
|---|
| 32 | #include "runtime/deoptimization.hpp" | 
|---|
| 33 |  | 
|---|
| 34 | class StubAssembler; | 
|---|
| 35 |  | 
|---|
| 36 | // The Runtime1 holds all assembly stubs and VM | 
|---|
| 37 | // runtime routines needed by code code generated | 
|---|
| 38 | // by the Compiler1. | 
|---|
| 39 |  | 
|---|
| 40 | #define RUNTIME1_STUBS(stub, last_entry) \ | 
|---|
| 41 | stub(dtrace_object_alloc)          \ | 
|---|
| 42 | stub(unwind_exception)             \ | 
|---|
| 43 | stub(forward_exception)            \ | 
|---|
| 44 | stub(throw_range_check_failed)       /* throws ArrayIndexOutOfBoundsException */ \ | 
|---|
| 45 | stub(throw_index_exception)          /* throws IndexOutOfBoundsException */ \ | 
|---|
| 46 | stub(throw_div0_exception)         \ | 
|---|
| 47 | stub(throw_null_pointer_exception) \ | 
|---|
| 48 | stub(register_finalizer)           \ | 
|---|
| 49 | stub(new_instance)                 \ | 
|---|
| 50 | stub(fast_new_instance)            \ | 
|---|
| 51 | stub(fast_new_instance_init_check) \ | 
|---|
| 52 | stub(new_type_array)               \ | 
|---|
| 53 | stub(new_object_array)             \ | 
|---|
| 54 | stub(new_multi_array)              \ | 
|---|
| 55 | stub(handle_exception_nofpu)         /* optimized version that does not preserve fpu registers */ \ | 
|---|
| 56 | stub(handle_exception)             \ | 
|---|
| 57 | stub(handle_exception_from_callee) \ | 
|---|
| 58 | stub(throw_array_store_exception)  \ | 
|---|
| 59 | stub(throw_class_cast_exception)   \ | 
|---|
| 60 | stub(throw_incompatible_class_change_error)   \ | 
|---|
| 61 | stub(slow_subtype_check)           \ | 
|---|
| 62 | stub(monitorenter)                 \ | 
|---|
| 63 | stub(monitorenter_nofpu)             /* optimized version that does not preserve fpu registers */ \ | 
|---|
| 64 | stub(monitorexit)                  \ | 
|---|
| 65 | stub(monitorexit_nofpu)              /* optimized version that does not preserve fpu registers */ \ | 
|---|
| 66 | stub(deoptimize)                   \ | 
|---|
| 67 | stub(access_field_patching)        \ | 
|---|
| 68 | stub(load_klass_patching)          \ | 
|---|
| 69 | stub(load_mirror_patching)         \ | 
|---|
| 70 | stub(load_appendix_patching)       \ | 
|---|
| 71 | stub(fpu2long_stub)                \ | 
|---|
| 72 | stub(counter_overflow)             \ | 
|---|
| 73 | stub(predicate_failed_trap)        \ | 
|---|
| 74 | last_entry(number_of_ids) | 
|---|
| 75 |  | 
|---|
| 76 | #define DECLARE_STUB_ID(x)       x ## _id , | 
|---|
| 77 | #define DECLARE_LAST_STUB_ID(x)  x | 
|---|
| 78 | #define STUB_NAME(x)             #x " Runtime1 stub", | 
|---|
| 79 | #define LAST_STUB_NAME(x)        #x " Runtime1 stub" | 
|---|
| 80 |  | 
|---|
| 81 | class StubAssemblerCodeGenClosure: public Closure { | 
|---|
| 82 | public: | 
|---|
| 83 | virtual OopMapSet* generate_code(StubAssembler* sasm) = 0; | 
|---|
| 84 | }; | 
|---|
| 85 |  | 
|---|
| 86 | class Runtime1: public AllStatic { | 
|---|
| 87 | friend class VMStructs; | 
|---|
| 88 | friend class ArrayCopyStub; | 
|---|
| 89 |  | 
|---|
| 90 | public: | 
|---|
| 91 | enum StubID { | 
|---|
| 92 | RUNTIME1_STUBS(DECLARE_STUB_ID, DECLARE_LAST_STUB_ID) | 
|---|
| 93 | }; | 
|---|
| 94 |  | 
|---|
| 95 | // statistics | 
|---|
| 96 | #ifndef PRODUCT | 
|---|
| 97 | static int _resolve_invoke_cnt; | 
|---|
| 98 | static int _handle_wrong_method_cnt; | 
|---|
| 99 | static int _ic_miss_cnt; | 
|---|
| 100 | static int _generic_arraycopy_cnt; | 
|---|
| 101 | static int _generic_arraycopystub_cnt; | 
|---|
| 102 | static int _arraycopy_slowcase_cnt; | 
|---|
| 103 | static int _arraycopy_checkcast_cnt; | 
|---|
| 104 | static int _arraycopy_checkcast_attempt_cnt; | 
|---|
| 105 | static int _new_type_array_slowcase_cnt; | 
|---|
| 106 | static int _new_object_array_slowcase_cnt; | 
|---|
| 107 | static int _new_instance_slowcase_cnt; | 
|---|
| 108 | static int _new_multi_array_slowcase_cnt; | 
|---|
| 109 | static int _monitorenter_slowcase_cnt; | 
|---|
| 110 | static int _monitorexit_slowcase_cnt; | 
|---|
| 111 | static int _patch_code_slowcase_cnt; | 
|---|
| 112 | static int _throw_range_check_exception_count; | 
|---|
| 113 | static int _throw_index_exception_count; | 
|---|
| 114 | static int _throw_div0_exception_count; | 
|---|
| 115 | static int _throw_null_pointer_exception_count; | 
|---|
| 116 | static int _throw_class_cast_exception_count; | 
|---|
| 117 | static int _throw_incompatible_class_change_error_count; | 
|---|
| 118 | static int _throw_array_store_exception_count; | 
|---|
| 119 | static int _throw_count; | 
|---|
| 120 | #endif | 
|---|
| 121 |  | 
|---|
| 122 | private: | 
|---|
| 123 | static CodeBlob* _blobs[number_of_ids]; | 
|---|
| 124 | static const char* _blob_names[]; | 
|---|
| 125 |  | 
|---|
| 126 | // stub generation | 
|---|
| 127 | public: | 
|---|
| 128 | static CodeBlob*  generate_blob(BufferBlob* buffer_blob, int stub_id, const char* name, bool expect_oop_map, StubAssemblerCodeGenClosure *cl); | 
|---|
| 129 | static void       generate_blob_for(BufferBlob* blob, StubID id); | 
|---|
| 130 | static OopMapSet* generate_code_for(StubID id, StubAssembler* sasm); | 
|---|
| 131 | private: | 
|---|
| 132 | static OopMapSet* generate_exception_throw(StubAssembler* sasm, address target, bool has_argument); | 
|---|
| 133 | static OopMapSet* generate_handle_exception(StubID id, StubAssembler* sasm); | 
|---|
| 134 | static void       generate_unwind_exception(StubAssembler *sasm); | 
|---|
| 135 | static OopMapSet* generate_patching(StubAssembler* sasm, address target); | 
|---|
| 136 |  | 
|---|
| 137 | static OopMapSet* generate_stub_call(StubAssembler* sasm, Register result, address entry, | 
|---|
| 138 | Register arg1 = noreg, Register arg2 = noreg, Register arg3 = noreg); | 
|---|
| 139 |  | 
|---|
| 140 | // runtime entry points | 
|---|
| 141 | static void new_instance    (JavaThread* thread, Klass* klass); | 
|---|
| 142 | static void new_type_array  (JavaThread* thread, Klass* klass, jint length); | 
|---|
| 143 | static void new_object_array(JavaThread* thread, Klass* klass, jint length); | 
|---|
| 144 | static void new_multi_array (JavaThread* thread, Klass* klass, int rank, jint* dims); | 
|---|
| 145 |  | 
|---|
| 146 | static address counter_overflow(JavaThread* thread, int bci, Method* method); | 
|---|
| 147 |  | 
|---|
| 148 | static void unimplemented_entry   (JavaThread* thread, StubID id); | 
|---|
| 149 |  | 
|---|
| 150 | static address exception_handler_for_pc(JavaThread* thread); | 
|---|
| 151 |  | 
|---|
| 152 | static void throw_range_check_exception(JavaThread* thread, int index, arrayOopDesc* a); | 
|---|
| 153 | static void throw_index_exception(JavaThread* thread, int index); | 
|---|
| 154 | static void throw_div0_exception(JavaThread* thread); | 
|---|
| 155 | static void throw_null_pointer_exception(JavaThread* thread); | 
|---|
| 156 | static void throw_class_cast_exception(JavaThread* thread, oopDesc* object); | 
|---|
| 157 | static void throw_incompatible_class_change_error(JavaThread* thread); | 
|---|
| 158 | static void throw_array_store_exception(JavaThread* thread, oopDesc* object); | 
|---|
| 159 |  | 
|---|
| 160 | static void monitorenter(JavaThread* thread, oopDesc* obj, BasicObjectLock* lock); | 
|---|
| 161 | static void monitorexit (JavaThread* thread, BasicObjectLock* lock); | 
|---|
| 162 |  | 
|---|
| 163 | static void deoptimize(JavaThread* thread, jint trap_request); | 
|---|
| 164 |  | 
|---|
| 165 | static int access_field_patching(JavaThread* thread); | 
|---|
| 166 | static int move_klass_patching(JavaThread* thread); | 
|---|
| 167 | static int move_mirror_patching(JavaThread* thread); | 
|---|
| 168 | static int move_appendix_patching(JavaThread* thread); | 
|---|
| 169 |  | 
|---|
| 170 | static void patch_code(JavaThread* thread, StubID stub_id); | 
|---|
| 171 |  | 
|---|
| 172 | public: | 
|---|
| 173 | // initialization | 
|---|
| 174 | static void initialize(BufferBlob* blob); | 
|---|
| 175 | static void initialize_pd(); | 
|---|
| 176 |  | 
|---|
| 177 | // stubs | 
|---|
| 178 | static CodeBlob* blob_for (StubID id); | 
|---|
| 179 | static address   entry_for(StubID id)          { return blob_for(id)->code_begin(); } | 
|---|
| 180 | static const char* name_for (StubID id); | 
|---|
| 181 | static const char* name_for_address(address entry); | 
|---|
| 182 |  | 
|---|
| 183 | // platform might add runtime names. | 
|---|
| 184 | static const char* pd_name_for_address(address entry); | 
|---|
| 185 |  | 
|---|
| 186 | // method tracing | 
|---|
| 187 | static void trace_block_entry(jint block_id); | 
|---|
| 188 |  | 
|---|
| 189 | #ifndef PRODUCT | 
|---|
| 190 | static address throw_count_address()               { return (address)&_throw_count;             } | 
|---|
| 191 | static address arraycopy_count_address(BasicType type); | 
|---|
| 192 | #endif | 
|---|
| 193 |  | 
|---|
| 194 | // directly accessible leaf routine | 
|---|
| 195 | static int  is_instance_of(oopDesc* mirror, oopDesc* obj); | 
|---|
| 196 |  | 
|---|
| 197 | static void predicate_failed_trap(JavaThread* thread); | 
|---|
| 198 |  | 
|---|
| 199 | static void print_statistics()                 PRODUCT_RETURN; | 
|---|
| 200 | }; | 
|---|
| 201 |  | 
|---|
| 202 | #endif // SHARE_C1_C1_RUNTIME1_HPP | 
|---|
| 203 |  | 
|---|