src/share/vm/code/relocInfo.cpp

changeset 4037
da91efe96a93
parent 2750
6c97c830fb6f
child 4318
cd3d6a6b95d9
     1.1 --- a/src/share/vm/code/relocInfo.cpp	Fri Aug 31 16:39:35 2012 -0700
     1.2 +++ b/src/share/vm/code/relocInfo.cpp	Sat Sep 01 13:25:18 2012 -0400
     1.3 @@ -1,5 +1,5 @@
     1.4  /*
     1.5 - * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
     1.6 + * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
     1.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     1.8   *
     1.9   * This code is free software; you can redistribute it and/or modify it
    1.10 @@ -439,6 +439,11 @@
    1.11          oop_Relocation* r = (oop_Relocation*)reloc();
    1.12          return oop_Relocation::spec(r->oop_index(), r->offset() + offset);
    1.13        }
    1.14 +    case relocInfo::metadata_type:
    1.15 +      {
    1.16 +        metadata_Relocation* r = (metadata_Relocation*)reloc();
    1.17 +        return metadata_Relocation::spec(r->metadata_index(), r->offset() + offset);
    1.18 +      }
    1.19      default:
    1.20        ShouldNotReachHere();
    1.21      }
    1.22 @@ -578,33 +583,33 @@
    1.23    unpack_2_ints(_oop_index, _offset);
    1.24  }
    1.25  
    1.26 +void metadata_Relocation::pack_data_to(CodeSection* dest) {
    1.27 +  short* p = (short*) dest->locs_end();
    1.28 +  p = pack_2_ints_to(p, _metadata_index, _offset);
    1.29 +  dest->set_locs_end((relocInfo*) p);
    1.30 +}
    1.31 +
    1.32 +
    1.33 +void metadata_Relocation::unpack_data() {
    1.34 +  unpack_2_ints(_metadata_index, _offset);
    1.35 +}
    1.36 +
    1.37  
    1.38  void virtual_call_Relocation::pack_data_to(CodeSection* dest) {
    1.39    short*  p     = (short*) dest->locs_end();
    1.40    address point =          dest->locs_point();
    1.41  
    1.42 -  // Try to make a pointer NULL first.
    1.43 -  if (_oop_limit >= point &&
    1.44 -      _oop_limit <= point + NativeCall::instruction_size) {
    1.45 -    _oop_limit = NULL;
    1.46 -  }
    1.47 -  // If the _oop_limit is NULL, it "defaults" to the end of the call.
    1.48 -  // See ic_call_Relocation::oop_limit() below.
    1.49 -
    1.50 -  normalize_address(_first_oop, dest);
    1.51 -  normalize_address(_oop_limit, dest);
    1.52 -  jint x0 = scaled_offset_null_special(_first_oop, point);
    1.53 -  jint x1 = scaled_offset_null_special(_oop_limit, point);
    1.54 -  p = pack_2_ints_to(p, x0, x1);
    1.55 +  normalize_address(_cached_value, dest);
    1.56 +  jint x0 = scaled_offset_null_special(_cached_value, point);
    1.57 +  p = pack_1_int_to(p, x0);
    1.58    dest->set_locs_end((relocInfo*) p);
    1.59  }
    1.60  
    1.61  
    1.62  void virtual_call_Relocation::unpack_data() {
    1.63 -  jint x0, x1; unpack_2_ints(x0, x1);
    1.64 +  jint x0 = unpack_1_int();
    1.65    address point = addr();
    1.66 -  _first_oop = x0==0? NULL: address_from_scaled_offset(x0, point);
    1.67 -  _oop_limit = x1==0? NULL: address_from_scaled_offset(x1, point);
    1.68 +  _cached_value = x0==0? NULL: address_from_scaled_offset(x0, point);
    1.69  }
    1.70  
    1.71  
    1.72 @@ -799,100 +804,48 @@
    1.73    }
    1.74  }
    1.75  
    1.76 -
    1.77 -RelocIterator virtual_call_Relocation::parse_ic(nmethod* &nm, address &ic_call, address &first_oop,
    1.78 -                                                oop* &oop_addr, bool *is_optimized) {
    1.79 -  assert(ic_call != NULL, "ic_call address must be set");
    1.80 -  assert(ic_call != NULL || first_oop != NULL, "must supply a non-null input");
    1.81 -  if (nm == NULL) {
    1.82 -    CodeBlob* code;
    1.83 -    if (ic_call != NULL) {
    1.84 -      code = CodeCache::find_blob(ic_call);
    1.85 -    } else if (first_oop != NULL) {
    1.86 -      code = CodeCache::find_blob(first_oop);
    1.87 -    }
    1.88 -    nm = code->as_nmethod_or_null();
    1.89 -    assert(nm != NULL, "address to parse must be in nmethod");
    1.90 -  }
    1.91 -  assert(ic_call   == NULL || nm->contains(ic_call),   "must be in nmethod");
    1.92 -  assert(first_oop == NULL || nm->contains(first_oop), "must be in nmethod");
    1.93 -
    1.94 -  address oop_limit = NULL;
    1.95 -
    1.96 -  if (ic_call != NULL) {
    1.97 -    // search for the ic_call at the given address
    1.98 -    RelocIterator iter(nm, ic_call, ic_call+1);
    1.99 -    bool ret = iter.next();
   1.100 -    assert(ret == true, "relocInfo must exist at this address");
   1.101 -    assert(iter.addr() == ic_call, "must find ic_call");
   1.102 -    if (iter.type() == relocInfo::virtual_call_type) {
   1.103 -      virtual_call_Relocation* r = iter.virtual_call_reloc();
   1.104 -      first_oop = r->first_oop();
   1.105 -      oop_limit = r->oop_limit();
   1.106 -      *is_optimized = false;
   1.107 +// meta data versions
   1.108 +Metadata** metadata_Relocation::metadata_addr() {
   1.109 +  int n = _metadata_index;
   1.110 +  if (n == 0) {
   1.111 +    // metadata is stored in the code stream
   1.112 +    return (Metadata**) pd_address_in_code();
   1.113      } else {
   1.114 -      assert(iter.type() == relocInfo::opt_virtual_call_type, "must be a virtual call");
   1.115 -      *is_optimized = true;
   1.116 -      oop_addr = NULL;
   1.117 -      first_oop = NULL;
   1.118 -      return iter;
   1.119 +    // metadata is stored in table at nmethod::metadatas_begin
   1.120 +    return code()->metadata_addr_at(n);
   1.121      }
   1.122    }
   1.123  
   1.124 -  // search for the first_oop, to get its oop_addr
   1.125 -  RelocIterator all_oops(nm, first_oop);
   1.126 -  RelocIterator iter = all_oops;
   1.127 -  iter.set_limit(first_oop+1);
   1.128 -  bool found_oop = false;
   1.129 -  while (iter.next()) {
   1.130 -    if (iter.type() == relocInfo::oop_type) {
   1.131 -      assert(iter.addr() == first_oop, "must find first_oop");
   1.132 -      oop_addr = iter.oop_reloc()->oop_addr();
   1.133 -      found_oop = true;
   1.134 -      break;
   1.135 -    }
   1.136 -  }
   1.137 -  assert(found_oop, "must find first_oop");
   1.138  
   1.139 -  bool did_reset = false;
   1.140 -  while (ic_call == NULL) {
   1.141 -    // search forward for the ic_call matching the given first_oop
   1.142 -    while (iter.next()) {
   1.143 -      if (iter.type() == relocInfo::virtual_call_type) {
   1.144 -        virtual_call_Relocation* r = iter.virtual_call_reloc();
   1.145 -        if (r->first_oop() == first_oop) {
   1.146 -          ic_call   = r->addr();
   1.147 -          oop_limit = r->oop_limit();
   1.148 -          break;
   1.149 -        }
   1.150 -      }
   1.151 -    }
   1.152 -    guarantee(!did_reset, "cannot find ic_call");
   1.153 -    iter = RelocIterator(nm); // search the whole nmethod
   1.154 -    did_reset = true;
   1.155 +Metadata* metadata_Relocation::metadata_value() {
   1.156 +  Metadata* v = *metadata_addr();
   1.157 +  // clean inline caches store a special pseudo-null
   1.158 +  if (v == (Metadata*)Universe::non_oop_word())  v = NULL;
   1.159 +  return v;
   1.160    }
   1.161  
   1.162 -  assert(oop_limit != NULL && first_oop != NULL && ic_call != NULL, "");
   1.163 -  all_oops.set_limit(oop_limit);
   1.164 -  return all_oops;
   1.165 +
   1.166 +void metadata_Relocation::fix_metadata_relocation() {
   1.167 +  if (!metadata_is_immediate()) {
   1.168 +    // get the metadata from the pool, and re-insert it into the instruction:
   1.169 +    pd_fix_value(value());
   1.170 +  }
   1.171  }
   1.172  
   1.173  
   1.174 -address virtual_call_Relocation::first_oop() {
   1.175 -  assert(_first_oop != NULL && _first_oop < addr(), "must precede ic_call");
   1.176 -  return _first_oop;
   1.177 +void metadata_Relocation::verify_metadata_relocation() {
   1.178 +  if (!metadata_is_immediate()) {
   1.179 +    // get the metadata from the pool, and re-insert it into the instruction:
   1.180 +    verify_value(value());
   1.181 +  }
   1.182  }
   1.183  
   1.184 -
   1.185 -address virtual_call_Relocation::oop_limit() {
   1.186 -  if (_oop_limit == NULL)
   1.187 -    return addr() + NativeCall::instruction_size;
   1.188 -  else
   1.189 -    return _oop_limit;
   1.190 +address virtual_call_Relocation::cached_value() {
   1.191 +  assert(_cached_value != NULL && _cached_value < addr(), "must precede ic_call");
   1.192 +  return _cached_value;
   1.193  }
   1.194  
   1.195  
   1.196 -
   1.197  void virtual_call_Relocation::clear_inline_cache() {
   1.198    // No stubs for ICs
   1.199    // Clean IC
   1.200 @@ -1139,6 +1092,25 @@
   1.201        }
   1.202        break;
   1.203      }
   1.204 +  case relocInfo::metadata_type:
   1.205 +    {
   1.206 +      metadata_Relocation* r = metadata_reloc();
   1.207 +      Metadata** metadata_addr  = NULL;
   1.208 +      Metadata*    raw_metadata   = NULL;
   1.209 +      Metadata*    metadata_value = NULL;
   1.210 +      if (code() != NULL || r->metadata_is_immediate()) {
   1.211 +        metadata_addr  = r->metadata_addr();
   1.212 +        raw_metadata   = *metadata_addr;
   1.213 +        metadata_value = r->metadata_value();
   1.214 +      }
   1.215 +      tty->print(" | [metadata_addr=" INTPTR_FORMAT " *=" INTPTR_FORMAT " offset=%d]",
   1.216 +                 metadata_addr, (address)raw_metadata, r->offset());
   1.217 +      if (metadata_value != NULL) {
   1.218 +        tty->print("metadata_value=" INTPTR_FORMAT ": ", (address)metadata_value);
   1.219 +        metadata_value->print_value_on(tty);
   1.220 +      }
   1.221 +      break;
   1.222 +    }
   1.223    case relocInfo::external_word_type:
   1.224    case relocInfo::internal_word_type:
   1.225    case relocInfo::section_word_type:
   1.226 @@ -1157,8 +1129,8 @@
   1.227    case relocInfo::virtual_call_type:
   1.228      {
   1.229        virtual_call_Relocation* r = (virtual_call_Relocation*) reloc();
   1.230 -      tty->print(" | [destination=" INTPTR_FORMAT " first_oop=" INTPTR_FORMAT " oop_limit=" INTPTR_FORMAT "]",
   1.231 -                 r->destination(), r->first_oop(), r->oop_limit());
   1.232 +      tty->print(" | [destination=" INTPTR_FORMAT " cached_value=" INTPTR_FORMAT "]",
   1.233 +                 r->destination(), r->cached_value());
   1.234        break;
   1.235      }
   1.236    case relocInfo::static_stub_type:

mercurial