src/share/vm/opto/compile.cpp

changeset 2350
2f644f85485d
parent 2349
5ddfcf4b079e
child 2414
51bd2d261853
     1.1 --- a/src/share/vm/opto/compile.cpp	Thu Dec 02 17:21:12 2010 -0800
     1.2 +++ b/src/share/vm/opto/compile.cpp	Fri Dec 03 01:34:31 2010 -0800
     1.3 @@ -75,6 +75,18 @@
     1.4  # include "adfiles/ad_zero.hpp"
     1.5  #endif
     1.6  
     1.7 +
     1.8 +// -------------------- Compile::mach_constant_base_node -----------------------
     1.9 +// Constant table base node singleton.
    1.10 +MachConstantBaseNode* Compile::mach_constant_base_node() {
    1.11 +  if (_mach_constant_base_node == NULL) {
    1.12 +    _mach_constant_base_node = new (C) MachConstantBaseNode();
    1.13 +    _mach_constant_base_node->add_req(C->root());
    1.14 +  }
    1.15 +  return _mach_constant_base_node;
    1.16 +}
    1.17 +
    1.18 +
    1.19  /// Support for intrinsics.
    1.20  
    1.21  // Return the index at which m must be inserted (or already exists).
    1.22 @@ -432,13 +444,14 @@
    1.23  }
    1.24  
    1.25  
    1.26 -void Compile::init_scratch_buffer_blob() {
    1.27 -  if( scratch_buffer_blob() != NULL )  return;
    1.28 +void Compile::init_scratch_buffer_blob(int const_size) {
    1.29 +  if (scratch_buffer_blob() != NULL)  return;
    1.30  
    1.31    // Construct a temporary CodeBuffer to have it construct a BufferBlob
    1.32    // Cache this BufferBlob for this compile.
    1.33    ResourceMark rm;
    1.34 -  int size = (MAX_inst_size + MAX_stubs_size + MAX_const_size);
    1.35 +  _scratch_const_size = const_size;
    1.36 +  int size = (MAX_inst_size + MAX_stubs_size + _scratch_const_size);
    1.37    BufferBlob* blob = BufferBlob::create("Compile::scratch_buffer", size);
    1.38    // Record the buffer blob for next time.
    1.39    set_scratch_buffer_blob(blob);
    1.40 @@ -455,9 +468,19 @@
    1.41  }
    1.42  
    1.43  
    1.44 +void Compile::clear_scratch_buffer_blob() {
    1.45 +  assert(scratch_buffer_blob(), "no BufferBlob set");
    1.46 +  set_scratch_buffer_blob(NULL);
    1.47 +  set_scratch_locs_memory(NULL);
    1.48 +}
    1.49 +
    1.50 +
    1.51  //-----------------------scratch_emit_size-------------------------------------
    1.52  // Helper function that computes size by emitting code
    1.53  uint Compile::scratch_emit_size(const Node* n) {
    1.54 +  // Start scratch_emit_size section.
    1.55 +  set_in_scratch_emit_size(true);
    1.56 +
    1.57    // Emit into a trash buffer and count bytes emitted.
    1.58    // This is a pretty expensive way to compute a size,
    1.59    // but it works well enough if seldom used.
    1.60 @@ -476,13 +499,20 @@
    1.61    address blob_end   = (address)locs_buf;
    1.62    assert(blob->content_contains(blob_end), "sanity");
    1.63    CodeBuffer buf(blob_begin, blob_end - blob_begin);
    1.64 -  buf.initialize_consts_size(MAX_const_size);
    1.65 +  buf.initialize_consts_size(_scratch_const_size);
    1.66    buf.initialize_stubs_size(MAX_stubs_size);
    1.67    assert(locs_buf != NULL, "sanity");
    1.68 -  int lsize = MAX_locs_size / 2;
    1.69 -  buf.insts()->initialize_shared_locs(&locs_buf[0],     lsize);
    1.70 -  buf.stubs()->initialize_shared_locs(&locs_buf[lsize], lsize);
    1.71 +  int lsize = MAX_locs_size / 3;
    1.72 +  buf.consts()->initialize_shared_locs(&locs_buf[lsize * 0], lsize);
    1.73 +  buf.insts()->initialize_shared_locs( &locs_buf[lsize * 1], lsize);
    1.74 +  buf.stubs()->initialize_shared_locs( &locs_buf[lsize * 2], lsize);
    1.75 +
    1.76 +  // Do the emission.
    1.77    n->emit(buf, this->regalloc());
    1.78 +
    1.79 +  // End scratch_emit_size section.
    1.80 +  set_in_scratch_emit_size(false);
    1.81 +
    1.82    return buf.insts_size();
    1.83  }
    1.84  
    1.85 @@ -516,10 +546,13 @@
    1.86                    _orig_pc_slot(0),
    1.87                    _orig_pc_slot_offset_in_bytes(0),
    1.88                    _has_method_handle_invokes(false),
    1.89 +                  _mach_constant_base_node(NULL),
    1.90                    _node_bundling_limit(0),
    1.91                    _node_bundling_base(NULL),
    1.92                    _java_calls(0),
    1.93                    _inner_loops(0),
    1.94 +                  _scratch_const_size(-1),
    1.95 +                  _in_scratch_emit_size(false),
    1.96  #ifndef PRODUCT
    1.97                    _trace_opto_output(TraceOptoOutput || method()->has_option("TraceOptoOutput")),
    1.98                    _printer(IdealGraphPrinter::printer()),
    1.99 @@ -783,6 +816,7 @@
   1.100      _failure_reason(NULL),
   1.101      _code_buffer("Compile::Fill_buffer"),
   1.102      _has_method_handle_invokes(false),
   1.103 +    _mach_constant_base_node(NULL),
   1.104      _node_bundling_limit(0),
   1.105      _node_bundling_base(NULL),
   1.106      _java_calls(0),
   1.107 @@ -2862,3 +2896,207 @@
   1.108      _log->done("phase nodes='%d'", C->unique());
   1.109    }
   1.110  }
   1.111 +
   1.112 +//=============================================================================
   1.113 +// Two Constant's are equal when the type and the value are equal.
   1.114 +bool Compile::Constant::operator==(const Constant& other) {
   1.115 +  if (type()          != other.type()         )  return false;
   1.116 +  if (can_be_reused() != other.can_be_reused())  return false;
   1.117 +  // For floating point values we compare the bit pattern.
   1.118 +  switch (type()) {
   1.119 +  case T_FLOAT:   return (_value.i == other._value.i);
   1.120 +  case T_LONG:
   1.121 +  case T_DOUBLE:  return (_value.j == other._value.j);
   1.122 +  case T_OBJECT:
   1.123 +  case T_ADDRESS: return (_value.l == other._value.l);
   1.124 +  case T_VOID:    return (_value.l == other._value.l);  // jump-table entries
   1.125 +  default: ShouldNotReachHere();
   1.126 +  }
   1.127 +  return false;
   1.128 +}
   1.129 +
   1.130 +// Emit constants grouped in the following order:
   1.131 +static BasicType type_order[] = {
   1.132 +  T_FLOAT,    // 32-bit
   1.133 +  T_OBJECT,   // 32 or 64-bit
   1.134 +  T_ADDRESS,  // 32 or 64-bit
   1.135 +  T_DOUBLE,   // 64-bit
   1.136 +  T_LONG,     // 64-bit
   1.137 +  T_VOID,     // 32 or 64-bit (jump-tables are at the end of the constant table for code emission reasons)
   1.138 +  T_ILLEGAL
   1.139 +};
   1.140 +
   1.141 +static int type_to_size_in_bytes(BasicType t) {
   1.142 +  switch (t) {
   1.143 +  case T_LONG:    return sizeof(jlong  );
   1.144 +  case T_FLOAT:   return sizeof(jfloat );
   1.145 +  case T_DOUBLE:  return sizeof(jdouble);
   1.146 +    // We use T_VOID as marker for jump-table entries (labels) which
   1.147 +    // need an interal word relocation.
   1.148 +  case T_VOID:
   1.149 +  case T_ADDRESS:
   1.150 +  case T_OBJECT:  return sizeof(jobject);
   1.151 +  }
   1.152 +
   1.153 +  ShouldNotReachHere();
   1.154 +  return -1;
   1.155 +}
   1.156 +
   1.157 +void Compile::ConstantTable::calculate_offsets_and_size() {
   1.158 +  int size = 0;
   1.159 +  for (int t = 0; type_order[t] != T_ILLEGAL; t++) {
   1.160 +    BasicType type = type_order[t];
   1.161 +
   1.162 +    for (int i = 0; i < _constants.length(); i++) {
   1.163 +      Constant con = _constants.at(i);
   1.164 +      if (con.type() != type)  continue;  // Skip other types.
   1.165 +
   1.166 +      // Align size for type.
   1.167 +      int typesize = type_to_size_in_bytes(con.type());
   1.168 +      size = align_size_up(size, typesize);
   1.169 +
   1.170 +      // Set offset.
   1.171 +      con.set_offset(size);
   1.172 +      _constants.at_put(i, con);
   1.173 +
   1.174 +      // Add type size.
   1.175 +      size = size + typesize;
   1.176 +    }
   1.177 +  }
   1.178 +
   1.179 +  // Align size up to the next section start (which is insts; see
   1.180 +  // CodeBuffer::align_at_start).
   1.181 +  assert(_size == -1, "already set?");
   1.182 +  _size = align_size_up(size, CodeEntryAlignment);
   1.183 +
   1.184 +  if (Matcher::constant_table_absolute_addressing) {
   1.185 +    set_table_base_offset(0);  // No table base offset required
   1.186 +  } else {
   1.187 +    if (UseRDPCForConstantTableBase) {
   1.188 +      // table base offset is set in MachConstantBaseNode::emit
   1.189 +    } else {
   1.190 +      // When RDPC is not used, the table base is set into the middle of
   1.191 +      // the constant table.
   1.192 +      int half_size = _size / 2;
   1.193 +      assert(half_size * 2 == _size, "sanity");
   1.194 +      set_table_base_offset(-half_size);
   1.195 +    }
   1.196 +  }
   1.197 +}
   1.198 +
   1.199 +void Compile::ConstantTable::emit(CodeBuffer& cb) {
   1.200 +  MacroAssembler _masm(&cb);
   1.201 +  for (int t = 0; type_order[t] != T_ILLEGAL; t++) {
   1.202 +    BasicType type = type_order[t];
   1.203 +
   1.204 +    for (int i = 0; i < _constants.length(); i++) {
   1.205 +      Constant con = _constants.at(i);
   1.206 +      if (con.type() != type)  continue;  // Skip other types.
   1.207 +
   1.208 +      address constant_addr;
   1.209 +      switch (con.type()) {
   1.210 +      case T_LONG:   constant_addr = _masm.long_constant(  con.get_jlong()  ); break;
   1.211 +      case T_FLOAT:  constant_addr = _masm.float_constant( con.get_jfloat() ); break;
   1.212 +      case T_DOUBLE: constant_addr = _masm.double_constant(con.get_jdouble()); break;
   1.213 +      case T_OBJECT: {
   1.214 +        jobject obj = con.get_jobject();
   1.215 +        int oop_index = _masm.oop_recorder()->find_index(obj);
   1.216 +        constant_addr = _masm.address_constant((address) obj, oop_Relocation::spec(oop_index));
   1.217 +        break;
   1.218 +      }
   1.219 +      case T_ADDRESS: {
   1.220 +        address addr = (address) con.get_jobject();
   1.221 +        constant_addr = _masm.address_constant(addr);
   1.222 +        break;
   1.223 +      }
   1.224 +      // We use T_VOID as marker for jump-table entries (labels) which
   1.225 +      // need an interal word relocation.
   1.226 +      case T_VOID: {
   1.227 +        // Write a dummy word.  The real value is filled in later
   1.228 +        // in fill_jump_table_in_constant_table.
   1.229 +        address addr = (address) con.get_jobject();
   1.230 +        constant_addr = _masm.address_constant(addr);
   1.231 +        break;
   1.232 +      }
   1.233 +      default: ShouldNotReachHere();
   1.234 +      }
   1.235 +      assert(constant_addr != NULL, "consts section too small");
   1.236 +      assert((constant_addr - _masm.code()->consts()->start()) == con.offset(), err_msg("must be: %d == %d", constant_addr - _masm.code()->consts()->start(), con.offset()));
   1.237 +    }
   1.238 +  }
   1.239 +}
   1.240 +
   1.241 +int Compile::ConstantTable::find_offset(Constant& con) const {
   1.242 +  int idx = _constants.find(con);
   1.243 +  assert(idx != -1, "constant must be in constant table");
   1.244 +  int offset = _constants.at(idx).offset();
   1.245 +  assert(offset != -1, "constant table not emitted yet?");
   1.246 +  return offset;
   1.247 +}
   1.248 +
   1.249 +void Compile::ConstantTable::add(Constant& con) {
   1.250 +  if (con.can_be_reused()) {
   1.251 +    int idx = _constants.find(con);
   1.252 +    if (idx != -1 && _constants.at(idx).can_be_reused()) {
   1.253 +      return;
   1.254 +    }
   1.255 +  }
   1.256 +  (void) _constants.append(con);
   1.257 +}
   1.258 +
   1.259 +Compile::Constant Compile::ConstantTable::add(BasicType type, jvalue value) {
   1.260 +  Constant con(type, value);
   1.261 +  add(con);
   1.262 +  return con;
   1.263 +}
   1.264 +
   1.265 +Compile::Constant Compile::ConstantTable::add(MachOper* oper) {
   1.266 +  jvalue value;
   1.267 +  BasicType type = oper->type()->basic_type();
   1.268 +  switch (type) {
   1.269 +  case T_LONG:    value.j = oper->constantL(); break;
   1.270 +  case T_FLOAT:   value.f = oper->constantF(); break;
   1.271 +  case T_DOUBLE:  value.d = oper->constantD(); break;
   1.272 +  case T_OBJECT:
   1.273 +  case T_ADDRESS: value.l = (jobject) oper->constant(); break;
   1.274 +  default: ShouldNotReachHere();
   1.275 +  }
   1.276 +  return add(type, value);
   1.277 +}
   1.278 +
   1.279 +Compile::Constant Compile::ConstantTable::allocate_jump_table(MachConstantNode* n) {
   1.280 +  jvalue value;
   1.281 +  // We can use the node pointer here to identify the right jump-table
   1.282 +  // as this method is called from Compile::Fill_buffer right before
   1.283 +  // the MachNodes are emitted and the jump-table is filled (means the
   1.284 +  // MachNode pointers do not change anymore).
   1.285 +  value.l = (jobject) n;
   1.286 +  Constant con(T_VOID, value, false);  // Labels of a jump-table cannot be reused.
   1.287 +  for (uint i = 0; i < n->outcnt(); i++) {
   1.288 +    add(con);
   1.289 +  }
   1.290 +  return con;
   1.291 +}
   1.292 +
   1.293 +void Compile::ConstantTable::fill_jump_table(CodeBuffer& cb, MachConstantNode* n, GrowableArray<Label*> labels) const {
   1.294 +  // If called from Compile::scratch_emit_size do nothing.
   1.295 +  if (Compile::current()->in_scratch_emit_size())  return;
   1.296 +
   1.297 +  assert(labels.is_nonempty(), "must be");
   1.298 +  assert((uint) labels.length() == n->outcnt(), err_msg("must be equal: %d == %d", labels.length(), n->outcnt()));
   1.299 +
   1.300 +  // Since MachConstantNode::constant_offset() also contains
   1.301 +  // table_base_offset() we need to subtract the table_base_offset()
   1.302 +  // to get the plain offset into the constant table.
   1.303 +  int offset = n->constant_offset() - table_base_offset();
   1.304 +
   1.305 +  MacroAssembler _masm(&cb);
   1.306 +  address* jump_table_base = (address*) (_masm.code()->consts()->start() + offset);
   1.307 +
   1.308 +  for (int i = 0; i < labels.length(); i++) {
   1.309 +    address* constant_addr = &jump_table_base[i];
   1.310 +    assert(*constant_addr == (address) n, "all jump-table entries must contain node pointer");
   1.311 +    *constant_addr = cb.consts()->target(*labels.at(i), (address) constant_addr);
   1.312 +    cb.consts()->relocate((address) constant_addr, relocInfo::internal_word_type);
   1.313 +  }
   1.314 +}

mercurial