< prev index next >

src/hotspot/share/compiler/oopMap.cpp

Print this page

 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 "precompiled.hpp"
 26 #include "code/codeBlob.hpp"
 27 #include "code/codeCache.hpp"
 28 #include "code/nmethod.hpp"
 29 #include "code/scopeDesc.hpp"
 30 #include "compiler/oopMap.hpp"
 31 #include "gc/shared/collectedHeap.hpp"
 32 #include "memory/allocation.inline.hpp"
 33 #include "memory/iterator.hpp"
 34 #include "memory/resourceArea.hpp"
 35 #include "memory/universe.hpp"
 36 #include "oops/compressedOops.hpp"
 37 #include "runtime/frame.inline.hpp"
 38 #include "runtime/handles.inline.hpp"
 39 #include "runtime/signature.hpp"

 40 #include "utilities/align.hpp"
 41 #include "utilities/lockFreeStack.hpp"
 42 #ifdef COMPILER1
 43 #include "c1/c1_Defs.hpp"
 44 #endif
 45 #ifdef COMPILER2
 46 #include "opto/optoreg.hpp"
 47 #endif
 48 
 49 // OopMapStream
 50 
 51 OopMapStream::OopMapStream(OopMap* oop_map) {
 52   _stream = new CompressedReadStream(oop_map->write_stream()->buffer());
 53   _size = oop_map->omv_count();
 54   _position = 0;
 55   _valid_omv = false;
 56 }
 57 
 58 OopMapStream::OopMapStream(const ImmutableOopMap* oop_map) {
 59   _stream = new CompressedReadStream(oop_map->data_addr());

254       }
255 
256 #ifndef TIERED
257       COMPILER1_PRESENT(ShouldNotReachHere();)
258 #if INCLUDE_JVMCI
259       if (UseJVMCICompiler) {
260         ShouldNotReachHere();
261       }
262 #endif
263 #endif // !TIERED
264       oop* loc = fr->oopmapreg_to_location(omv.reg(),reg_map);
265       guarantee(loc != NULL, "missing saved register");
266       oop *derived_loc = loc;
267       oop *base_loc    = fr->oopmapreg_to_location(omv.content_reg(), reg_map);
268       // Ignore NULL oops and decoded NULL narrow oops which
269       // equal to CompressedOops::base() when a narrow oop
270       // implicit null check is used in compiled code.
271       // The narrow_oop_base could be NULL or be the address
272       // of the page below heap depending on compressed oops mode.
273       if (base_loc != NULL && *base_loc != NULL && !CompressedOops::is_base(*base_loc)) {











274         derived_oop_fn(base_loc, derived_loc);
275       }
276     }
277   }
278 
279   {

280     // We want coop and oop oop_types
281     for (OopMapStream oms(map); !oms.is_done(); oms.next()) {
282       OopMapValue omv = oms.current();
283       oop* loc = fr->oopmapreg_to_location(omv.reg(),reg_map);
284       // It should be an error if no location can be found for a
285       // register mentioned as contained an oop of some kind.  Maybe
286       // this was allowed previously because value_value items might
287       // be missing?
288       guarantee(loc != NULL, "missing saved register");
289       if ( omv.type() == OopMapValue::oop_value ) {
290         oop val = *loc;
291         if (val == NULL || CompressedOops::is_base(val)) {
292           // Ignore NULL oops and decoded NULL narrow oops which
293           // equal to CompressedOops::base() when a narrow oop
294           // implicit null check is used in compiled code.
295           // The narrow_oop_base could be NULL or be the address
296           // of the page below heap depending on compressed oops mode.
297           continue;
298         }





































299 #ifdef ASSERT
300         if ((((uintptr_t)loc & (sizeof(*loc)-1)) != 0) ||
301             !Universe::heap()->is_in_or_null(*loc)) {
302           tty->print_cr("# Found non oop pointer.  Dumping state at failure");
303           // try to dump out some helpful debugging information
304           trace_codeblob_maps(fr, reg_map);
305           omv.print();
306           tty->print_cr("register r");
307           omv.reg()->print();
308           tty->print_cr("loc = %p *loc = %p\n", loc, cast_from_oop<address>(*loc));
309           // do the real assert.
310           assert(Universe::heap()->is_in_or_null(*loc), "found non oop pointer");
311         }
312 #endif // ASSERT
313         oop_fn->do_oop(loc);
314       } else if ( omv.type() == OopMapValue::narrowoop_value ) {
315         narrowOop *nl = (narrowOop*)loc;
316 #ifndef VM_LITTLE_ENDIAN
317         VMReg vmReg = omv.reg();
318         if (!vmReg->is_stack()) {
319           // compressed oops in registers only take up 4 bytes of an
320           // 8 byte register but they are in the wrong part of the
321           // word so adjust loc to point at the right place.
322           nl = (narrowOop*)((address)nl + 4);
323         }
324 #endif
325         oop_fn->do_oop(nl);
326       }
327     }
328   }
329 }
330 

















































