src/hotspot/share/compiler/oopMap.cpp
changeset 58527 f9cc0141574c
parent 58083 9046db64ca39
child 58679 9c3209ff7550
child 58795 3df2bf731a87
equal deleted inserted replaced
58524:e84d8379815b 58527:f9cc0141574c
    46 #include "opto/optoreg.hpp"
    46 #include "opto/optoreg.hpp"
    47 #endif
    47 #endif
    48 
    48 
    49 // OopMapStream
    49 // OopMapStream
    50 
    50 
    51 OopMapStream::OopMapStream(OopMap* oop_map, int oop_types_mask) {
    51 OopMapStream::OopMapStream(OopMap* oop_map) {
    52   _stream = new CompressedReadStream(oop_map->write_stream()->buffer());
    52   _stream = new CompressedReadStream(oop_map->write_stream()->buffer());
    53   _mask = oop_types_mask;
       
    54   _size = oop_map->omv_count();
    53   _size = oop_map->omv_count();
    55   _position = 0;
    54   _position = 0;
    56   _valid_omv = false;
    55   _valid_omv = false;
    57 }
    56 }
    58 
    57 
    59 OopMapStream::OopMapStream(const ImmutableOopMap* oop_map, int oop_types_mask) {
    58 OopMapStream::OopMapStream(const ImmutableOopMap* oop_map) {
    60   _stream = new CompressedReadStream(oop_map->data_addr());
    59   _stream = new CompressedReadStream(oop_map->data_addr());
    61   _mask = oop_types_mask;
       
    62   _size = oop_map->count();
    60   _size = oop_map->count();
    63   _position = 0;
    61   _position = 0;
    64   _valid_omv = false;
    62   _valid_omv = false;
    65 }
    63 }
    66 
    64 
    67 void OopMapStream::find_next() {
    65 void OopMapStream::find_next() {
    68   while(_position++ < _size) {
    66   if (_position++ < _size) {
    69     _omv.read_from(_stream);
    67     _omv.read_from(_stream);
    70     if(((int)_omv.type() & _mask) > 0) {
    68     _valid_omv = true;
    71       _valid_omv = true;
    69     return;
    72       return;
       
    73     }
       
    74   }
    70   }
    75   _valid_omv = false;
    71   _valid_omv = false;
    76 }
    72 }
    77 
    73 
    78 
    74 
   138 
   134 
   139   assert(reg->value() < _locs_length, "too big reg value for stack size");
   135   assert(reg->value() < _locs_length, "too big reg value for stack size");
   140   assert( _locs_used[reg->value()] == OopMapValue::unused_value, "cannot insert twice" );
   136   assert( _locs_used[reg->value()] == OopMapValue::unused_value, "cannot insert twice" );
   141   debug_only( _locs_used[reg->value()] = x; )
   137   debug_only( _locs_used[reg->value()] = x; )
   142 
   138 
   143   OopMapValue o(reg, x);
   139   OopMapValue o(reg, x, optional);
   144 
       
   145   if(x == OopMapValue::callee_saved_value) {
       
   146     // This can never be a stack location, so we don't need to transform it.
       
   147     assert(optional->is_reg(), "Trying to callee save a stack location");
       
   148     o.set_content_reg(optional);
       
   149   } else if(x == OopMapValue::derived_oop_value) {
       
   150     o.set_content_reg(optional);
       
   151   }
       
   152 
       
   153   o.write_on(write_stream());
   140   o.write_on(write_stream());
   154   increment_count();
   141   increment_count();
   155 }
   142 }
   156 
   143 
   157 
   144 
   158 void OopMap::set_oop(VMReg reg) {
   145 void OopMap::set_oop(VMReg reg) {
   159   set_xxx(reg, OopMapValue::oop_value, VMRegImpl::Bad());
   146   set_xxx(reg, OopMapValue::oop_value, VMRegImpl::Bad());
   160 }
       
   161 
       
   162 
       
   163 void OopMap::set_value(VMReg reg) {
       
   164   // At this time, we don't need value entries in our OopMap.
       
   165 }
   147 }
   166 
   148 
   167 
   149 
   168 void OopMap::set_narrowoop(VMReg reg) {
   150 void OopMap::set_narrowoop(VMReg reg) {
   169   set_xxx(reg, OopMapValue::narrowoop_value, VMRegImpl::Bad());
   151   set_xxx(reg, OopMapValue::narrowoop_value, VMRegImpl::Bad());
   326 
   308 
   327   // handle derived pointers first (otherwise base pointer may be
   309   // handle derived pointers first (otherwise base pointer may be
   328   // changed before derived pointer offset has been collected)
   310   // changed before derived pointer offset has been collected)
   329   OopMapValue omv;
   311   OopMapValue omv;
   330   {
   312   {
   331     OopMapStream oms(map,OopMapValue::derived_oop_value);
   313     OopMapStream oms(map);
   332     if (!oms.is_done()) {
   314     if (!oms.is_done()) {
   333 #ifndef TIERED
   315 #ifndef TIERED
   334       COMPILER1_PRESENT(ShouldNotReachHere();)
   316       COMPILER1_PRESENT(ShouldNotReachHere();)
   335 #if INCLUDE_JVMCI
   317 #if INCLUDE_JVMCI
   336       if (UseJVMCICompiler) {
   318       if (UseJVMCICompiler) {
   338       }
   320       }
   339 #endif
   321 #endif
   340 #endif // !TIERED
   322 #endif // !TIERED
   341       do {
   323       do {
   342         omv = oms.current();
   324         omv = oms.current();
   343         oop* loc = fr->oopmapreg_to_location(omv.reg(),reg_map);
   325         if (omv.type() == OopMapValue::derived_oop_value) {
   344         guarantee(loc != NULL, "missing saved register");
   326           oop* loc = fr->oopmapreg_to_location(omv.reg(),reg_map);
   345         oop *derived_loc = loc;
   327           guarantee(loc != NULL, "missing saved register");
   346         oop *base_loc    = fr->oopmapreg_to_location(omv.content_reg(), reg_map);
   328           oop *derived_loc = loc;
   347         // Ignore NULL oops and decoded NULL narrow oops which
   329           oop *base_loc    = fr->oopmapreg_to_location(omv.content_reg(), reg_map);
   348         // equal to CompressedOops::base() when a narrow oop
   330           // Ignore NULL oops and decoded NULL narrow oops which
   349         // implicit null check is used in compiled code.
   331           // equal to CompressedOops::base() when a narrow oop
   350         // The narrow_oop_base could be NULL or be the address
   332           // implicit null check is used in compiled code.
   351         // of the page below heap depending on compressed oops mode.
   333           // The narrow_oop_base could be NULL or be the address
   352         if (base_loc != NULL && *base_loc != NULL && !CompressedOops::is_base(*base_loc)) {
   334           // of the page below heap depending on compressed oops mode.
   353           derived_oop_fn(base_loc, derived_loc);
   335           if (base_loc != NULL && *base_loc != NULL && !CompressedOops::is_base(*base_loc)) {
       
   336             derived_oop_fn(base_loc, derived_loc);
       
   337           }
   354         }
   338         }
   355         oms.next();
   339         oms.next();
   356       }  while (!oms.is_done());
   340       }  while (!oms.is_done());
   357     }
   341     }
   358   }
   342   }
   359 
   343 
   360   // We want coop and oop oop_types
       
   361   int mask = OopMapValue::oop_value | OopMapValue::narrowoop_value;
       
   362   {
   344   {
   363     for (OopMapStream oms(map,mask); !oms.is_done(); oms.next()) {
   345     // We want coop and oop oop_types
       
   346     for (OopMapStream oms(map); !oms.is_done(); oms.next()) {
   364       omv = oms.current();
   347       omv = oms.current();
   365       oop* loc = fr->oopmapreg_to_location(omv.reg(),reg_map);
   348       oop* loc = fr->oopmapreg_to_location(omv.reg(),reg_map);
   366       // It should be an error if no location can be found for a
   349       // It should be an error if no location can be found for a
   367       // register mentioned as contained an oop of some kind.  Maybe
   350       // register mentioned as contained an oop of some kind.  Maybe
   368       // this was allowed previously because value_value items might
   351       // this was allowed previously because value_value items might
   434   address pc = fr->pc();
   417   address pc = fr->pc();
   435   const ImmutableOopMap* map  = cb->oop_map_for_return_address(pc);
   418   const ImmutableOopMap* map  = cb->oop_map_for_return_address(pc);
   436   assert(map != NULL, "no ptr map found");
   419   assert(map != NULL, "no ptr map found");
   437   DEBUG_ONLY(int nof_callee = 0;)
   420   DEBUG_ONLY(int nof_callee = 0;)
   438 
   421 
   439   for (OopMapStream oms(map, OopMapValue::callee_saved_value); !oms.is_done(); oms.next()) {
   422   for (OopMapStream oms(map); !oms.is_done(); oms.next()) {
   440     OopMapValue omv = oms.current();
   423     OopMapValue omv = oms.current();
   441     VMReg reg = omv.content_reg();
   424     if (omv.type() == OopMapValue::callee_saved_value) {
   442     oop* loc = fr->oopmapreg_to_location(omv.reg(), reg_map);
   425       VMReg reg = omv.content_reg();
   443     reg_map->set_location(reg, (address) loc);
   426       oop* loc = fr->oopmapreg_to_location(omv.reg(), reg_map);
   444     DEBUG_ONLY(nof_callee++;)
   427       reg_map->set_location(reg, (address) loc);
       
   428       DEBUG_ONLY(nof_callee++;)
       
   429     }
   445   }
   430   }
   446 
   431 
   447   // Check that runtime stubs save all callee-saved registers
   432   // Check that runtime stubs save all callee-saved registers
   448 #ifdef COMPILER2
   433 #ifdef COMPILER2
   449   assert(cb->is_compiled_by_c1() || cb->is_compiled_by_jvmci() || !cb->is_runtime_stub() ||
   434   assert(cb->is_compiled_by_c1() || cb->is_compiled_by_jvmci() || !cb->is_runtime_stub() ||
   450          (nof_callee >= SAVED_ON_ENTRY_REG_COUNT || nof_callee >= C_SAVED_ON_ENTRY_REG_COUNT),
   435          (nof_callee >= SAVED_ON_ENTRY_REG_COUNT || nof_callee >= C_SAVED_ON_ENTRY_REG_COUNT),
   451          "must save all");
   436          "must save all");
   452 #endif // COMPILER2
   437 #endif // COMPILER2
   453 }
   438 }
   454 
       
   455 //=============================================================================
       
   456 // Non-Product code
       
   457 
       
   458 #ifndef PRODUCT
       
   459 
       
   460 bool ImmutableOopMap::has_derived_pointer() const {
       
   461 #if !defined(TIERED) && !INCLUDE_JVMCI
       
   462   COMPILER1_PRESENT(return false);
       
   463 #endif // !TIERED
       
   464 #if COMPILER2_OR_JVMCI
       
   465   OopMapStream oms(this,OopMapValue::derived_oop_value);
       
   466   return oms.is_done();
       
   467 #else
       
   468   return false;
       
   469 #endif // COMPILER2_OR_JVMCI
       
   470 }
       
   471 
       
   472 #endif //PRODUCT
       
   473 
   439 
   474 // Printing code is present in product build for -XX:+PrintAssembly.
   440 // Printing code is present in product build for -XX:+PrintAssembly.
   475 
   441 
   476 static
   442 static
   477 void print_register_type(OopMapValue::oop_types x, VMReg optional,
   443 void print_register_type(OopMapValue::oop_types x, VMReg optional,