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 | |