src/hotspot/share/compiler/oopMap.cpp
branchdatagramsocketimpl-branch
changeset 58678 9cf78a70fa4f
parent 54960 e46fe26d7f77
child 58679 9c3209ff7550
equal deleted inserted replaced
58677:13588c901957 58678:9cf78a70fa4f
    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
   377           // The narrow_oop_base could be NULL or be the address
   360           // The narrow_oop_base could be NULL or be the address
   378           // of the page below heap depending on compressed oops mode.
   361           // of the page below heap depending on compressed oops mode.
   379           continue;
   362           continue;
   380         }
   363         }
   381 #ifdef ASSERT
   364 #ifdef ASSERT
   382         // We can not verify the oop here if we are using ZGC, the oop
   365         if ((((uintptr_t)loc & (sizeof(*loc)-1)) != 0) ||
   383         // will be bad in case we had a safepoint between a load and a
   366             !Universe::heap()->is_in_or_null(*loc)) {
   384         // load barrier.
       
   385         if (!UseZGC &&
       
   386             ((((uintptr_t)loc & (sizeof(*loc)-1)) != 0) ||
       
   387              !Universe::heap()->is_in_or_null(*loc))) {
       
   388           tty->print_cr("# Found non oop pointer.  Dumping state at failure");
   367           tty->print_cr("# Found non oop pointer.  Dumping state at failure");
   389           // try to dump out some helpful debugging information
   368           // try to dump out some helpful debugging information
   390           trace_codeblob_maps(fr, reg_map);
   369           trace_codeblob_maps(fr, reg_map);
   391           omv.print();
   370           omv.print();
   392           tty->print_cr("register r");
   371           tty->print_cr("register r");
   438   address pc = fr->pc();
   417   address pc = fr->pc();
   439   const ImmutableOopMap* map  = cb->oop_map_for_return_address(pc);
   418   const ImmutableOopMap* map  = cb->oop_map_for_return_address(pc);
   440   assert(map != NULL, "no ptr map found");
   419   assert(map != NULL, "no ptr map found");
   441   DEBUG_ONLY(int nof_callee = 0;)
   420   DEBUG_ONLY(int nof_callee = 0;)
   442 
   421 
   443   for (OopMapStream oms(map, OopMapValue::callee_saved_value); !oms.is_done(); oms.next()) {
   422   for (OopMapStream oms(map); !oms.is_done(); oms.next()) {
   444     OopMapValue omv = oms.current();
   423     OopMapValue omv = oms.current();
   445     VMReg reg = omv.content_reg();
   424     if (omv.type() == OopMapValue::callee_saved_value) {
   446     oop* loc = fr->oopmapreg_to_location(omv.reg(), reg_map);
   425       VMReg reg = omv.content_reg();
   447     reg_map->set_location(reg, (address) loc);
   426       oop* loc = fr->oopmapreg_to_location(omv.reg(), reg_map);
   448     DEBUG_ONLY(nof_callee++;)
   427       reg_map->set_location(reg, (address) loc);
       
   428       DEBUG_ONLY(nof_callee++;)
       
   429     }
   449   }
   430   }
   450 
   431 
   451   // Check that runtime stubs save all callee-saved registers
   432   // Check that runtime stubs save all callee-saved registers
   452 #ifdef COMPILER2
   433 #ifdef COMPILER2
   453   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() ||
   454          (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),
   455          "must save all");
   436          "must save all");
   456 #endif // COMPILER2
   437 #endif // COMPILER2
   457 }
   438 }
   458 
       
   459 //=============================================================================
       
   460 // Non-Product code
       
   461 
       
   462 #ifndef PRODUCT
       
   463 
       
   464 bool ImmutableOopMap::has_derived_pointer() const {
       
   465 #if !defined(TIERED) && !INCLUDE_JVMCI
       
   466   COMPILER1_PRESENT(return false);
       
   467 #endif // !TIERED
       
   468 #if COMPILER2_OR_JVMCI
       
   469   OopMapStream oms(this,OopMapValue::derived_oop_value);
       
   470   return oms.is_done();
       
   471 #else
       
   472   return false;
       
   473 #endif // COMPILER2_OR_JVMCI
       
   474 }
       
   475 
       
   476 #endif //PRODUCT
       
   477 
   439 
   478 // Printing code is present in product build for -XX:+PrintAssembly.
   440 // Printing code is present in product build for -XX:+PrintAssembly.
   479 
   441 
   480 static
   442 static
   481 void print_register_type(OopMapValue::oop_types x, VMReg optional,
   443 void print_register_type(OopMapValue::oop_types x, VMReg optional,
   734 
   696 
   735 ImmutableOopMapSet* ImmutableOopMapBuilder::build() {
   697 ImmutableOopMapSet* ImmutableOopMapBuilder::build() {
   736   _required = heap_size();
   698   _required = heap_size();
   737 
   699 
   738   // We need to allocate a chunk big enough to hold the ImmutableOopMapSet and all of its ImmutableOopMaps
   700   // We need to allocate a chunk big enough to hold the ImmutableOopMapSet and all of its ImmutableOopMaps
   739   address buffer = (address) NEW_C_HEAP_ARRAY(unsigned char, _required, mtCode);
   701   address buffer = NEW_C_HEAP_ARRAY(unsigned char, _required, mtCode);
   740   return generate_into(buffer);
   702   return generate_into(buffer);
   741 }
   703 }
   742 
   704 
   743 ImmutableOopMapSet* ImmutableOopMapSet::build_from(const OopMapSet* oopmap_set) {
   705 ImmutableOopMapSet* ImmutableOopMapSet::build_from(const OopMapSet* oopmap_set) {
   744   ResourceMark mark;
   706   ResourceMark mark;