< prev index next >

src/hotspot/share/compiler/oopMap.cpp

Print this page
rev 50307 : [mq]: cont


 248 
 249 
 250 OopMap* OopMapSet::find_map_at_offset(int pc_offset) const {
 251   int i, len = om_count();
 252   assert( len > 0, "must have pointer maps" );
 253 
 254   // Scan through oopmaps. Stop when current offset is either equal or greater
 255   // than the one we are looking for.
 256   for( i = 0; i < len; i++) {
 257     if( at(i)->offset() >= pc_offset )
 258       break;
 259   }
 260 
 261   assert( i < len, "oopmap not found" );
 262 
 263   OopMap* m = at(i);
 264   assert( m->offset() == pc_offset, "oopmap not found" );
 265   return m;
 266 }
 267 
 268 static void add_derived_oop(oop* base, oop* derived) {

 269 #if !defined(TIERED) && !INCLUDE_JVMCI
 270   COMPILER1_PRESENT(ShouldNotReachHere();)
 271 #endif // !defined(TIERED) && !INCLUDE_JVMCI
 272 #if COMPILER2_OR_JVMCI
 273   DerivedPointerTable::add(derived, base);
 274 #endif // COMPILER2_OR_JVMCI
 275 }

 276 
 277 
 278 #ifndef PRODUCT
 279 static void trace_codeblob_maps(const frame *fr, const RegisterMap *reg_map) {
 280   // Print oopmap and regmap
 281   tty->print_cr("------ ");
 282   CodeBlob* cb = fr->cb();
 283   const ImmutableOopMapSet* maps = cb->oop_maps();
 284   const ImmutableOopMap* map = cb->oop_map_for_return_address(fr->pc());
 285   map->print();
 286   if( cb->is_nmethod() ) {
 287     nmethod* nm = (nmethod*)cb;
 288     // native wrappers have no scope data, it is implied
 289     if (nm->is_native_method()) {
 290       tty->print("bci: 0 (native)");
 291     } else {
 292       ScopeDesc* scope  = nm->scope_desc_at(fr->pc());
 293       tty->print("bci: %d ",scope->bci());
 294     }
 295   }
 296   tty->cr();
 297   fr->print_on(tty);
 298   tty->print("     ");
 299   cb->print_value_on(tty);  tty->cr();
 300   reg_map->print();
 301   tty->print_cr("------ ");
 302 
 303 }
 304 #endif // PRODUCT
 305 
 306 void OopMapSet::oops_do(const frame *fr, const RegisterMap* reg_map, OopClosure* f) {
 307   // add derived oops to a table
 308   all_do(fr, reg_map, f, add_derived_oop, &do_nothing_cl);
 309 }
 310 
 311 
 312 void OopMapSet::all_do(const frame *fr, const RegisterMap *reg_map,
 313                        OopClosure* oop_fn, void derived_oop_fn(oop*, oop*),
 314                        OopClosure* value_fn) {
 315   CodeBlob* cb = fr->cb();
 316   assert(cb != NULL, "no codeblob");
 317 
 318   NOT_PRODUCT(if (TraceCodeBlobStacks) trace_codeblob_maps(fr, reg_map);)
 319 
 320   const ImmutableOopMapSet* maps = cb->oop_maps();
 321   const ImmutableOopMap* map = cb->oop_map_for_return_address(fr->pc());
 322   assert(map != NULL, "no ptr map found");
 323 
 324   // handle derived pointers first (otherwise base pointer may be
 325   // changed before derived pointer offset has been collected)
 326   OopMapValue omv;
 327   {
 328     OopMapStream oms(map,OopMapValue::derived_oop_value);
 329     if (!oms.is_done()) {
 330 #ifndef TIERED
 331       COMPILER1_PRESENT(ShouldNotReachHere();)
 332 #if INCLUDE_JVMCI
 333       if (UseJVMCICompiler) {
 334         ShouldNotReachHere();
 335       }
 336 #endif
 337 #endif // !TIERED
 338       // Protect the operation on the derived pointers.  This
 339       // protects the addition of derived pointers to the shared
 340       // derived pointer table in DerivedPointerTable::add().
 341       MutexLockerEx x(DerivedPointerTableGC_lock, Mutex::_no_safepoint_check_flag);
 342       do {
 343         omv = oms.current();
 344         oop* loc = fr->oopmapreg_to_location(omv.reg(),reg_map);
 345         guarantee(loc != NULL, "missing saved register");
 346         oop *derived_loc = loc;
 347         oop *base_loc    = fr->oopmapreg_to_location(omv.content_reg(), reg_map);
 348         // Ignore NULL oops and decoded NULL narrow oops which
 349         // equal to Universe::narrow_oop_base when a narrow oop
 350         // implicit null check is used in compiled code.
 351         // The narrow_oop_base could be NULL or be the address
 352         // of the page below heap depending on compressed oops mode.
 353         if (base_loc != NULL && *base_loc != (oop)NULL && !Universe::is_narrow_oop_base(*base_loc)) {
 354           derived_oop_fn(base_loc, derived_loc);
 355         }
 356         oms.next();
 357       }  while (!oms.is_done());























 358     }
 359   }

 360 


















 361   // We want coop and oop oop_types
 362   int mask = OopMapValue::oop_value | OopMapValue::narrowoop_value;
 363   {
 364     for (OopMapStream oms(map,mask); !oms.is_done(); oms.next()) {
 365       omv = oms.current();
 366       oop* loc = fr->oopmapreg_to_location(omv.reg(),reg_map);
 367       // It should be an error if no location can be found for a
 368       // register mentioned as contained an oop of some kind.  Maybe
 369       // this was allowed previously because value_value items might
 370       // be missing?







 371       guarantee(loc != NULL, "missing saved register");
 372       if ( omv.type() == OopMapValue::oop_value ) {
 373         oop val = *loc;
 374         if (val == (oop)NULL || Universe::is_narrow_oop_base(val)) {
 375           // Ignore NULL oops and decoded NULL narrow oops which
 376           // equal to Universe::narrow_oop_base when a narrow oop
 377           // implicit null check is used in compiled code.
 378           // The narrow_oop_base could be NULL or be the address
 379           // of the page below heap depending on compressed oops mode.
 380           continue;
 381         }
 382 #ifdef ASSERT
 383         if ((((uintptr_t)loc & (sizeof(*loc)-1)) != 0) ||
 384             !Universe::heap()->is_in_or_null(*loc)) {

 385           tty->print_cr("# Found non oop pointer.  Dumping state at failure");
 386           // try to dump out some helpful debugging information
 387           trace_codeblob_maps(fr, reg_map);
 388           omv.print();
 389           tty->print_cr("register r");
 390           omv.reg()->print();
 391           tty->print_cr("loc = %p *loc = %p\n", loc, (address)*loc);



 392           // do the real assert.
 393           assert(Universe::heap()->is_in_or_null(*loc), "found non oop pointer");
 394         }
 395 #endif // ASSERT
 396         oop_fn->do_oop(loc);
 397       } else if ( omv.type() == OopMapValue::narrowoop_value ) {
 398         narrowOop *nl = (narrowOop*)loc;
 399 #ifndef VM_LITTLE_ENDIAN
 400         VMReg vmReg = omv.reg();
 401         // Don't do this on SPARC float registers as they can be individually addressed
 402         if (!vmReg->is_stack() SPARC_ONLY(&& !vmReg->is_FloatRegister())) {
 403           // compressed oops in registers only take up 4 bytes of an
 404           // 8 byte register but they are in the wrong part of the
 405           // word so adjust loc to point at the right place.
 406           nl = (narrowOop*)((address)nl + 4);
 407         }
 408 #endif
 409         oop_fn->do_oop(nl);
 410       }
 411     }
 412   }





 413 }
 414 
 415 
 416 // Update callee-saved register info for the following frame
 417 void OopMapSet::update_register_map(const frame *fr, RegisterMap *reg_map) {
 418   ResourceMark rm;
 419   CodeBlob* cb = fr->cb();
 420   assert(cb != NULL, "no codeblob");
 421 
 422   // Any reg might be saved by a safepoint handler (see generate_handler_blob).
 423   assert( reg_map->_update_for_id == NULL || fr->is_older(reg_map->_update_for_id),
 424          "already updated this map; do not 'update' it twice!" );
 425   debug_only(reg_map->_update_for_id = fr->id());
 426 
 427   // Check if caller must update oop argument
 428   assert((reg_map->include_argument_oops() ||
 429           !cb->caller_must_gc_arguments(reg_map->thread())),
 430          "include_argument_oops should already be set");
 431 
 432   // Scan through oopmap and find location of all callee-saved registers




 248 
 249 
 250 OopMap* OopMapSet::find_map_at_offset(int pc_offset) const {
 251   int i, len = om_count();
 252   assert( len > 0, "must have pointer maps" );
 253 
 254   // Scan through oopmaps. Stop when current offset is either equal or greater
 255   // than the one we are looking for.
 256   for( i = 0; i < len; i++) {
 257     if( at(i)->offset() >= pc_offset )
 258       break;
 259   }
 260 
 261   assert( i < len, "oopmap not found" );
 262 
 263   OopMap* m = at(i);
 264   assert( m->offset() == pc_offset, "oopmap not found" );
 265   return m;
 266 }
 267 
 268 class AddDerivedOop : public DerivedOopClosure {
 269   virtual void do_derived_oop(oop* base, oop* derived) {
 270 #if !defined(TIERED) && !INCLUDE_JVMCI
 271   COMPILER1_PRESENT(ShouldNotReachHere();)
 272 #endif // !defined(TIERED) && !INCLUDE_JVMCI
 273 #if COMPILER2_OR_JVMCI
 274   DerivedPointerTable::add(derived, base);
 275 #endif // COMPILER2_OR_JVMCI
 276   }
 277 } add_derived_oop;
 278 
 279 
 280 #ifndef PRODUCT
 281 static void trace_codeblob_maps(const frame *fr, const RegisterMap *reg_map) {
 282   // Print oopmap and regmap
 283   tty->print_cr("------ ");
 284   CodeBlob* cb = fr->cb();
 285   const ImmutableOopMapSet* maps = cb->oop_maps();
 286   const ImmutableOopMap* map = cb->oop_map_for_return_address(fr->pc());
 287   map->print();
 288   if( cb->is_nmethod() ) {
 289     nmethod* nm = (nmethod*)cb;
 290     // native wrappers have no scope data, it is implied
 291     if (nm->is_native_method()) {
 292       tty->print("bci: 0 (native)");
 293     } else {
 294       ScopeDesc* scope  = nm->scope_desc_at(fr->pc());
 295       tty->print("bci: %d ",scope->bci());
 296     }
 297   }
 298   tty->cr();
 299   fr->print_on(tty);
 300   tty->print("     ");
 301   cb->print_value_on(tty);  tty->cr();
 302   reg_map->print();
 303   tty->print_cr("------ ");
 304 
 305 }
 306 #endif // PRODUCT
 307 
 308 void OopMapSet::oops_do(const frame *fr, const RegisterMap* reg_map, OopClosure* f, DerivedOopClosure* df) {
 309   // add_derived_oop: add derived oops to a table
 310   all_do(fr, reg_map, f, df != NULL ? df : &add_derived_oop, &do_nothing_cl);
 311 }
 312 
 313 static void walk_derived_pointers1(OopMapStream& oms, const frame *fr, const RegisterMap *reg_map, DerivedOopClosure* derived_oop_fn) {














 314   OopMapValue omv;















 315   do {
 316     omv = oms.current();
 317     oop* loc = fr->oopmapreg_to_location(omv.reg(),reg_map);
 318     guarantee(loc != NULL, "missing saved register");
 319     oop *derived_loc = loc;
 320     oop *base_loc    = fr->oopmapreg_to_location(omv.content_reg(), reg_map);
 321     // Ignore NULL oops and decoded NULL narrow oops which
 322     // equal to Universe::narrow_oop_base when a narrow oop
 323     // implicit null check is used in compiled code.
 324     // The narrow_oop_base could be NULL or be the address
 325     // of the page below heap depending on compressed oops mode.
 326     if (base_loc != NULL && *base_loc != (oop)NULL && !Universe::is_narrow_oop_base(*base_loc)) {
 327       derived_oop_fn->do_derived_oop(base_loc, derived_loc);
 328     }
 329     oms.next();
 330   } while (!oms.is_done());
 331 }
 332 
 333 static void walk_derived_pointers(const frame *fr, const ImmutableOopMap* map, const RegisterMap *reg_map, 
 334                                   DerivedOopClosure* derived_oop_fn) {
 335   OopMapStream oms(map,OopMapValue::derived_oop_value);
 336   if (!oms.is_done()) {
 337 #ifndef TIERED
 338     COMPILER1_PRESENT(ShouldNotReachHere();)
 339 #if INCLUDE_JVMCI
 340     if (UseJVMCICompiler) {
 341       ShouldNotReachHere();
 342     }
 343 #endif
 344 #endif // !TIERED
 345 
 346     if (derived_oop_fn == &add_derived_oop) { // TODO: UGLY
 347       // Protect the operation on the derived pointers.  This
 348       // protects the addition of derived pointers to the shared
 349       // derived pointer table in DerivedPointerTable::add().
 350       MutexLockerEx x(DerivedPointerTableGC_lock, Mutex::_no_safepoint_check_flag);
 351       walk_derived_pointers1(oms, fr, reg_map, derived_oop_fn);
 352     } else {
 353       walk_derived_pointers1(oms, fr, reg_map, derived_oop_fn);
 354     }
 355   }
 356 }
 357 
 358 void OopMapSet::all_do(const frame *fr, const RegisterMap *reg_map,
 359                        OopClosure* oop_fn, DerivedOopClosure* derived_oop_fn,
 360                        OopClosure* value_fn) {
 361   CodeBlob* cb = fr->cb();
 362   assert(cb != NULL, "no codeblob");
 363 
 364   NOT_PRODUCT(if (TraceCodeBlobStacks) trace_codeblob_maps(fr, reg_map);)
 365 
 366   const ImmutableOopMapSet* maps = cb->oop_maps();
 367   const ImmutableOopMap* map = cb->oop_map_for_return_address(fr->pc());
 368   assert(map != NULL, "no ptr map found");
 369 
 370   // handle derived pointers first (otherwise base pointer may be
 371   // changed before derived pointer offset has been collected)
 372   if (reg_map->validate_oops())
 373     walk_derived_pointers(fr, map, reg_map, derived_oop_fn);
 374 
 375   OopMapValue omv;
 376   // We want coop and oop oop_types
 377   int mask = OopMapValue::oop_value | OopMapValue::narrowoop_value;
 378   {
 379     for (OopMapStream oms(map,mask); !oms.is_done(); oms.next()) {
 380       omv = oms.current();
 381       oop* loc = fr->oopmapreg_to_location(omv.reg(),reg_map);
 382       // It should be an error if no location can be found for a
 383       // register mentioned as contained an oop of some kind.  Maybe
 384       // this was allowed previously because value_value items might
 385       // be missing?
 386 #ifdef ASSERT
 387     if (loc == NULL) {
 388       VMReg reg = omv.reg();
 389       tty->print_cr("missing saved register: reg: %ld %s loc: %p", reg->value(), reg->name(), loc);
 390       fr->print_on(tty);
 391     }
 392 #endif
 393       guarantee(loc != NULL, "missing saved register");
 394       if ( omv.type() == OopMapValue::oop_value ) {
 395         oop val = *loc;
 396         if (val == (oop)NULL || Universe::is_narrow_oop_base(val)) {
 397           // Ignore NULL oops and decoded NULL narrow oops which
 398           // equal to Universe::narrow_oop_base when a narrow oop
 399           // implicit null check is used in compiled code.
 400           // The narrow_oop_base could be NULL or be the address
 401           // of the page below heap depending on compressed oops mode.
 402           continue;
 403         }
 404 #ifdef ASSERT
 405         if (reg_map->validate_oops() && 
 406             ((((uintptr_t)loc & (sizeof(*loc)-1)) != 0) ||
 407              !Universe::heap()->is_in_or_null(*loc))) {
 408           tty->print_cr("# Found non oop pointer.  Dumping state at failure");
 409           // try to dump out some helpful debugging information
 410           trace_codeblob_maps(fr, reg_map);
 411           omv.print();
 412           tty->print_cr("register r");
 413           omv.reg()->print();
 414           tty->print_cr("loc = %p *loc = %p\n", loc, (address)*loc);
 415           // os::print_location(tty, (intptr_t)*loc);
 416           tty->print("pc: "); os::print_location(tty, (intptr_t)fr->pc());
 417           fr->print_value_on(tty, NULL);
 418           // do the real assert.
 419           assert(Universe::heap()->is_in_or_null(*loc), "found non oop pointer");
 420         }
 421 #endif // ASSERT
 422         oop_fn->do_oop(loc);
 423       } else if ( omv.type() == OopMapValue::narrowoop_value ) {
 424         narrowOop *nl = (narrowOop*)loc;
 425 #ifndef VM_LITTLE_ENDIAN
 426         VMReg vmReg = omv.reg();
 427         // Don't do this on SPARC float registers as they can be individually addressed
 428         if (!vmReg->is_stack() SPARC_ONLY(&& !vmReg->is_FloatRegister())) {
 429           // compressed oops in registers only take up 4 bytes of an
 430           // 8 byte register but they are in the wrong part of the
 431           // word so adjust loc to point at the right place.
 432           nl = (narrowOop*)((address)nl + 4);
 433         }
 434 #endif
 435         oop_fn->do_oop(nl);
 436       }
 437     }
 438   }
 439 
 440   // When thawing continuation frames, we want to walk derived pointers
 441   // after walking oops
 442   if (!reg_map->validate_oops())
 443     walk_derived_pointers(fr, map, reg_map, derived_oop_fn);
 444 }
 445 
 446 
 447 // Update callee-saved register info for the following frame
 448 void OopMapSet::update_register_map(const frame *fr, RegisterMap *reg_map) {
 449   ResourceMark rm;
 450   CodeBlob* cb = fr->cb();
 451   assert(cb != NULL, "no codeblob");
 452 
 453   // Any reg might be saved by a safepoint handler (see generate_handler_blob).
 454   assert( reg_map->_update_for_id == NULL || fr->is_older(reg_map->_update_for_id),
 455          "already updated this map; do not 'update' it twice!" );
 456   debug_only(reg_map->_update_for_id = fr->id());
 457 
 458   // Check if caller must update oop argument
 459   assert((reg_map->include_argument_oops() ||
 460           !cb->caller_must_gc_arguments(reg_map->thread())),
 461          "include_argument_oops should already be set");
 462 
 463   // Scan through oopmap and find location of all callee-saved registers


< prev index next >