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 #include "code/codeBlob.hpp"
26 #include "code/codeCache.hpp"
27 #include "code/relocInfo.hpp"
28 #include "code/vtableStubs.hpp"
29 #include "compiler/disassembler.hpp"
30 #include "compiler/oopMap.hpp"
31 #include "cppstdlib/type_traits.hpp"
32 #include "interpreter/bytecode.hpp"
33 #include "interpreter/interpreter.hpp"
34 #include "jvm.h"
35 #include "memory/allocation.inline.hpp"
36 #include "memory/heap.hpp"
37 #include "memory/resourceArea.hpp"
38 #include "oops/oop.inline.hpp"
39 #include "prims/forte.hpp"
40 #include "prims/jvmtiExport.hpp"
41 #include "runtime/handles.inline.hpp"
42 #include "runtime/interfaceSupport.inline.hpp"
43 #include "runtime/javaFrameAnchor.hpp"
44 #include "runtime/jniHandles.inline.hpp"
171 _name(name),
172 _mutable_data(header_begin() + size), // default value is blob_end()
173 _size(size),
174 _relocation_size(0),
175 _content_offset(CodeBlob::align_code_offset(header_size)),
176 _code_offset(_content_offset),
177 _data_offset(size),
178 _frame_size(0),
179 _mutable_data_size(0),
180 S390_ONLY(_ctable_offset(0) COMMA)
181 _header_size(header_size),
182 _frame_complete_offset(CodeOffsets::frame_never_safe),
183 _kind(kind),
184 _caller_must_gc_arguments(false)
185 {
186 assert(is_aligned(size, oopSize), "unaligned size");
187 assert(is_aligned(header_size, oopSize), "unaligned size");
188 assert(_mutable_data == blob_end(), "sanity");
189 }
190
191 void CodeBlob::restore_mutable_data(address reloc_data) {
192 // Relocation data is now stored as part of the mutable data area; allocate it before copy relocations
193 if (_mutable_data_size > 0) {
194 _mutable_data = (address)os::malloc(_mutable_data_size, mtCode);
195 if (_mutable_data == nullptr) {
196 vm_exit_out_of_memory(_mutable_data_size, OOM_MALLOC_ERROR, "codebuffer: no space for mutable data");
197 }
198 } else {
199 _mutable_data = blob_end(); // default value
200 }
201 if (_relocation_size > 0) {
202 assert(_mutable_data_size > 0, "relocation is part of mutable data section");
203 memcpy((address)relocation_begin(), reloc_data, relocation_size());
204 }
205 }
206
207 void CodeBlob::purge() {
208 assert(_mutable_data != nullptr, "should never be null");
209 if (_mutable_data != blob_end()) {
210 os::free(_mutable_data);
211 _mutable_data = blob_end(); // Valid not null address
212 _mutable_data_size = 0;
213 _relocation_size = 0;
214 }
215 if (_oop_maps != nullptr) {
216 delete _oop_maps;
217 _oop_maps = nullptr;
218 }
219 NOT_PRODUCT(_asm_remarks.clear());
220 NOT_PRODUCT(_dbg_strings.clear());
221 }
222
223 void CodeBlob::set_oop_maps(OopMapSet* p) {
224 // Danger Will Robinson! This method allocates a big
225 // chunk of memory, its your job to free it.
226 if (p != nullptr) {
227 _oop_maps = ImmutableOopMapSet::build_from(p);
228 } else {
229 _oop_maps = nullptr;
230 }
231 }
232
233 const ImmutableOopMap* CodeBlob::oop_map_for_return_address(address return_address) const {
234 assert(_oop_maps != nullptr, "nope");
235 return _oop_maps->find_map_at_offset((intptr_t) return_address - (intptr_t) code_begin());
236 }
237
238 void CodeBlob::print_code_on(outputStream* st) {
239 ResourceMark m;
240 Disassembler::decode(this, st);
241 }
242
243 void CodeBlob::prepare_for_archiving_impl() {
244 set_name(nullptr);
245 _oop_maps = nullptr;
246 _mutable_data = nullptr;
247 #ifndef PRODUCT
248 asm_remarks().clear();
249 dbg_strings().clear();
250 #endif /* PRODUCT */
251 }
252
253 void CodeBlob::prepare_for_archiving() {
254 vptr(_kind)->prepare_for_archiving(this);
255 }
256
257 void CodeBlob::archive_blob(CodeBlob* blob, address archive_buffer) {
258 blob->copy_to(archive_buffer);
259 CodeBlob* archived_blob = (CodeBlob*)archive_buffer;
260 archived_blob->prepare_for_archiving();
261 }
262
263 void CodeBlob::post_restore_impl() {
264 // Track memory usage statistic after releasing CodeCache_lock
265 MemoryService::track_code_cache_memory_usage();
266 }
267
268 void CodeBlob::post_restore() {
269 vptr(_kind)->post_restore(this);
286 const char* name,
287 address archived_reloc_data,
288 ImmutableOopMapSet* archived_oop_maps
289 )
290 {
291 ThreadInVMfromUnknown __tiv; // get to VM state in case we block on CodeCache_lock
292
293 CodeCache::gc_on_allocation();
294
295 CodeBlob* blob = nullptr;
296 unsigned int size = archived_blob->size();
297 {
298 MutexLocker mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
299 address code_cache_buffer = (address)CodeCache::allocate(size, CodeBlobType::NonNMethod);
300 if (code_cache_buffer != nullptr) {
301 blob = archived_blob->restore(code_cache_buffer,
302 name,
303 archived_reloc_data,
304 archived_oop_maps);
305 assert(blob != nullptr, "sanity check");
306
307 // Flush the code block
308 ICache::invalidate_range(blob->code_begin(), blob->code_size());
309 CodeCache::commit(blob); // Count adapters
310 }
311 }
312 if (blob != nullptr) {
313 blob->post_restore();
314 }
315 return blob;
316 }
317
318 //-----------------------------------------------------------------------------------------
319 // Creates a RuntimeBlob from a CodeBuffer and copy code and relocation info.
320
321 RuntimeBlob::RuntimeBlob(
322 const char* name,
323 CodeBlobKind kind,
324 CodeBuffer* cb,
325 int size,
326 uint16_t header_size,
|
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 #include "code/aotCodeCache.hpp"
26 #include "code/codeBlob.hpp"
27 #include "code/codeCache.hpp"
28 #include "code/relocInfo.hpp"
29 #include "code/vtableStubs.hpp"
30 #include "compiler/disassembler.hpp"
31 #include "compiler/oopMap.hpp"
32 #include "cppstdlib/type_traits.hpp"
33 #include "interpreter/bytecode.hpp"
34 #include "interpreter/interpreter.hpp"
35 #include "jvm.h"
36 #include "memory/allocation.inline.hpp"
37 #include "memory/heap.hpp"
38 #include "memory/resourceArea.hpp"
39 #include "oops/oop.inline.hpp"
40 #include "prims/forte.hpp"
41 #include "prims/jvmtiExport.hpp"
42 #include "runtime/handles.inline.hpp"
43 #include "runtime/interfaceSupport.inline.hpp"
44 #include "runtime/javaFrameAnchor.hpp"
45 #include "runtime/jniHandles.inline.hpp"
172 _name(name),
173 _mutable_data(header_begin() + size), // default value is blob_end()
174 _size(size),
175 _relocation_size(0),
176 _content_offset(CodeBlob::align_code_offset(header_size)),
177 _code_offset(_content_offset),
178 _data_offset(size),
179 _frame_size(0),
180 _mutable_data_size(0),
181 S390_ONLY(_ctable_offset(0) COMMA)
182 _header_size(header_size),
183 _frame_complete_offset(CodeOffsets::frame_never_safe),
184 _kind(kind),
185 _caller_must_gc_arguments(false)
186 {
187 assert(is_aligned(size, oopSize), "unaligned size");
188 assert(is_aligned(header_size, oopSize), "unaligned size");
189 assert(_mutable_data == blob_end(), "sanity");
190 }
191
192 #ifdef ASSERT
193 CodeBlob::~CodeBlob() {
194 assert(_oop_maps == nullptr || AOTCodeCache::is_address_in_aot_cache((address)_oop_maps), "Not flushed");
195 }
196 #endif
197
198 void CodeBlob::restore_mutable_data(address reloc_data) {
199 // Relocation data is now stored as part of the mutable data area; allocate it before copy relocations
200 if (_mutable_data_size > 0) {
201 _mutable_data = (address)os::malloc(_mutable_data_size, mtCode);
202 if (_mutable_data == nullptr) {
203 vm_exit_out_of_memory(_mutable_data_size, OOM_MALLOC_ERROR, "codebuffer: no space for mutable data");
204 }
205 } else {
206 _mutable_data = blob_end(); // default value
207 }
208 if (_relocation_size > 0) {
209 assert(_mutable_data_size > 0, "relocation is part of mutable data section");
210 memcpy((address)relocation_begin(), reloc_data, relocation_size());
211 }
212 }
213
214 void CodeBlob::purge() {
215 assert(_mutable_data != nullptr, "should never be null");
216 if (_mutable_data != blob_end()) {
217 os::free(_mutable_data);
218 _mutable_data = blob_end(); // Valid not null address
219 _mutable_data_size = 0;
220 _relocation_size = 0;
221 }
222 if (_oop_maps != nullptr && !AOTCodeCache::is_address_in_aot_cache((address)_oop_maps)) {
223 delete _oop_maps;
224 _oop_maps = nullptr;
225 }
226 NOT_PRODUCT(_asm_remarks.clear());
227 NOT_PRODUCT(_dbg_strings.clear());
228 }
229
230 void CodeBlob::set_oop_maps(OopMapSet* p) {
231 // Danger Will Robinson! This method allocates a big
232 // chunk of memory, its your job to free it.
233 if (p != nullptr) {
234 _oop_maps = ImmutableOopMapSet::build_from(p);
235 } else {
236 _oop_maps = nullptr;
237 }
238 }
239
240 const ImmutableOopMap* CodeBlob::oop_map_for_return_address(address return_address) const {
241 assert(_oop_maps != nullptr, "nope");
242 return _oop_maps->find_map_at_offset((intptr_t) return_address - (intptr_t) code_begin());
243 }
244
245 void CodeBlob::print_code_on(outputStream* st) {
246 ResourceMark m;
247 Disassembler::decode(this, st);
248 }
249
250 void CodeBlob::prepare_for_archiving_impl() {
251 set_name(nullptr);
252 _oop_maps = nullptr;
253 _mutable_data = nullptr;
254 #ifndef PRODUCT
255 asm_remarks().clear_ref();
256 dbg_strings().clear_ref();
257 #endif /* PRODUCT */
258 }
259
260 void CodeBlob::prepare_for_archiving() {
261 vptr(_kind)->prepare_for_archiving(this);
262 }
263
264 void CodeBlob::archive_blob(CodeBlob* blob, address archive_buffer) {
265 blob->copy_to(archive_buffer);
266 CodeBlob* archived_blob = (CodeBlob*)archive_buffer;
267 archived_blob->prepare_for_archiving();
268 }
269
270 void CodeBlob::post_restore_impl() {
271 // Track memory usage statistic after releasing CodeCache_lock
272 MemoryService::track_code_cache_memory_usage();
273 }
274
275 void CodeBlob::post_restore() {
276 vptr(_kind)->post_restore(this);
293 const char* name,
294 address archived_reloc_data,
295 ImmutableOopMapSet* archived_oop_maps
296 )
297 {
298 ThreadInVMfromUnknown __tiv; // get to VM state in case we block on CodeCache_lock
299
300 CodeCache::gc_on_allocation();
301
302 CodeBlob* blob = nullptr;
303 unsigned int size = archived_blob->size();
304 {
305 MutexLocker mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
306 address code_cache_buffer = (address)CodeCache::allocate(size, CodeBlobType::NonNMethod);
307 if (code_cache_buffer != nullptr) {
308 blob = archived_blob->restore(code_cache_buffer,
309 name,
310 archived_reloc_data,
311 archived_oop_maps);
312 assert(blob != nullptr, "sanity check");
313 // Flush the code block
314 ICache::invalidate_range(blob->code_begin(), blob->code_size());
315 CodeCache::commit(blob); // Count adapters
316 }
317 }
318 if (blob != nullptr) {
319 blob->post_restore();
320 }
321 return blob;
322 }
323
324 //-----------------------------------------------------------------------------------------
325 // Creates a RuntimeBlob from a CodeBuffer and copy code and relocation info.
326
327 RuntimeBlob::RuntimeBlob(
328 const char* name,
329 CodeBlobKind kind,
330 CodeBuffer* cb,
331 int size,
332 uint16_t header_size,
|