src/cpu/x86/vm/c1_LIRAssembler_x86.cpp

changeset 5914
d13d7aba8c12
parent 5737
da051ce490eb
child 5980
252d541466ea
     1.1 --- a/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp	Wed Oct 09 11:05:17 2013 -0700
     1.2 +++ b/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp	Wed Oct 09 16:32:21 2013 +0200
     1.3 @@ -3632,6 +3632,161 @@
     1.4    }
     1.5  }
     1.6  
     1.7 +void LIR_Assembler::emit_profile_type(LIR_OpProfileType* op) {
     1.8 +  Register obj = op->obj()->as_register();
     1.9 +  Register tmp = op->tmp()->as_pointer_register();
    1.10 +  Address mdo_addr = as_Address(op->mdp()->as_address_ptr());
    1.11 +  ciKlass* exact_klass = op->exact_klass();
    1.12 +  intptr_t current_klass = op->current_klass();
    1.13 +  bool not_null = op->not_null();
    1.14 +  bool no_conflict = op->no_conflict();
    1.15 +
    1.16 +  Label update, next, none;
    1.17 +
    1.18 +  bool do_null = !not_null;
    1.19 +  bool exact_klass_set = exact_klass != NULL && ciTypeEntries::valid_ciklass(current_klass) == exact_klass;
    1.20 +  bool do_update = !TypeEntries::is_type_unknown(current_klass) && !exact_klass_set;
    1.21 +
    1.22 +  assert(do_null || do_update, "why are we here?");
    1.23 +  assert(!TypeEntries::was_null_seen(current_klass) || do_update, "why are we here?");
    1.24 +
    1.25 +  __ verify_oop(obj);
    1.26 +
    1.27 +  if (tmp != obj) {
    1.28 +    __ mov(tmp, obj);
    1.29 +  }
    1.30 +  if (do_null) {
    1.31 +    __ testptr(tmp, tmp);
    1.32 +    __ jccb(Assembler::notZero, update);
    1.33 +    if (!TypeEntries::was_null_seen(current_klass)) {
    1.34 +      __ orptr(mdo_addr, TypeEntries::null_seen);
    1.35 +    }
    1.36 +    if (do_update) {
    1.37 +#ifndef ASSERT
    1.38 +      __ jmpb(next);
    1.39 +    }
    1.40 +#else
    1.41 +      __ jmp(next);
    1.42 +    }
    1.43 +  } else {
    1.44 +    __ testptr(tmp, tmp);
    1.45 +    __ jccb(Assembler::notZero, update);
    1.46 +    __ stop("unexpect null obj");
    1.47 +#endif
    1.48 +  }
    1.49 +
    1.50 +  __ bind(update);
    1.51 +
    1.52 +  if (do_update) {
    1.53 +#ifdef ASSERT
    1.54 +    if (exact_klass != NULL) {
    1.55 +      Label ok;
    1.56 +      __ load_klass(tmp, tmp);
    1.57 +      __ push(tmp);
    1.58 +      __ mov_metadata(tmp, exact_klass->constant_encoding());
    1.59 +      __ cmpptr(tmp, Address(rsp, 0));
    1.60 +      __ jccb(Assembler::equal, ok);
    1.61 +      __ stop("exact klass and actual klass differ");
    1.62 +      __ bind(ok);
    1.63 +      __ pop(tmp);
    1.64 +    }
    1.65 +#endif
    1.66 +    if (!no_conflict) {
    1.67 +      if (exact_klass == NULL || TypeEntries::is_type_none(current_klass)) {
    1.68 +        if (exact_klass != NULL) {
    1.69 +          __ mov_metadata(tmp, exact_klass->constant_encoding());
    1.70 +        } else {
    1.71 +          __ load_klass(tmp, tmp);
    1.72 +        }
    1.73 +
    1.74 +        __ xorptr(tmp, mdo_addr);
    1.75 +        __ testptr(tmp, TypeEntries::type_klass_mask);
    1.76 +        // klass seen before, nothing to do. The unknown bit may have been
    1.77 +        // set already but no need to check.
    1.78 +        __ jccb(Assembler::zero, next);
    1.79 +
    1.80 +        __ testptr(tmp, TypeEntries::type_unknown);
    1.81 +        __ jccb(Assembler::notZero, next); // already unknown. Nothing to do anymore.
    1.82 +
    1.83 +        if (TypeEntries::is_type_none(current_klass)) {
    1.84 +          __ cmpptr(mdo_addr, 0);
    1.85 +          __ jccb(Assembler::equal, none);
    1.86 +          __ cmpptr(mdo_addr, TypeEntries::null_seen);
    1.87 +          __ jccb(Assembler::equal, none);
    1.88 +          // There is a chance that the checks above (re-reading profiling
    1.89 +          // data from memory) fail if another thread has just set the
    1.90 +          // profiling to this obj's klass
    1.91 +          __ xorptr(tmp, mdo_addr);
    1.92 +          __ testptr(tmp, TypeEntries::type_klass_mask);
    1.93 +          __ jccb(Assembler::zero, next);
    1.94 +        }
    1.95 +      } else {
    1.96 +        assert(ciTypeEntries::valid_ciklass(current_klass) != NULL &&
    1.97 +               ciTypeEntries::valid_ciklass(current_klass) != exact_klass, "conflict only");
    1.98 +
    1.99 +        __ movptr(tmp, mdo_addr);
   1.100 +        __ testptr(tmp, TypeEntries::type_unknown);
   1.101 +        __ jccb(Assembler::notZero, next); // already unknown. Nothing to do anymore.
   1.102 +      }
   1.103 +
   1.104 +      // different than before. Cannot keep accurate profile.
   1.105 +      __ orptr(mdo_addr, TypeEntries::type_unknown);
   1.106 +
   1.107 +      if (TypeEntries::is_type_none(current_klass)) {
   1.108 +        __ jmpb(next);
   1.109 +
   1.110 +        __ bind(none);
   1.111 +        // first time here. Set profile type.
   1.112 +        __ movptr(mdo_addr, tmp);
   1.113 +      }
   1.114 +    } else {
   1.115 +      // There's a single possible klass at this profile point
   1.116 +      assert(exact_klass != NULL, "should be");
   1.117 +      if (TypeEntries::is_type_none(current_klass)) {
   1.118 +        __ mov_metadata(tmp, exact_klass->constant_encoding());
   1.119 +        __ xorptr(tmp, mdo_addr);
   1.120 +        __ testptr(tmp, TypeEntries::type_klass_mask);
   1.121 +#ifdef ASSERT
   1.122 +        __ jcc(Assembler::zero, next);
   1.123 +
   1.124 +        {
   1.125 +          Label ok;
   1.126 +          __ push(tmp);
   1.127 +          __ cmpptr(mdo_addr, 0);
   1.128 +          __ jcc(Assembler::equal, ok);
   1.129 +          __ cmpptr(mdo_addr, TypeEntries::null_seen);
   1.130 +          __ jcc(Assembler::equal, ok);
   1.131 +          // may have been set by another thread
   1.132 +          __ mov_metadata(tmp, exact_klass->constant_encoding());
   1.133 +          __ xorptr(tmp, mdo_addr);
   1.134 +          __ testptr(tmp, TypeEntries::type_mask);
   1.135 +          __ jcc(Assembler::zero, ok);
   1.136 +
   1.137 +          __ stop("unexpected profiling mismatch");
   1.138 +          __ bind(ok);
   1.139 +          __ pop(tmp);
   1.140 +        }
   1.141 +#else
   1.142 +        __ jccb(Assembler::zero, next);
   1.143 +#endif
   1.144 +        // first time here. Set profile type.
   1.145 +        __ movptr(mdo_addr, tmp);
   1.146 +      } else {
   1.147 +        assert(ciTypeEntries::valid_ciklass(current_klass) != NULL &&
   1.148 +               ciTypeEntries::valid_ciklass(current_klass) != exact_klass, "inconsistent");
   1.149 +
   1.150 +        __ movptr(tmp, mdo_addr);
   1.151 +        __ testptr(tmp, TypeEntries::type_unknown);
   1.152 +        __ jccb(Assembler::notZero, next); // already unknown. Nothing to do anymore.
   1.153 +
   1.154 +        __ orptr(mdo_addr, TypeEntries::type_unknown);
   1.155 +      }
   1.156 +    }
   1.157 +
   1.158 +    __ bind(next);
   1.159 +  }
   1.160 +}
   1.161 +
   1.162  void LIR_Assembler::emit_delay(LIR_OpDelay*) {
   1.163    Unimplemented();
   1.164  }

mercurial