Print this page


Split Close
Expand all
Collapse all
          --- old/src/share/vm/opto/parse3.cpp
          +++ new/src/share/vm/opto/parse3.cpp
↓ open down ↓ 409 lines elided ↑ open up ↑
 410  410  void Parse::do_multianewarray() {
 411  411    int ndimensions = iter().get_dimensions();
 412  412  
 413  413    // the m-dimensional array
 414  414    bool will_link;
 415  415    ciArrayKlass* array_klass = iter().get_klass(will_link)->as_array_klass();
 416  416    assert(will_link, "multianewarray: typeflow responsibility");
 417  417  
 418  418    // Note:  Array classes are always initialized; no is_initialized check.
 419  419  
 420      -  enum { MAX_DIMENSION = 5 };
 421      -  if (ndimensions > MAX_DIMENSION || ndimensions <= 0) {
 422      -    uncommon_trap(Deoptimization::Reason_unhandled,
 423      -                  Deoptimization::Action_none);
 424      -    return;
 425      -  }
 426      -
 427  420    kill_dead_locals();
 428  421  
 429  422    // get the lengths from the stack (first dimension is on top)
 430      -  Node* length[MAX_DIMENSION+1];
      423 +  Node** length = NEW_RESOURCE_ARRAY(Node*, ndimensions + 1);
 431  424    length[ndimensions] = NULL;  // terminating null for make_runtime_call
 432  425    int j;
 433  426    for (j = ndimensions-1; j >= 0 ; j--) length[j] = pop();
 434  427  
 435  428    // The original expression was of this form: new T[length0][length1]...
 436  429    // It is often the case that the lengths are small (except the last).
 437  430    // If that happens, use the fast 1-d creator a constant number of times.
 438  431    const jint expand_limit = MIN2((juint)MultiArrayExpandLimit, (juint)100);
 439  432    jint expand_count = 1;        // count of allocations in the expansion
 440  433    jint expand_fanout = 1;       // running total fanout
↓ open down ↓ 22 lines elided ↑ open up ↑
 463  456        _sp += ndimensions;
 464  457        // Pass 0 as nargs since uncommon trap code does not need to restore stack.
 465  458        obj = expand_multianewarray(array_klass, &length[0], ndimensions, 0);
 466  459      } //original reexecute and sp are set back here
 467  460      push(obj);
 468  461      return;
 469  462    }
 470  463  
 471  464    address fun = NULL;
 472  465    switch (ndimensions) {
 473      -  //case 1: Actually, there is no case 1.  It's handled by new_array.
      466 +  case 1: ShouldNotReachHere(); break; 
 474  467    case 2: fun = OptoRuntime::multianewarray2_Java(); break;
 475  468    case 3: fun = OptoRuntime::multianewarray3_Java(); break;
 476  469    case 4: fun = OptoRuntime::multianewarray4_Java(); break;
 477  470    case 5: fun = OptoRuntime::multianewarray5_Java(); break;
 478      -  default: ShouldNotReachHere();
 479  471    };
      472 +  Node* c = NULL;
      473 +
      474 +  if (fun != NULL) {
      475 +    c = make_runtime_call(RC_NO_LEAF | RC_NO_IO,
      476 +                          OptoRuntime::multianewarray_Type(ndimensions),
      477 +                          fun, NULL, TypeRawPtr::BOTTOM,
      478 +                          makecon(TypeKlassPtr::make(array_klass)),
      479 +                          length[0], length[1], length[2],
      480 +                          length[3], length[4]);
      481 +  } else {
      482 +    // Create a java array for dimension sizes
      483 +    Node* dims = NULL;
      484 +    { PreserveReexecuteState preexecs(this);
      485 +      _sp += ndimensions; 
      486 +      Node* dims_array_klass = makecon(TypeKlassPtr::make(ciArrayKlass::make(ciType::make(T_INT))));
      487 +      dims = new_array(dims_array_klass, intcon(ndimensions), 0);
      488 +
      489 +      // Fill-in it with values
      490 +      for (j = 0; j < ndimensions; j++) {
      491 +        Node *dims_elem = array_element_address(dims, intcon(j), T_INT);
      492 +        store_to_memory(control(), dims_elem, length[j], T_INT, TypeAryPtr::INTS);
      493 +      }
      494 +    }
      495 +
      496 +    c = make_runtime_call(RC_NO_LEAF | RC_NO_IO,
      497 +                          OptoRuntime::multianewarrayN_Type(),
      498 +                          OptoRuntime::multianewarrayN_Java(), NULL, TypeRawPtr::BOTTOM,
      499 +                          makecon(TypeKlassPtr::make(array_klass)),
      500 +                          dims);
      501 +  }
 480  502  
 481      -  Node* c = make_runtime_call(RC_NO_LEAF | RC_NO_IO,
 482      -                              OptoRuntime::multianewarray_Type(ndimensions),
 483      -                              fun, NULL, TypeRawPtr::BOTTOM,
 484      -                              makecon(TypeKlassPtr::make(array_klass)),
 485      -                              length[0], length[1], length[2],
 486      -                              length[3], length[4]);
 487  503    Node* res = _gvn.transform(new (C, 1) ProjNode(c, TypeFunc::Parms));
 488  504  
 489  505    const Type* type = TypeOopPtr::make_from_klass_raw(array_klass);
 490  506  
 491  507    // Improve the type:  We know it's not null, exact, and of a given length.
 492  508    type = type->is_ptr()->cast_to_ptr_type(TypePtr::NotNull);
 493  509    type = type->is_aryptr()->cast_to_exactness(true);
 494  510  
 495  511    const TypeInt* ltype = _gvn.find_int_type(length[0]);
 496  512    if (ltype != NULL)
 497  513      type = type->is_aryptr()->cast_to_size(ltype);
 498  514  
 499      -  // We cannot sharpen the nested sub-arrays, since the top level is mutable.
      515 +    // We cannot sharpen the nested sub-arrays, since the top level is mutable.
 500  516  
 501  517    Node* cast = _gvn.transform( new (C, 2) CheckCastPPNode(control(), res, type) );
 502  518    push(cast);
 503  519  
 504  520    // Possible improvements:
 505  521    // - Make a fast path for small multi-arrays.  (W/ implicit init. loops.)
 506  522    // - Issue CastII against length[*] values, to TypeInt::POS.
 507  523  }
    
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX