6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation

Tue, 04 Aug 2009 21:32:08 -0700

author
cfang
date
Tue, 04 Aug 2009 21:32:08 -0700
changeset 1337
fc2281ddce3c
parent 1336
2b9164d13ce9
child 1338
15bbd3f505c0

6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
Summary: Improvement on reexecute implementation to fix the assertion failure
Reviewed-by: kvn, never

src/share/vm/opto/library_call.cpp file | annotate | diff | comparison | revisions
     1.1 --- a/src/share/vm/opto/library_call.cpp	Tue Aug 04 17:11:17 2009 -0700
     1.2 +++ b/src/share/vm/opto/library_call.cpp	Tue Aug 04 21:32:08 2009 -0700
     1.3 @@ -3169,65 +3169,62 @@
     1.4    Node* end               = is_copyOfRange? argument(2): argument(1);
     1.5    Node* array_type_mirror = is_copyOfRange? argument(3): argument(2);
     1.6  
     1.7 -  _sp += nargs;  // set original stack for use by uncommon_trap
     1.8 -  array_type_mirror = do_null_check(array_type_mirror, T_OBJECT);
     1.9 -  original          = do_null_check(original, T_OBJECT);
    1.10 -  _sp -= nargs;
    1.11 -
    1.12 -  // Check if a null path was taken unconditionally.
    1.13 -  if (stopped())  return true;
    1.14 -
    1.15 -  Node* orig_length = load_array_length(original);
    1.16 -
    1.17 -  Node* klass_node = load_klass_from_mirror(array_type_mirror, false, nargs,
    1.18 -                                            NULL, 0);
    1.19 -  _sp += nargs;  // set original stack for use by uncommon_trap
    1.20 -  klass_node = do_null_check(klass_node, T_OBJECT);
    1.21 -  _sp -= nargs;
    1.22 -
    1.23 -  RegionNode* bailout = new (C, 1) RegionNode(1);
    1.24 -  record_for_igvn(bailout);
    1.25 -
    1.26 -  // Despite the generic type of Arrays.copyOf, the mirror might be int, int[], etc.
    1.27 -  // Bail out if that is so.
    1.28 -  Node* not_objArray = generate_non_objArray_guard(klass_node, bailout);
    1.29 -  if (not_objArray != NULL) {
    1.30 -    // Improve the klass node's type from the new optimistic assumption:
    1.31 -    ciKlass* ak = ciArrayKlass::make(env()->Object_klass());
    1.32 -    const Type* akls = TypeKlassPtr::make(TypePtr::NotNull, ak, 0/*offset*/);
    1.33 -    Node* cast = new (C, 2) CastPPNode(klass_node, akls);
    1.34 -    cast->init_req(0, control());
    1.35 -    klass_node = _gvn.transform(cast);
    1.36 -  }
    1.37 -
    1.38 -  // Bail out if either start or end is negative.
    1.39 -  generate_negative_guard(start, bailout, &start);
    1.40 -  generate_negative_guard(end,   bailout, &end);
    1.41 -
    1.42 -  Node* length = end;
    1.43 -  if (_gvn.type(start) != TypeInt::ZERO) {
    1.44 -    length = _gvn.transform( new (C, 3) SubINode(end, start) );
    1.45 -  }
    1.46 -
    1.47 -  // Bail out if length is negative.
    1.48 -  // ...Not needed, since the new_array will throw the right exception.
    1.49 -  //generate_negative_guard(length, bailout, &length);
    1.50 -
    1.51 -  if (bailout->req() > 1) {
    1.52 -    PreserveJVMState pjvms(this);
    1.53 -    set_control( _gvn.transform(bailout) );
    1.54 -    _sp += nargs;  // push the arguments back on the stack
    1.55 -    uncommon_trap(Deoptimization::Reason_intrinsic,
    1.56 -                  Deoptimization::Action_maybe_recompile);
    1.57 -  }
    1.58 -
    1.59 -  if (!stopped()) {
    1.60 -    Node *newcopy;
    1.61 -    //set the original stack and the reexecute bit for the interpreter to reexecute
    1.62 -    //the bytecode that invokes Arrays.copyOf if deoptimization happens
    1.63 -    { PreserveReexecuteState preexecs(this);
    1.64 -      _sp += nargs;
    1.65 -      jvms()->set_should_reexecute(true);
    1.66 +  Node* newcopy;
    1.67 +
    1.68 +  //set the original stack and the reexecute bit for the interpreter to reexecute
    1.69 +  //the bytecode that invokes Arrays.copyOf if deoptimization happens
    1.70 +  { PreserveReexecuteState preexecs(this);
    1.71 +    _sp += nargs;
    1.72 +    jvms()->set_should_reexecute(true);
    1.73 +
    1.74 +    array_type_mirror = do_null_check(array_type_mirror, T_OBJECT);
    1.75 +    original          = do_null_check(original, T_OBJECT);
    1.76 +
    1.77 +    // Check if a null path was taken unconditionally.
    1.78 +    if (stopped())  return true;
    1.79 +
    1.80 +    Node* orig_length = load_array_length(original);
    1.81 +
    1.82 +    Node* klass_node = load_klass_from_mirror(array_type_mirror, false, 0,
    1.83 +                                              NULL, 0);
    1.84 +    klass_node = do_null_check(klass_node, T_OBJECT);
    1.85 +
    1.86 +    RegionNode* bailout = new (C, 1) RegionNode(1);
    1.87 +    record_for_igvn(bailout);
    1.88 +
    1.89 +    // Despite the generic type of Arrays.copyOf, the mirror might be int, int[], etc.
    1.90 +    // Bail out if that is so.
    1.91 +    Node* not_objArray = generate_non_objArray_guard(klass_node, bailout);
    1.92 +    if (not_objArray != NULL) {
    1.93 +      // Improve the klass node's type from the new optimistic assumption:
    1.94 +      ciKlass* ak = ciArrayKlass::make(env()->Object_klass());
    1.95 +      const Type* akls = TypeKlassPtr::make(TypePtr::NotNull, ak, 0/*offset*/);
    1.96 +      Node* cast = new (C, 2) CastPPNode(klass_node, akls);
    1.97 +      cast->init_req(0, control());
    1.98 +      klass_node = _gvn.transform(cast);
    1.99 +    }
   1.100 +
   1.101 +    // Bail out if either start or end is negative.
   1.102 +    generate_negative_guard(start, bailout, &start);
   1.103 +    generate_negative_guard(end,   bailout, &end);
   1.104 +
   1.105 +    Node* length = end;
   1.106 +    if (_gvn.type(start) != TypeInt::ZERO) {
   1.107 +      length = _gvn.transform( new (C, 3) SubINode(end, start) );
   1.108 +    }
   1.109 +
   1.110 +    // Bail out if length is negative.
   1.111 +    // ...Not needed, since the new_array will throw the right exception.
   1.112 +    //generate_negative_guard(length, bailout, &length);
   1.113 +
   1.114 +    if (bailout->req() > 1) {
   1.115 +      PreserveJVMState pjvms(this);
   1.116 +      set_control( _gvn.transform(bailout) );
   1.117 +      uncommon_trap(Deoptimization::Reason_intrinsic,
   1.118 +                    Deoptimization::Action_maybe_recompile);
   1.119 +    }
   1.120 +
   1.121 +    if (!stopped()) {
   1.122  
   1.123        // How many elements will we copy from the original?
   1.124        // The answer is MinI(orig_length - start, length).
   1.125 @@ -3247,8 +3244,10 @@
   1.126        generate_arraycopy(TypeAryPtr::OOPS, T_OBJECT,
   1.127                           original, start, newcopy, intcon(0), moved,
   1.128                           disjoint_bases, length_never_negative);
   1.129 -    } //original reexecute and sp are set back here
   1.130 -
   1.131 +    }
   1.132 +  } //original reexecute and sp are set back here
   1.133 +
   1.134 +  if(!stopped()) {
   1.135      push(newcopy);
   1.136    }
   1.137  
   1.138 @@ -4000,43 +3999,49 @@
   1.139  //
   1.140  bool LibraryCallKit::inline_native_clone(bool is_virtual) {
   1.141    int nargs = 1;
   1.142 -  Node* obj = null_check_receiver(callee());
   1.143 -  if (stopped())  return true;
   1.144 -  Node* obj_klass = load_object_klass(obj);
   1.145 -  const TypeKlassPtr* tklass = _gvn.type(obj_klass)->isa_klassptr();
   1.146 -  const TypeOopPtr*   toop   = ((tklass != NULL)
   1.147 -                                ? tklass->as_instance_type()
   1.148 -                                : TypeInstPtr::NOTNULL);
   1.149 -
   1.150 -  // Conservatively insert a memory barrier on all memory slices.
   1.151 -  // Do not let writes into the original float below the clone.
   1.152 -  insert_mem_bar(Op_MemBarCPUOrder);
   1.153 -
   1.154 -  // paths into result_reg:
   1.155 -  enum {
   1.156 -    _slow_path = 1,     // out-of-line call to clone method (virtual or not)
   1.157 -    _objArray_path,     // plain array allocation, plus arrayof_oop_arraycopy
   1.158 -    _array_path,        // plain array allocation, plus arrayof_long_arraycopy
   1.159 -    _instance_path,     // plain instance allocation, plus arrayof_long_arraycopy
   1.160 -    PATH_LIMIT
   1.161 -  };
   1.162 -  RegionNode* result_reg = new(C, PATH_LIMIT) RegionNode(PATH_LIMIT);
   1.163 -  PhiNode*    result_val = new(C, PATH_LIMIT) PhiNode(result_reg,
   1.164 -                                                      TypeInstPtr::NOTNULL);
   1.165 -  PhiNode*    result_i_o = new(C, PATH_LIMIT) PhiNode(result_reg, Type::ABIO);
   1.166 -  PhiNode*    result_mem = new(C, PATH_LIMIT) PhiNode(result_reg, Type::MEMORY,
   1.167 -                                                      TypePtr::BOTTOM);
   1.168 -  record_for_igvn(result_reg);
   1.169 -
   1.170 -  const TypePtr* raw_adr_type = TypeRawPtr::BOTTOM;
   1.171 -  int raw_adr_idx = Compile::AliasIdxRaw;
   1.172 -  const bool raw_mem_only = true;
   1.173 +  PhiNode* result_val;
   1.174  
   1.175    //set the original stack and the reexecute bit for the interpreter to reexecute
   1.176    //the bytecode that invokes Object.clone if deoptimization happens
   1.177    { PreserveReexecuteState preexecs(this);
   1.178 +    jvms()->set_should_reexecute(true);
   1.179 +
   1.180 +    //null_check_receiver will adjust _sp (push and pop)
   1.181 +    Node* obj = null_check_receiver(callee());
   1.182 +    if (stopped())  return true;
   1.183 +
   1.184      _sp += nargs;
   1.185 -    jvms()->set_should_reexecute(true);
   1.186 +
   1.187 +    Node* obj_klass = load_object_klass(obj);
   1.188 +    const TypeKlassPtr* tklass = _gvn.type(obj_klass)->isa_klassptr();
   1.189 +    const TypeOopPtr*   toop   = ((tklass != NULL)
   1.190 +                                ? tklass->as_instance_type()
   1.191 +                                : TypeInstPtr::NOTNULL);
   1.192 +
   1.193 +    // Conservatively insert a memory barrier on all memory slices.
   1.194 +    // Do not let writes into the original float below the clone.
   1.195 +    insert_mem_bar(Op_MemBarCPUOrder);
   1.196 +
   1.197 +    // paths into result_reg:
   1.198 +    enum {
   1.199 +      _slow_path = 1,     // out-of-line call to clone method (virtual or not)
   1.200 +      _objArray_path,     // plain array allocation, plus arrayof_oop_arraycopy
   1.201 +      _array_path,        // plain array allocation, plus arrayof_long_arraycopy
   1.202 +      _instance_path,     // plain instance allocation, plus arrayof_long_arraycopy
   1.203 +      PATH_LIMIT
   1.204 +    };
   1.205 +    RegionNode* result_reg = new(C, PATH_LIMIT) RegionNode(PATH_LIMIT);
   1.206 +    result_val             = new(C, PATH_LIMIT) PhiNode(result_reg,
   1.207 +                                                        TypeInstPtr::NOTNULL);
   1.208 +    PhiNode*    result_i_o = new(C, PATH_LIMIT) PhiNode(result_reg, Type::ABIO);
   1.209 +    PhiNode*    result_mem = new(C, PATH_LIMIT) PhiNode(result_reg, Type::MEMORY,
   1.210 +                                                        TypePtr::BOTTOM);
   1.211 +    record_for_igvn(result_reg);
   1.212 +
   1.213 +    const TypePtr* raw_adr_type = TypeRawPtr::BOTTOM;
   1.214 +    int raw_adr_idx = Compile::AliasIdxRaw;
   1.215 +    const bool raw_mem_only = true;
   1.216 +
   1.217  
   1.218      Node* array_ctl = generate_array_guard(obj_klass, (RegionNode*)NULL);
   1.219      if (array_ctl != NULL) {
   1.220 @@ -4141,13 +4146,13 @@
   1.221        result_i_o ->set_req(_slow_path, i_o());
   1.222        result_mem ->set_req(_slow_path, reset_memory());
   1.223      }
   1.224 +
   1.225 +    // Return the combined state.
   1.226 +    set_control(    _gvn.transform(result_reg) );
   1.227 +    set_i_o(        _gvn.transform(result_i_o) );
   1.228 +    set_all_memory( _gvn.transform(result_mem) );
   1.229    } //original reexecute and sp are set back here
   1.230  
   1.231 -  // Return the combined state.
   1.232 -  set_control(    _gvn.transform(result_reg) );
   1.233 -  set_i_o(        _gvn.transform(result_i_o) );
   1.234 -  set_all_memory( _gvn.transform(result_mem) );
   1.235 -
   1.236    push(_gvn.transform(result_val));
   1.237  
   1.238    return true;

mercurial