58 assert(_num_rt_args == args, "can't change the number of args"); |
58 assert(_num_rt_args == args, "can't change the number of args"); |
59 } |
59 } |
60 |
60 |
61 // Implementation of Runtime1 |
61 // Implementation of Runtime1 |
62 |
62 |
63 bool Runtime1::_is_initialized = false; |
|
64 CodeBlob* Runtime1::_blobs[Runtime1::number_of_ids]; |
63 CodeBlob* Runtime1::_blobs[Runtime1::number_of_ids]; |
65 const char *Runtime1::_blob_names[] = { |
64 const char *Runtime1::_blob_names[] = { |
66 RUNTIME1_STUBS(STUB_NAME, LAST_STUB_NAME) |
65 RUNTIME1_STUBS(STUB_NAME, LAST_STUB_NAME) |
67 }; |
66 }; |
68 |
67 |
87 int Runtime1::_throw_incompatible_class_change_error_count = 0; |
86 int Runtime1::_throw_incompatible_class_change_error_count = 0; |
88 int Runtime1::_throw_array_store_exception_count = 0; |
87 int Runtime1::_throw_array_store_exception_count = 0; |
89 int Runtime1::_throw_count = 0; |
88 int Runtime1::_throw_count = 0; |
90 #endif |
89 #endif |
91 |
90 |
92 BufferBlob* Runtime1::_buffer_blob = NULL; |
|
93 |
|
94 // Simple helper to see if the caller of a runtime stub which |
91 // Simple helper to see if the caller of a runtime stub which |
95 // entered the VM has been deoptimized |
92 // entered the VM has been deoptimized |
96 |
93 |
97 static bool caller_is_deopted() { |
94 static bool caller_is_deopted() { |
98 JavaThread* thread = JavaThread::current(); |
95 JavaThread* thread = JavaThread::current(); |
115 assert(caller_is_deopted(), "Must be deoptimized"); |
112 assert(caller_is_deopted(), "Must be deoptimized"); |
116 } |
113 } |
117 } |
114 } |
118 |
115 |
119 |
116 |
120 BufferBlob* Runtime1::get_buffer_blob() { |
117 void Runtime1::generate_blob_for(BufferBlob* buffer_blob, StubID id) { |
121 // Allocate code buffer space only once |
|
122 BufferBlob* blob = _buffer_blob; |
|
123 if (blob == NULL) { |
|
124 // setup CodeBuffer. Preallocate a BufferBlob of size |
|
125 // NMethodSizeLimit plus some extra space for constants. |
|
126 int code_buffer_size = desired_max_code_buffer_size() + desired_max_constant_size(); |
|
127 blob = BufferBlob::create("Compiler1 temporary CodeBuffer", |
|
128 code_buffer_size); |
|
129 guarantee(blob != NULL, "must create initial code buffer"); |
|
130 _buffer_blob = blob; |
|
131 } |
|
132 return _buffer_blob; |
|
133 } |
|
134 |
|
135 void Runtime1::setup_code_buffer(CodeBuffer* code, int call_stub_estimate) { |
|
136 // Preinitialize the consts section to some large size: |
|
137 int locs_buffer_size = 20 * (relocInfo::length_limit + sizeof(relocInfo)); |
|
138 char* locs_buffer = NEW_RESOURCE_ARRAY(char, locs_buffer_size); |
|
139 code->insts()->initialize_shared_locs((relocInfo*)locs_buffer, |
|
140 locs_buffer_size / sizeof(relocInfo)); |
|
141 code->initialize_consts_size(desired_max_constant_size()); |
|
142 // Call stubs + deopt/exception handler |
|
143 code->initialize_stubs_size((call_stub_estimate * LIR_Assembler::call_stub_size) + |
|
144 LIR_Assembler::exception_handler_size + |
|
145 LIR_Assembler::deopt_handler_size); |
|
146 } |
|
147 |
|
148 |
|
149 void Runtime1::generate_blob_for(StubID id) { |
|
150 assert(0 <= id && id < number_of_ids, "illegal stub id"); |
118 assert(0 <= id && id < number_of_ids, "illegal stub id"); |
151 ResourceMark rm; |
119 ResourceMark rm; |
152 // create code buffer for code storage |
120 // create code buffer for code storage |
153 CodeBuffer code(get_buffer_blob()->instructions_begin(), |
121 CodeBuffer code(buffer_blob->instructions_begin(), |
154 get_buffer_blob()->instructions_size()); |
122 buffer_blob->instructions_size()); |
155 |
123 |
156 setup_code_buffer(&code, 0); |
124 Compilation::setup_code_buffer(&code, 0); |
157 |
125 |
158 // create assembler for code generation |
126 // create assembler for code generation |
159 StubAssembler* sasm = new StubAssembler(&code, name_for(id), id); |
127 StubAssembler* sasm = new StubAssembler(&code, name_for(id), id); |
160 // generate code for runtime stub |
128 // generate code for runtime stub |
161 OopMapSet* oop_maps; |
129 OopMapSet* oop_maps; |
202 assert(blob != NULL, "blob must exist"); |
170 assert(blob != NULL, "blob must exist"); |
203 _blobs[id] = blob; |
171 _blobs[id] = blob; |
204 } |
172 } |
205 |
173 |
206 |
174 |
207 void Runtime1::initialize() { |
175 void Runtime1::initialize(BufferBlob* blob) { |
208 // Warning: If we have more than one compilation running in parallel, we |
176 // platform-dependent initialization |
209 // need a lock here with the current setup (lazy initialization). |
177 initialize_pd(); |
210 if (!is_initialized()) { |
178 // generate stubs |
211 _is_initialized = true; |
179 for (int id = 0; id < number_of_ids; id++) generate_blob_for(blob, (StubID)id); |
212 |
180 // printing |
213 // platform-dependent initialization |
|
214 initialize_pd(); |
|
215 // generate stubs |
|
216 for (int id = 0; id < number_of_ids; id++) generate_blob_for((StubID)id); |
|
217 // printing |
|
218 #ifndef PRODUCT |
181 #ifndef PRODUCT |
219 if (PrintSimpleStubs) { |
182 if (PrintSimpleStubs) { |
220 ResourceMark rm; |
183 ResourceMark rm; |
221 for (int id = 0; id < number_of_ids; id++) { |
184 for (int id = 0; id < number_of_ids; id++) { |
222 _blobs[id]->print(); |
185 _blobs[id]->print(); |
223 if (_blobs[id]->oop_maps() != NULL) { |
186 if (_blobs[id]->oop_maps() != NULL) { |
224 _blobs[id]->oop_maps()->print(); |
187 _blobs[id]->oop_maps()->print(); |
225 } |
|
226 } |
188 } |
227 } |
189 } |
|
190 } |
228 #endif |
191 #endif |
229 } |
|
230 } |
192 } |
231 |
193 |
232 |
194 |
233 CodeBlob* Runtime1::blob_for(StubID id) { |
195 CodeBlob* Runtime1::blob_for(StubID id) { |
234 assert(0 <= id && id < number_of_ids, "illegal stub id"); |
196 assert(0 <= id && id < number_of_ids, "illegal stub id"); |
235 if (!is_initialized()) initialize(); |
|
236 return _blobs[id]; |
197 return _blobs[id]; |
237 } |
198 } |
238 |
199 |
239 |
200 |
240 const char* Runtime1::name_for(StubID id) { |
201 const char* Runtime1::name_for(StubID id) { |