331 
332 // Update callee-saved register info for the following frame
333 void OopMapSet::update_register_map(const frame *fr, RegisterMap *reg_map) {
334   ResourceMark rm;
335   CodeBlob* cb = fr->cb();
336   assert(cb != NULL, "no codeblob");
337 
338   // Any reg might be saved by a safepoint handler (see generate_handler_blob).
339   assert( reg_map->_update_for_id == NULL || fr->is_older(reg_map->_update_for_id),
340          "already updated this map; do not 'update' it twice!" );
341   debug_only(reg_map->_update_for_id = fr->id());
342 
343   // Check if caller must update oop argument
344   assert((reg_map->include_argument_oops() ||
345           !cb->caller_must_gc_arguments(reg_map->thread())),
346          "include_argument_oops should already be set");
347 
348   // Scan through oopmap and find location of all callee-saved registers
349   // (we do not do update in place, since info could be overwritten)
350 

 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 "precompiled.hpp"
 26 #include "code/codeBlob.hpp"
 27 #include "code/codeCache.hpp"
 28 #include "code/nmethod.hpp"
 29 #include "code/scopeDesc.hpp"
 30 #include "compiler/oopMap.hpp"
 31 #include "gc/shared/collectedHeap.hpp"
 32 #include "memory/allocation.inline.hpp"
 33 #include "memory/iterator.inline.hpp"
 34 #include "memory/resourceArea.hpp"
 35 #include "memory/universe.hpp"
 36 #include "oops/compressedOops.hpp"
 37 #include "runtime/frame.inline.hpp"
 38 #include "runtime/handles.inline.hpp"
 39 #include "runtime/signature.hpp"
 40 #include "runtime/vframe_hp.hpp"
 41 #include "utilities/align.hpp"
 42 #include "utilities/lockFreeStack.hpp"
 43 #ifdef COMPILER1
 44 #include "c1/c1_Defs.hpp"
 45 #endif
 46 #ifdef COMPILER2
 47 #include "opto/optoreg.hpp"
 48 #endif
 49 
 50 // OopMapStream
 51 
 52 OopMapStream::OopMapStream(OopMap* oop_map) {
 53   _stream = new CompressedReadStream(oop_map->write_stream()->buffer());
 54   _size = oop_map->omv_count();
 55   _position = 0;
 56   _valid_omv = false;
 57 }
 58 
 59 OopMapStream::OopMapStream(const ImmutableOopMap* oop_map) {
 60   _stream = new CompressedReadStream(oop_map->data_addr());

255       }
256 
257 #ifndef TIERED
258       COMPILER1_PRESENT(ShouldNotReachHere();)
259 #if INCLUDE_JVMCI
260       if (UseJVMCICompiler) {
261         ShouldNotReachHere();
262       }
263 #endif
264 #endif // !TIERED
265       oop* loc = fr->oopmapreg_to_location(omv.reg(),reg_map);
266       guarantee(loc != NULL, "missing saved register");
267       oop *derived_loc = loc;
268       oop *base_loc    = fr->oopmapreg_to_location(omv.content_reg(), reg_map);
269       // Ignore NULL oops and decoded NULL narrow oops which
270       // equal to CompressedOops::base() when a narrow oop
271       // implicit null check is used in compiled code.
272       // The narrow_oop_base could be NULL or be the address
273       // of the page below heap depending on compressed oops mode.
274       if (base_loc != NULL && *base_loc != NULL && !CompressedOops::is_base(*base_loc)) {
275 
276         if (UseStackAllocationRuntime) {
277           intptr_t *stack_base = fr->unextended_sp();
278           intptr_t *stack_top = stack_base + cb->frame_size();
279           intptr_t *oop_ptr = cast_from_oop<intptr_t *>(*base_loc);
280           if ((stack_base <= oop_ptr) && (oop_ptr < stack_top)) {
281             // If the base is a stack oop just continue because stack oops will not move
282             continue;
283           }
284         }
285 
286         derived_oop_fn(base_loc, derived_loc);
287       }
288     }
289   }
290 
291   {
292     GrowableArray<oop> stack_oops;
293     // We want coop and oop oop_types
294     for (OopMapStream oms(map); !oms.is_done(); oms.next()) {
295       OopMapValue omv = oms.current();
296       oop* loc = fr->oopmapreg_to_location(omv.reg(),reg_map);
297       // It should be an error if no location can be found for a
298       // register mentioned as contained an oop of some kind.  Maybe
299       // this was allowed previously because value_value items might
300       // be missing?
301       guarantee(loc != NULL, "missing saved register");
302       if ( omv.type() == OopMapValue::oop_value ) {
303         oop val = *loc;
304         if (val == NULL || CompressedOops::is_base(val)) {
305           // Ignore NULL oops and decoded NULL narrow oops which
306           // equal to CompressedOops::base() when a narrow oop
307           // implicit null check is used in compiled code.
308           // The narrow_oop_base could be NULL or be the address
309           // of the page below heap depending on compressed oops mode.
310           continue;
311         }
312 
313         // TODO can we check if a CodeBlob includes stack allocated objects?
314         // If macro.cpp tags the compilation as including stack allocated objects
315         // then it should be possible to set something on codeblob.
316         if (UseStackAllocationRuntime) {
317           intptr_t *base = fr->unextended_sp();
318           intptr_t *top = base + cb->frame_size();
319           intptr_t *oop_ptr = cast_from_oop<intptr_t *>(val);
320           // If a stack slot points to a stack allocated object handle it
321           if ((base <= oop_ptr) && (oop_ptr < top)) {
322             // If we are verifying the stack, do extra checking that this
323             // stack location is indeed one of the stack allocated objects we
324             // have described in the oop maps.
325             if (VerifyStack) {
326               Thread* current_thread = Thread::current();
327               ResourceMark rm(current_thread);
328               HandleMark hm(current_thread);
329 
330               vframe*  vf = vframe::new_vframe(fr, reg_map, reg_map->thread());
331               if (vf->is_compiled_frame()) {
332                 compiledVFrame* cvf = compiledVFrame::cast(vf);
333                 GrowableArray<ScopeValue*>* objects = cvf->scope()->objects();
334 
335                 // Match the stack location offset to any described
336                 // stack allocated objects.
337                 // In case we didn't find this location in our described objects
338                 // we just continue, it's not really a stack oop.
339                 if (cvf->match_object_to_stack_oop(oop_ptr, base, objects) == NULL) {
340                   continue;
341                 }
342               }
343             }
344 
345             OopMapSet::stack_oop_do(loc, oop_fn, &stack_oops, base, top);
346             continue;
347           }
348         }
349 #ifdef ASSERT
350         if ((((uintptr_t)loc & (sizeof(*loc)-1)) != 0) ||
351             !Universe::heap()->is_in_or_null(*loc)) {
352           tty->print_cr("# Found non oop pointer.  Dumping state at failure");
353           // try to dump out some helpful debugging information
354           trace_codeblob_maps(fr, reg_map);
355           omv.print();
356           tty->print_cr("register r");
357           omv.reg()->print();
358           tty->print_cr("loc = %p *loc = %p\n", loc, cast_from_oop<address>(*loc));
359           // do the real assert.
360           assert(Universe::heap()->is_in_or_null(*loc), "found non oop pointer");
361         }
362 #endif // ASSERT
363         oop_fn->do_oop(loc);
364       } else if ( omv.type() == OopMapValue::narrowoop_value ) {
365         narrowOop *nl = (narrowOop*)loc;
366 #ifndef VM_LITTLE_ENDIAN
367         VMReg vmReg = omv.reg();
368         if (!vmReg->is_stack()) {
369           // compressed oops in registers only take up 4 bytes of an
370           // 8 byte register but they are in the wrong part of the
371           // word so adjust loc to point at the right place.
372           nl = (narrowOop*)((address)nl + 4);
373         }
374 #endif
375         oop_fn->do_oop(nl);
376       }
377     }
378   }
379 }
380 
381 class OopClosureWalker: public BasicOopIterateClosure {
382 protected:
383   OopClosure *_closure;
384   GrowableArray<oop> *_stack_oops;
385   intptr_t *_base;
386   intptr_t *_top;
387 
388 public:
389   OopClosureWalker(OopClosure *closure, GrowableArray<oop> *stack_oops, intptr_t *base, intptr_t *top) :
390     BasicOopIterateClosure(NULL),
391     _closure(closure),
392     _stack_oops(stack_oops),
393     _base(base),
394     _top(top) {}
395 
396   void do_oop(oop *o) {
397     intptr_t *oop_ptr = cast_from_oop<intptr_t *>(*o);
398     if ((_base <= oop_ptr) && (oop_ptr < _top)) {
399       OopMapSet::stack_oop_do(o, _closure, _stack_oops, _base, _top);
400     } else {
401       _closure->do_oop(o);
402     }
403   }
404   void do_oop(narrowOop *o) {
405     oop obj = RawAccess<>::oop_load(o);
406     intptr_t *oop_ptr = cast_from_oop<intptr_t *>(obj);
407     if ((_base <= oop_ptr) && (oop_ptr < _top)) {
408       // no references to stack allocated oops in UseCompressedOops
409       assert(false, "unreachable");
410     } else {
411       _closure->do_oop(o);
412     }
413   }
414 
415   debug_only(virtual bool should_verify_oops() { return false; })
416 };
417 
418 void OopMapSet::stack_oop_do(oop *p, OopClosure* oop_fn, GrowableArray<oop> *stack_oops, intptr_t *stack_base, intptr_t *stack_top) {
419   oop o = RawAccess<IS_NOT_NULL>::oop_load(p);
420   Klass *t = o->klass();
421   assert(t->is_klass(), "Has to be a class");
422   if (!t->is_typeArray_klass()) {
423     if (stack_oops->append_if_missing(o)) {
424       OopClosureWalker walk_elements(oop_fn, stack_oops, stack_base, stack_top);
425       o->oop_iterate(&walk_elements);
426     }
427   }
428 }
429 
430 
431 // Update callee-saved register info for the following frame
432 void OopMapSet::update_register_map(const frame *fr, RegisterMap *reg_map) {
433   ResourceMark rm;
434   CodeBlob* cb = fr->cb();
435   assert(cb != NULL, "no codeblob");
436 
437   // Any reg might be saved by a safepoint handler (see generate_handler_blob).
438   assert( reg_map->_update_for_id == NULL || fr->is_older(reg_map->_update_for_id),
439          "already updated this map; do not 'update' it twice!" );
440   debug_only(reg_map->_update_for_id = fr->id());
441 
442   // Check if caller must update oop argument
443   assert((reg_map->include_argument_oops() ||
444           !cb->caller_must_gc_arguments(reg_map->thread())),
445          "include_argument_oops should already be set");
446 
447   // Scan through oopmap and find location of all callee-saved registers
448   // (we do not do update in place, since info could be overwritten)
449 
< prev index next >