< prev index next >

src/hotspot/share/code/codeBlob.cpp

Print this page

  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 "interpreter/bytecode.hpp"
 32 #include "interpreter/interpreter.hpp"
 33 #include "jvm.h"
 34 #include "memory/allocation.inline.hpp"
 35 #include "memory/heap.hpp"
 36 #include "memory/resourceArea.hpp"
 37 #include "oops/oop.inline.hpp"
 38 #include "prims/forte.hpp"
 39 #include "prims/jvmtiExport.hpp"
 40 #include "runtime/handles.inline.hpp"
 41 #include "runtime/interfaceSupport.inline.hpp"
 42 #include "runtime/javaFrameAnchor.hpp"
 43 #include "runtime/jniHandles.inline.hpp"
 44 #include "runtime/mutexLocker.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 void CodeBlob::restore_mutable_data(address reloc_data) {
193   // Relocation data is now stored as part of the mutable data area; allocate it before copy relocations
194   if (_mutable_data_size > 0) {
195     _mutable_data = (address)os::malloc(_mutable_data_size, mtCode);
196     if (_mutable_data == nullptr) {
197       vm_exit_out_of_memory(_mutable_data_size, OOM_MALLOC_ERROR, "codebuffer: no space for mutable data");
198     }
199   } else {
200     _mutable_data = blob_end(); // default value
201   }
202   if (_relocation_size > 0) {
203     assert(_mutable_data_size > 0, "relocation is part of mutable data section");
204     memcpy((address)relocation_begin(), reloc_data, relocation_size());
205   }
206 }
207 
208 void CodeBlob::purge() {
209   assert(_mutable_data != nullptr, "should never be null");
210   if (_mutable_data != blob_end()) {
211     os::free(_mutable_data);
212     _mutable_data = blob_end(); // Valid not null address
213     _mutable_data_size = 0;
214     _relocation_size = 0;
215   }
216   if (_oop_maps != nullptr) {
217     delete _oop_maps;
218     _oop_maps = nullptr;
219   }
220   NOT_PRODUCT(_asm_remarks.clear());
221   NOT_PRODUCT(_dbg_strings.clear());
222 }
223 
224 void CodeBlob::set_oop_maps(OopMapSet* p) {
225   // Danger Will Robinson! This method allocates a big
226   // chunk of memory, its your job to free it.
227   if (p != nullptr) {
228     _oop_maps = ImmutableOopMapSet::build_from(p);
229   } else {
230     _oop_maps = nullptr;
231   }
232 }
233 
234 const ImmutableOopMap* CodeBlob::oop_map_for_return_address(address return_address) const {
235   assert(_oop_maps != nullptr, "nope");
236   return _oop_maps->find_map_at_offset((intptr_t) return_address - (intptr_t) code_begin());
237 }
238 
239 void CodeBlob::print_code_on(outputStream* st) {
240   ResourceMark m;
241   Disassembler::decode(this, st);
242 }
243 
244 void CodeBlob::prepare_for_archiving_impl() {
245   set_name(nullptr);
246   _oop_maps = nullptr;
247   _mutable_data = nullptr;
248 #ifndef PRODUCT
249   asm_remarks().clear();
250   dbg_strings().clear();
251 #endif /* PRODUCT */
252 }
253 
254 void CodeBlob::prepare_for_archiving() {
255   vptr(_kind)->prepare_for_archiving(this);
256 }
257 
258 void CodeBlob::archive_blob(CodeBlob* blob, address archive_buffer) {
259   blob->copy_to(archive_buffer);
260   CodeBlob* archived_blob = (CodeBlob*)archive_buffer;
261   archived_blob->prepare_for_archiving();
262 }
263 
264 void CodeBlob::post_restore_impl() {
265   // Track memory usage statistic after releasing CodeCache_lock
266   MemoryService::track_code_cache_memory_usage();
267 }
268 
269 void CodeBlob::post_restore() {
270   vptr(_kind)->post_restore(this);

287                            const char* name,
288                            address archived_reloc_data,
289                            ImmutableOopMapSet* archived_oop_maps
290                           )
291 {
292   ThreadInVMfromUnknown __tiv;  // get to VM state in case we block on CodeCache_lock
293 
294   CodeCache::gc_on_allocation();
295 
296   CodeBlob* blob = nullptr;
297   unsigned int size = archived_blob->size();
298   {
299     MutexLocker mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
300     address code_cache_buffer = (address)CodeCache::allocate(size, CodeBlobType::NonNMethod);
301     if (code_cache_buffer != nullptr) {
302       blob = archived_blob->restore(code_cache_buffer,
303                                     name,
304                                     archived_reloc_data,
305                                     archived_oop_maps);
306       assert(blob != nullptr, "sanity check");
307 
308       // Flush the code block
309       ICache::invalidate_range(blob->code_begin(), blob->code_size());
310       CodeCache::commit(blob); // Count adapters
311     }
312   }
313   if (blob != nullptr) {
314     blob->post_restore();
315   }
316   return blob;
317 }
318 
319 //-----------------------------------------------------------------------------------------
320 // Creates a RuntimeBlob from a CodeBuffer and copy code and relocation info.
321 
322 RuntimeBlob::RuntimeBlob(
323   const char* name,
324   CodeBlobKind kind,
325   CodeBuffer* cb,
326   int         size,
327   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 "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"
 45 #include "runtime/mutexLocker.hpp"

173   _name(name),
174   _mutable_data(header_begin() + size), // default value is blob_end()
175   _size(size),
176   _relocation_size(0),
177   _content_offset(CodeBlob::align_code_offset(header_size)),
178   _code_offset(_content_offset),
179   _data_offset(size),
180   _frame_size(0),
181   _mutable_data_size(0),
182   S390_ONLY(_ctable_offset(0) COMMA)
183   _header_size(header_size),
184   _frame_complete_offset(CodeOffsets::frame_never_safe),
185   _kind(kind),
186   _caller_must_gc_arguments(false)
187 {
188   assert(is_aligned(size,            oopSize), "unaligned size");
189   assert(is_aligned(header_size,     oopSize), "unaligned size");
190   assert(_mutable_data == blob_end(), "sanity");
191 }
192 
193 #ifdef ASSERT
194 CodeBlob::~CodeBlob() {
195   assert(_oop_maps == nullptr || AOTCodeCache::is_address_in_aot_cache((address)_oop_maps), "Not flushed");
196 }
197 #endif
198  
199 void CodeBlob::restore_mutable_data(address reloc_data) {
200   // Relocation data is now stored as part of the mutable data area; allocate it before copy relocations
201   if (_mutable_data_size > 0) {
202     _mutable_data = (address)os::malloc(_mutable_data_size, mtCode);
203     if (_mutable_data == nullptr) {
204       vm_exit_out_of_memory(_mutable_data_size, OOM_MALLOC_ERROR, "codebuffer: no space for mutable data");
205     }
206   } else {
207     _mutable_data = blob_end(); // default value
208   }
209   if (_relocation_size > 0) {
210     assert(_mutable_data_size > 0, "relocation is part of mutable data section");
211     memcpy((address)relocation_begin(), reloc_data, relocation_size());
212   }
213 }
214 
215 void CodeBlob::purge() {
216   assert(_mutable_data != nullptr, "should never be null");
217   if (_mutable_data != blob_end()) {
218     os::free(_mutable_data);
219     _mutable_data = blob_end(); // Valid not null address
220     _mutable_data_size = 0;
221     _relocation_size = 0;
222   }
223   if (_oop_maps != nullptr && !AOTCodeCache::is_address_in_aot_cache((address)_oop_maps)) {
224     delete _oop_maps;
225     _oop_maps = nullptr;
226   }
227   NOT_PRODUCT(_asm_remarks.clear());
228   NOT_PRODUCT(_dbg_strings.clear());
229 }
230 
231 void CodeBlob::set_oop_maps(OopMapSet* p) {
232   // Danger Will Robinson! This method allocates a big
233   // chunk of memory, its your job to free it.
234   if (p != nullptr) {
235     _oop_maps = ImmutableOopMapSet::build_from(p);
236   } else {
237     _oop_maps = nullptr;
238   }
239 }
240 
241 const ImmutableOopMap* CodeBlob::oop_map_for_return_address(address return_address) const {
242   assert(_oop_maps != nullptr, "nope");
243   return _oop_maps->find_map_at_offset((intptr_t) return_address - (intptr_t) code_begin());
244 }
245 
246 void CodeBlob::print_code_on(outputStream* st) {
247   ResourceMark m;
248   Disassembler::decode(this, st);
249 }
250 
251 void CodeBlob::prepare_for_archiving_impl() {
252   set_name(nullptr);
253   _oop_maps = nullptr;
254   _mutable_data = nullptr;
255 #ifndef PRODUCT
256   asm_remarks().clear_ref();
257   dbg_strings().clear_ref();
258 #endif /* PRODUCT */
259 }
260 
261 void CodeBlob::prepare_for_archiving() {
262   vptr(_kind)->prepare_for_archiving(this);
263 }
264 
265 void CodeBlob::archive_blob(CodeBlob* blob, address archive_buffer) {
266   blob->copy_to(archive_buffer);
267   CodeBlob* archived_blob = (CodeBlob*)archive_buffer;
268   archived_blob->prepare_for_archiving();
269 }
270 
271 void CodeBlob::post_restore_impl() {
272   // Track memory usage statistic after releasing CodeCache_lock
273   MemoryService::track_code_cache_memory_usage();
274 }
275 
276 void CodeBlob::post_restore() {
277   vptr(_kind)->post_restore(this);

294                            const char* name,
295                            address archived_reloc_data,
296                            ImmutableOopMapSet* archived_oop_maps
297                           )
298 {
299   ThreadInVMfromUnknown __tiv;  // get to VM state in case we block on CodeCache_lock
300 
301   CodeCache::gc_on_allocation();
302 
303   CodeBlob* blob = nullptr;
304   unsigned int size = archived_blob->size();
305   {
306     MutexLocker mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
307     address code_cache_buffer = (address)CodeCache::allocate(size, CodeBlobType::NonNMethod);
308     if (code_cache_buffer != nullptr) {
309       blob = archived_blob->restore(code_cache_buffer,
310                                     name,
311                                     archived_reloc_data,
312                                     archived_oop_maps);
313       assert(blob != nullptr, "sanity check");

314       // Flush the code block
315       ICache::invalidate_range(blob->code_begin(), blob->code_size());
316       CodeCache::commit(blob); // Count adapters
317     }
318   }
319   if (blob != nullptr) {
320     blob->post_restore();
321   }
322   return blob;
323 }
324 
325 //-----------------------------------------------------------------------------------------
326 // Creates a RuntimeBlob from a CodeBuffer and copy code and relocation info.
327 
328 RuntimeBlob::RuntimeBlob(
329   const char* name,
330   CodeBlobKind kind,
331   CodeBuffer* cb,
332   int         size,
333   uint16_t    header_size,
< prev index next >