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 ↓ 27 lines elided ↑ open up ↑
 468  461      return;
 469  462    }
 470  463  
 471  464    address fun = NULL;
 472  465    switch (ndimensions) {
 473  466    //case 1: Actually, there is no case 1.  It's handled by new_array.
 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 dimention sizes
      483 +    Node* dims_array_klass = makecon(TypeKlassPtr::make(ciArrayKlass::make(ciType::make(T_INT))));
      484 +    Node* dims = new_array(dims_array_klass, intcon(ndimensions), 0);
      485 +
      486 +    // Fill-in it with values
      487 +    for (j = 0; j < ndimensions; j++) {
      488 +      Node *dims_elem = array_element_address(dims, intcon(j), T_INT);
      489 +      store_to_memory(control(), dims_elem, length[j], T_INT, TypeAryPtr::INTS);
      490 +    }
      491 +
      492 +    c = make_runtime_call(RC_NO_LEAF | RC_NO_IO,
      493 +                          OptoRuntime::multianewarrayN_Type(),
      494 +                          OptoRuntime::multianewarrayN_Java(), NULL, TypeRawPtr::BOTTOM,
      495 +                          makecon(TypeKlassPtr::make(array_klass)),
      496 +                          dims);
      497 +  }
 480  498  
 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  499    Node* res = _gvn.transform(new (C, 1) ProjNode(c, TypeFunc::Parms));
 488  500  
 489  501    const Type* type = TypeOopPtr::make_from_klass_raw(array_klass);
 490  502  
 491  503    // Improve the type:  We know it's not null, exact, and of a given length.
 492  504    type = type->is_ptr()->cast_to_ptr_type(TypePtr::NotNull);
 493  505    type = type->is_aryptr()->cast_to_exactness(true);
 494  506  
 495  507    const TypeInt* ltype = _gvn.find_int_type(length[0]);
 496  508    if (ltype != NULL)
 497  509      type = type->is_aryptr()->cast_to_size(ltype);
 498  510  
 499      -  // We cannot sharpen the nested sub-arrays, since the top level is mutable.
      511 +    // We cannot sharpen the nested sub-arrays, since the top level is mutable.
 500  512  
 501  513    Node* cast = _gvn.transform( new (C, 2) CheckCastPPNode(control(), res, type) );
 502  514    push(cast);
 503  515  
 504  516    // Possible improvements:
 505  517    // - Make a fast path for small multi-arrays.  (W/ implicit init. loops.)
 506  518    // - Issue CastII against length[*] values, to TypeInt::POS.
 507  519  }
    
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX