src/cpu/x86/vm/c1_LIRAssembler_x86.cpp

changeset 2138
d5d065957597
parent 1934
e9ff18c4ace7
child 2145
7f9553bedfd5
     1.1 --- a/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp	Thu Sep 02 11:40:02 2010 -0700
     1.2 +++ b/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp	Fri Sep 03 17:51:07 2010 -0700
     1.3 @@ -1613,7 +1613,194 @@
     1.4    __ bind(*op->stub()->continuation());
     1.5  }
     1.6  
     1.7 -
     1.8 +void LIR_Assembler::type_profile_helper(Register mdo,
     1.9 +                                        ciMethodData *md, ciProfileData *data,
    1.10 +                                        Register recv, Label* update_done) {
    1.11 +  uint i;
    1.12 +  for (i = 0; i < ReceiverTypeData::row_limit(); i++) {
    1.13 +    Label next_test;
    1.14 +    // See if the receiver is receiver[n].
    1.15 +    __ cmpptr(recv, Address(mdo, md->byte_offset_of_slot(data, ReceiverTypeData::receiver_offset(i))));
    1.16 +    __ jccb(Assembler::notEqual, next_test);
    1.17 +    Address data_addr(mdo, md->byte_offset_of_slot(data, ReceiverTypeData::receiver_count_offset(i)));
    1.18 +    __ addptr(data_addr, DataLayout::counter_increment);
    1.19 +    __ jmpb(*update_done);
    1.20 +    __ bind(next_test);
    1.21 +  }
    1.22 +
    1.23 +  // Didn't find receiver; find next empty slot and fill it in
    1.24 +  for (i = 0; i < ReceiverTypeData::row_limit(); i++) {
    1.25 +    Label next_test;
    1.26 +    Address recv_addr(mdo, md->byte_offset_of_slot(data, ReceiverTypeData::receiver_offset(i)));
    1.27 +    __ cmpptr(recv_addr, (intptr_t)NULL_WORD);
    1.28 +    __ jccb(Assembler::notEqual, next_test);
    1.29 +    __ movptr(recv_addr, recv);
    1.30 +    __ movptr(Address(mdo, md->byte_offset_of_slot(data, ReceiverTypeData::receiver_count_offset(i))), DataLayout::counter_increment);
    1.31 +    __ jmpb(*update_done);
    1.32 +    __ bind(next_test);
    1.33 +  }
    1.34 +}
    1.35 +
    1.36 +void LIR_Assembler::emit_checkcast(LIR_OpTypeCheck *op) {
    1.37 +  assert(op->code() == lir_checkcast, "Invalid operation");
    1.38 +  // we always need a stub for the failure case.
    1.39 +  CodeStub* stub = op->stub();
    1.40 +  Register obj = op->object()->as_register();
    1.41 +  Register k_RInfo = op->tmp1()->as_register();
    1.42 +  Register klass_RInfo = op->tmp2()->as_register();
    1.43 +  Register dst = op->result_opr()->as_register();
    1.44 +  ciKlass* k = op->klass();
    1.45 +  Register Rtmp1 = noreg;
    1.46 +
    1.47 +  // check if it needs to be profiled
    1.48 +  ciMethodData* md;
    1.49 +  ciProfileData* data;
    1.50 +
    1.51 +  if (op->should_profile()) {
    1.52 +    ciMethod* method = op->profiled_method();
    1.53 +    assert(method != NULL, "Should have method");
    1.54 +    int bci = op->profiled_bci();
    1.55 +    md = method->method_data();
    1.56 +    if (md == NULL) {
    1.57 +      bailout("out of memory building methodDataOop");
    1.58 +      return;
    1.59 +    }
    1.60 +    data = md->bci_to_data(bci);
    1.61 +    assert(data != NULL,                "need data for checkcast");
    1.62 +    assert(data->is_ReceiverTypeData(), "need ReceiverTypeData for checkcast");
    1.63 +  }
    1.64 +  Label profile_cast_failure;
    1.65 +
    1.66 +  Label done, done_null;
    1.67 +  // Where to go in case of cast failure
    1.68 +  Label *failure_target = op->should_profile() ? &profile_cast_failure : stub->entry();
    1.69 +
    1.70 +  if (obj == k_RInfo) {
    1.71 +    k_RInfo = dst;
    1.72 +  } else if (obj == klass_RInfo) {
    1.73 +    klass_RInfo = dst;
    1.74 +  }
    1.75 +  if (k->is_loaded()) {
    1.76 +    select_different_registers(obj, dst, k_RInfo, klass_RInfo);
    1.77 +  } else {
    1.78 +    Rtmp1 = op->tmp3()->as_register();
    1.79 +    select_different_registers(obj, dst, k_RInfo, klass_RInfo, Rtmp1);
    1.80 +  }
    1.81 +
    1.82 +  assert_different_registers(obj, k_RInfo, klass_RInfo);
    1.83 +  if (!k->is_loaded()) {
    1.84 +    jobject2reg_with_patching(k_RInfo, op->info_for_patch());
    1.85 +  } else {
    1.86 +#ifdef _LP64
    1.87 +    __ movoop(k_RInfo, k->constant_encoding());
    1.88 +#endif // _LP64
    1.89 +  }
    1.90 +  assert(obj != k_RInfo, "must be different");
    1.91 +
    1.92 +  __ cmpptr(obj, (int32_t)NULL_WORD);
    1.93 +  if (op->should_profile()) {
    1.94 +    Label profile_done;
    1.95 +    __ jccb(Assembler::notEqual, profile_done);
    1.96 +    // Object is null; update methodDataOop
    1.97 +    Register mdo  = klass_RInfo;
    1.98 +    __ movoop(mdo, md->constant_encoding());
    1.99 +    Address data_addr(mdo, md->byte_offset_of_slot(data, DataLayout::header_offset()));
   1.100 +    int header_bits = DataLayout::flag_mask_to_header_mask(BitData::null_seen_byte_constant());
   1.101 +    __ orl(data_addr, header_bits);
   1.102 +    __ jmp(done_null);
   1.103 +    __ bind(profile_done);
   1.104 +  } else {
   1.105 +    __ jcc(Assembler::equal, done_null);
   1.106 +  }
   1.107 +  __ verify_oop(obj);
   1.108 +
   1.109 +  if (op->fast_check()) {
   1.110 +    // get object classo
   1.111 +    // not a safepoint as obj null check happens earlier
   1.112 +    if (k->is_loaded()) {
   1.113 +#ifdef _LP64
   1.114 +      __ cmpptr(k_RInfo, Address(obj, oopDesc::klass_offset_in_bytes()));
   1.115 +#else
   1.116 +      __ cmpoop(Address(obj, oopDesc::klass_offset_in_bytes()), k->constant_encoding());
   1.117 +#endif // _LP64
   1.118 +    } else {
   1.119 +      __ cmpptr(k_RInfo, Address(obj, oopDesc::klass_offset_in_bytes()));
   1.120 +    }
   1.121 +    __ jcc(Assembler::notEqual, *failure_target);
   1.122 +  } else {
   1.123 +    // get object class
   1.124 +    // not a safepoint as obj null check happens earlier
   1.125 +    __ movptr(klass_RInfo, Address(obj, oopDesc::klass_offset_in_bytes()));
   1.126 +    if (k->is_loaded()) {
   1.127 +      // See if we get an immediate positive hit
   1.128 +#ifdef _LP64
   1.129 +      __ cmpptr(k_RInfo, Address(klass_RInfo, k->super_check_offset()));
   1.130 +#else
   1.131 +      __ cmpoop(Address(klass_RInfo, k->super_check_offset()), k->constant_encoding());
   1.132 +#endif // _LP64
   1.133 +      if (sizeof(oopDesc) + Klass::secondary_super_cache_offset_in_bytes() != k->super_check_offset()) {
   1.134 +        __ jcc(Assembler::notEqual, *failure_target);
   1.135 +      } else {
   1.136 +        // See if we get an immediate positive hit
   1.137 +        __ jcc(Assembler::equal, done);
   1.138 +        // check for self
   1.139 +#ifdef _LP64
   1.140 +        __ cmpptr(klass_RInfo, k_RInfo);
   1.141 +#else
   1.142 +        __ cmpoop(klass_RInfo, k->constant_encoding());
   1.143 +#endif // _LP64
   1.144 +        __ jcc(Assembler::equal, done);
   1.145 +
   1.146 +        __ push(klass_RInfo);
   1.147 +#ifdef _LP64
   1.148 +        __ push(k_RInfo);
   1.149 +#else
   1.150 +        __ pushoop(k->constant_encoding());
   1.151 +#endif // _LP64
   1.152 +        __ call(RuntimeAddress(Runtime1::entry_for(Runtime1::slow_subtype_check_id)));
   1.153 +        __ pop(klass_RInfo);
   1.154 +        __ pop(klass_RInfo);
   1.155 +        // result is a boolean
   1.156 +        __ cmpl(klass_RInfo, 0);
   1.157 +        __ jcc(Assembler::equal, *failure_target);
   1.158 +      }
   1.159 +    } else {
   1.160 +      // perform the fast part of the checking logic
   1.161 +      __ check_klass_subtype_fast_path(klass_RInfo, k_RInfo, Rtmp1, &done, failure_target, NULL);
   1.162 +      // call out-of-line instance of __ check_klass_subtype_slow_path(...):
   1.163 +      __ push(klass_RInfo);
   1.164 +      __ push(k_RInfo);
   1.165 +      __ call(RuntimeAddress(Runtime1::entry_for(Runtime1::slow_subtype_check_id)));
   1.166 +      __ pop(klass_RInfo);
   1.167 +      __ pop(k_RInfo);
   1.168 +      // result is a boolean
   1.169 +      __ cmpl(k_RInfo, 0);
   1.170 +      __ jcc(Assembler::equal, *failure_target);
   1.171 +    }
   1.172 +  }
   1.173 +  __ bind(done);
   1.174 +
   1.175 +  if (op->should_profile()) {
   1.176 +    Register mdo  = klass_RInfo, recv = k_RInfo;
   1.177 +    __ movoop(mdo, md->constant_encoding());
   1.178 +    __ movptr(recv, Address(obj, oopDesc::klass_offset_in_bytes()));
   1.179 +    Label update_done;
   1.180 +    type_profile_helper(mdo, md, data, recv, &update_done);
   1.181 +    __ jmpb(update_done);
   1.182 +
   1.183 +    __ bind(profile_cast_failure);
   1.184 +    __ movoop(mdo, md->constant_encoding());
   1.185 +    Address counter_addr(mdo, md->byte_offset_of_slot(data, CounterData::count_offset()));
   1.186 +    __ subptr(counter_addr, DataLayout::counter_increment);
   1.187 +    __ jmp(*stub->entry());
   1.188 +
   1.189 +    __ bind(update_done);
   1.190 +  }
   1.191 +  __ bind(done_null);
   1.192 +  if (dst != obj) {
   1.193 +    __ mov(dst, obj);
   1.194 +  }
   1.195 +}
   1.196  
   1.197  void LIR_Assembler::emit_opTypeCheck(LIR_OpTypeCheck* op) {
   1.198    LIR_Code code = op->code();
   1.199 @@ -1646,140 +1833,6 @@
   1.200      __ cmpl(k_RInfo, 0);
   1.201      __ jcc(Assembler::equal, *stub->entry());
   1.202      __ bind(done);
   1.203 -  } else if (op->code() == lir_checkcast) {
   1.204 -    // we always need a stub for the failure case.
   1.205 -    CodeStub* stub = op->stub();
   1.206 -    Register obj = op->object()->as_register();
   1.207 -    Register k_RInfo = op->tmp1()->as_register();
   1.208 -    Register klass_RInfo = op->tmp2()->as_register();
   1.209 -    Register dst = op->result_opr()->as_register();
   1.210 -    ciKlass* k = op->klass();
   1.211 -    Register Rtmp1 = noreg;
   1.212 -
   1.213 -    Label done;
   1.214 -    if (obj == k_RInfo) {
   1.215 -      k_RInfo = dst;
   1.216 -    } else if (obj == klass_RInfo) {
   1.217 -      klass_RInfo = dst;
   1.218 -    }
   1.219 -    if (k->is_loaded()) {
   1.220 -      select_different_registers(obj, dst, k_RInfo, klass_RInfo);
   1.221 -    } else {
   1.222 -      Rtmp1 = op->tmp3()->as_register();
   1.223 -      select_different_registers(obj, dst, k_RInfo, klass_RInfo, Rtmp1);
   1.224 -    }
   1.225 -
   1.226 -    assert_different_registers(obj, k_RInfo, klass_RInfo);
   1.227 -    if (!k->is_loaded()) {
   1.228 -      jobject2reg_with_patching(k_RInfo, op->info_for_patch());
   1.229 -    } else {
   1.230 -#ifdef _LP64
   1.231 -      __ movoop(k_RInfo, k->constant_encoding());
   1.232 -#else
   1.233 -      k_RInfo = noreg;
   1.234 -#endif // _LP64
   1.235 -    }
   1.236 -    assert(obj != k_RInfo, "must be different");
   1.237 -    __ cmpptr(obj, (int32_t)NULL_WORD);
   1.238 -    if (op->profiled_method() != NULL) {
   1.239 -      ciMethod* method = op->profiled_method();
   1.240 -      int bci          = op->profiled_bci();
   1.241 -
   1.242 -      Label profile_done;
   1.243 -      __ jcc(Assembler::notEqual, profile_done);
   1.244 -      // Object is null; update methodDataOop
   1.245 -      ciMethodData* md = method->method_data();
   1.246 -      if (md == NULL) {
   1.247 -        bailout("out of memory building methodDataOop");
   1.248 -        return;
   1.249 -      }
   1.250 -      ciProfileData* data = md->bci_to_data(bci);
   1.251 -      assert(data != NULL,       "need data for checkcast");
   1.252 -      assert(data->is_BitData(), "need BitData for checkcast");
   1.253 -      Register mdo  = klass_RInfo;
   1.254 -      __ movoop(mdo, md->constant_encoding());
   1.255 -      Address data_addr(mdo, md->byte_offset_of_slot(data, DataLayout::header_offset()));
   1.256 -      int header_bits = DataLayout::flag_mask_to_header_mask(BitData::null_seen_byte_constant());
   1.257 -      __ orl(data_addr, header_bits);
   1.258 -      __ jmp(done);
   1.259 -      __ bind(profile_done);
   1.260 -    } else {
   1.261 -      __ jcc(Assembler::equal, done);
   1.262 -    }
   1.263 -    __ verify_oop(obj);
   1.264 -
   1.265 -    if (op->fast_check()) {
   1.266 -      // get object classo
   1.267 -      // not a safepoint as obj null check happens earlier
   1.268 -      if (k->is_loaded()) {
   1.269 -#ifdef _LP64
   1.270 -        __ cmpptr(k_RInfo, Address(obj, oopDesc::klass_offset_in_bytes()));
   1.271 -#else
   1.272 -        __ cmpoop(Address(obj, oopDesc::klass_offset_in_bytes()), k->constant_encoding());
   1.273 -#endif // _LP64
   1.274 -      } else {
   1.275 -        __ cmpptr(k_RInfo, Address(obj, oopDesc::klass_offset_in_bytes()));
   1.276 -
   1.277 -      }
   1.278 -      __ jcc(Assembler::notEqual, *stub->entry());
   1.279 -      __ bind(done);
   1.280 -    } else {
   1.281 -      // get object class
   1.282 -      // not a safepoint as obj null check happens earlier
   1.283 -      __ movptr(klass_RInfo, Address(obj, oopDesc::klass_offset_in_bytes()));
   1.284 -      if (k->is_loaded()) {
   1.285 -        // See if we get an immediate positive hit
   1.286 -#ifdef _LP64
   1.287 -        __ cmpptr(k_RInfo, Address(klass_RInfo, k->super_check_offset()));
   1.288 -#else
   1.289 -        __ cmpoop(Address(klass_RInfo, k->super_check_offset()), k->constant_encoding());
   1.290 -#endif // _LP64
   1.291 -        if (sizeof(oopDesc) + Klass::secondary_super_cache_offset_in_bytes() != k->super_check_offset()) {
   1.292 -          __ jcc(Assembler::notEqual, *stub->entry());
   1.293 -        } else {
   1.294 -          // See if we get an immediate positive hit
   1.295 -          __ jcc(Assembler::equal, done);
   1.296 -          // check for self
   1.297 -#ifdef _LP64
   1.298 -          __ cmpptr(klass_RInfo, k_RInfo);
   1.299 -#else
   1.300 -          __ cmpoop(klass_RInfo, k->constant_encoding());
   1.301 -#endif // _LP64
   1.302 -          __ jcc(Assembler::equal, done);
   1.303 -
   1.304 -          __ push(klass_RInfo);
   1.305 -#ifdef _LP64
   1.306 -          __ push(k_RInfo);
   1.307 -#else
   1.308 -          __ pushoop(k->constant_encoding());
   1.309 -#endif // _LP64
   1.310 -          __ call(RuntimeAddress(Runtime1::entry_for(Runtime1::slow_subtype_check_id)));
   1.311 -          __ pop(klass_RInfo);
   1.312 -          __ pop(klass_RInfo);
   1.313 -          // result is a boolean
   1.314 -          __ cmpl(klass_RInfo, 0);
   1.315 -          __ jcc(Assembler::equal, *stub->entry());
   1.316 -        }
   1.317 -        __ bind(done);
   1.318 -      } else {
   1.319 -        // perform the fast part of the checking logic
   1.320 -        __ check_klass_subtype_fast_path(klass_RInfo, k_RInfo, Rtmp1, &done, stub->entry(), NULL);
   1.321 -        // call out-of-line instance of __ check_klass_subtype_slow_path(...):
   1.322 -        __ push(klass_RInfo);
   1.323 -        __ push(k_RInfo);
   1.324 -        __ call(RuntimeAddress(Runtime1::entry_for(Runtime1::slow_subtype_check_id)));
   1.325 -        __ pop(klass_RInfo);
   1.326 -        __ pop(k_RInfo);
   1.327 -        // result is a boolean
   1.328 -        __ cmpl(k_RInfo, 0);
   1.329 -        __ jcc(Assembler::equal, *stub->entry());
   1.330 -        __ bind(done);
   1.331 -      }
   1.332 -
   1.333 -    }
   1.334 -    if (dst != obj) {
   1.335 -      __ mov(dst, obj);
   1.336 -    }
   1.337    } else if (code == lir_instanceof) {
   1.338      Register obj = op->object()->as_register();
   1.339      Register k_RInfo = op->tmp1()->as_register();
   1.340 @@ -1922,7 +1975,6 @@
   1.341    }
   1.342  }
   1.343  
   1.344 -
   1.345  void LIR_Assembler::cmove(LIR_Condition condition, LIR_Opr opr1, LIR_Opr opr2, LIR_Opr result) {
   1.346    Assembler::Condition acond, ncond;
   1.347    switch (condition) {
   1.348 @@ -3253,13 +3305,13 @@
   1.349    // Perform additional virtual call profiling for invokevirtual and
   1.350    // invokeinterface bytecodes
   1.351    if ((bc == Bytecodes::_invokevirtual || bc == Bytecodes::_invokeinterface) &&
   1.352 -      Tier1ProfileVirtualCalls) {
   1.353 +      C1ProfileVirtualCalls) {
   1.354      assert(op->recv()->is_single_cpu(), "recv must be allocated");
   1.355      Register recv = op->recv()->as_register();
   1.356      assert_different_registers(mdo, recv);
   1.357      assert(data->is_VirtualCallData(), "need VirtualCallData for virtual calls");
   1.358      ciKlass* known_klass = op->known_holder();
   1.359 -    if (Tier1OptimizeVirtualCallProfiling && known_klass != NULL) {
   1.360 +    if (C1OptimizeVirtualCallProfiling && known_klass != NULL) {
   1.361        // We know the type that will be seen at this call site; we can
   1.362        // statically update the methodDataOop rather than needing to do
   1.363        // dynamic tests on the receiver type
   1.364 @@ -3272,7 +3324,7 @@
   1.365          ciKlass* receiver = vc_data->receiver(i);
   1.366          if (known_klass->equals(receiver)) {
   1.367            Address data_addr(mdo, md->byte_offset_of_slot(data, VirtualCallData::receiver_count_offset(i)));
   1.368 -          __ addl(data_addr, DataLayout::counter_increment);
   1.369 +          __ addptr(data_addr, DataLayout::counter_increment);
   1.370            return;
   1.371          }
   1.372        }
   1.373 @@ -3288,49 +3340,26 @@
   1.374            Address recv_addr(mdo, md->byte_offset_of_slot(data, VirtualCallData::receiver_offset(i)));
   1.375            __ movoop(recv_addr, known_klass->constant_encoding());
   1.376            Address data_addr(mdo, md->byte_offset_of_slot(data, VirtualCallData::receiver_count_offset(i)));
   1.377 -          __ addl(data_addr, DataLayout::counter_increment);
   1.378 +          __ addptr(data_addr, DataLayout::counter_increment);
   1.379            return;
   1.380          }
   1.381        }
   1.382      } else {
   1.383        __ movptr(recv, Address(recv, oopDesc::klass_offset_in_bytes()));
   1.384        Label update_done;
   1.385 -      uint i;
   1.386 -      for (i = 0; i < VirtualCallData::row_limit(); i++) {
   1.387 -        Label next_test;
   1.388 -        // See if the receiver is receiver[n].
   1.389 -        __ cmpptr(recv, Address(mdo, md->byte_offset_of_slot(data, VirtualCallData::receiver_offset(i))));
   1.390 -        __ jcc(Assembler::notEqual, next_test);
   1.391 -        Address data_addr(mdo, md->byte_offset_of_slot(data, VirtualCallData::receiver_count_offset(i)));
   1.392 -        __ addl(data_addr, DataLayout::counter_increment);
   1.393 -        __ jmp(update_done);
   1.394 -        __ bind(next_test);
   1.395 -      }
   1.396 -
   1.397 -      // Didn't find receiver; find next empty slot and fill it in
   1.398 -      for (i = 0; i < VirtualCallData::row_limit(); i++) {
   1.399 -        Label next_test;
   1.400 -        Address recv_addr(mdo, md->byte_offset_of_slot(data, VirtualCallData::receiver_offset(i)));
   1.401 -        __ cmpptr(recv_addr, (int32_t)NULL_WORD);
   1.402 -        __ jcc(Assembler::notEqual, next_test);
   1.403 -        __ movptr(recv_addr, recv);
   1.404 -        __ movl(Address(mdo, md->byte_offset_of_slot(data, VirtualCallData::receiver_count_offset(i))), DataLayout::counter_increment);
   1.405 -        __ jmp(update_done);
   1.406 -        __ bind(next_test);
   1.407 -      }
   1.408 +      type_profile_helper(mdo, md, data, recv, &update_done);
   1.409        // Receiver did not match any saved receiver and there is no empty row for it.
   1.410        // Increment total counter to indicate polymorphic case.
   1.411 -      __ addl(counter_addr, DataLayout::counter_increment);
   1.412 +      __ addptr(counter_addr, DataLayout::counter_increment);
   1.413  
   1.414        __ bind(update_done);
   1.415      }
   1.416    } else {
   1.417      // Static call
   1.418 -    __ addl(counter_addr, DataLayout::counter_increment);
   1.419 +    __ addptr(counter_addr, DataLayout::counter_increment);
   1.420    }
   1.421  }
   1.422  
   1.423 -
   1.424  void LIR_Assembler::emit_delay(LIR_OpDelay*) {
   1.425    Unimplemented();
   1.426  }

mercurial