< 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 "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,
< prev index next >