326 __ brx(Assembler::equal, false, Assembler::pt, no_deopt);
327 __ delayed()->nop();
328
329 // return to the deoptimization handler entry for unpacking and rexecute
330 // if we simply returned the we'd deopt as if any call we patched had just
331 // returned.
332
333 restore_live_registers(sasm);
334 __ restore();
335 __ br(Assembler::always, false, Assembler::pt, deopt_blob->unpack_with_reexecution(), relocInfo::runtime_call_type);
336 __ delayed()->nop();
337
338 __ bind(no_deopt);
339 restore_live_registers(sasm);
340 __ ret();
341 __ delayed()->restore();
342
343 return oop_maps;
344 }
345
346 OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) {
347
348 OopMapSet* oop_maps = NULL;
349 // for better readability
350 const bool must_gc_arguments = true;
351 const bool dont_gc_arguments = false;
352
353 // stub code & info for the different stubs
354 switch (id) {
355 case forward_exception_id:
356 {
357 // we're handling an exception in the context of a compiled
358 // frame. The registers have been saved in the standard
359 // places. Perform an exception lookup in the caller and
360 // dispatch to the handler if found. Otherwise unwind and
361 // dispatch to the callers exception handler.
362
363 oop_maps = new OopMapSet();
364 OopMap* oop_map = generate_oop_map(sasm, true);
365
396 Register G1_obj_size = G1;
397 Register G3_t1 = G3;
398 Register G4_t2 = G4;
399 assert_different_registers(G5_klass, G1_obj_size, G3_t1, G4_t2);
400
401 // Push a frame since we may do dtrace notification for the
402 // allocation which requires calling out and we don't want
403 // to stomp the real return address.
404 __ save_frame(0);
405
406 if (id == fast_new_instance_init_check_id) {
407 // make sure the klass is initialized
408 __ ld(G5_klass, instanceKlass::init_state_offset_in_bytes() + sizeof(oopDesc), G3_t1);
409 __ cmp(G3_t1, instanceKlass::fully_initialized);
410 __ br(Assembler::notEqual, false, Assembler::pn, slow_path);
411 __ delayed()->nop();
412 }
413 #ifdef ASSERT
414 // assert object can be fast path allocated
415 {
416 Label ok, not_ok;
417 __ ld(G5_klass, Klass::layout_helper_offset_in_bytes() + sizeof(oopDesc), G1_obj_size);
418 __ cmp(G1_obj_size, 0); // make sure it's an instance (LH > 0)
419 __ br(Assembler::lessEqual, false, Assembler::pn, not_ok);
420 __ delayed()->nop();
421 __ btst(Klass::_lh_instance_slow_path_bit, G1_obj_size);
422 __ br(Assembler::zero, false, Assembler::pn, ok);
423 __ delayed()->nop();
424 __ bind(not_ok);
425 __ stop("assert(can be fast path allocated)");
426 __ should_not_reach_here();
427 __ bind(ok);
428 }
429 #endif // ASSERT
430 // if we got here then the TLAB allocation failed, so try
431 // refilling the TLAB or allocating directly from eden.
432 Label retry_tlab, try_eden;
433 __ tlab_refill(retry_tlab, try_eden, slow_path); // preserves G5_klass
434
435 __ bind(retry_tlab);
436
437 // get the instance size
438 __ ld(G5_klass, klassOopDesc::header_size() * HeapWordSize + Klass::layout_helper_offset_in_bytes(), G1_obj_size);
439 __ tlab_allocate(O0_obj, G1_obj_size, 0, G3_t1, slow_path);
440 __ initialize_object(O0_obj, G5_klass, G1_obj_size, 0, G3_t1, G4_t2);
441 __ verify_oop(O0_obj);
442 __ mov(O0, I0);
443 __ ret();
444 __ delayed()->restore();
445
446 __ bind(try_eden);
447 // get the instance size
448 __ ld(G5_klass, klassOopDesc::header_size() * HeapWordSize + Klass::layout_helper_offset_in_bytes(), G1_obj_size);
449 __ eden_allocate(O0_obj, G1_obj_size, 0, G3_t1, G4_t2, slow_path);
450 __ initialize_object(O0_obj, G5_klass, G1_obj_size, 0, G3_t1, G4_t2);
451 __ verify_oop(O0_obj);
452 __ mov(O0, I0);
453 __ ret();
454 __ delayed()->restore();
455
456 __ bind(slow_path);
457
458 // pop this frame so generate_stub_call can push it's own
459 __ restore();
460 }
461
462 oop_maps = generate_stub_call(sasm, I0, CAST_FROM_FN_PTR(address, new_instance), G5_klass);
463 // I0->O0: new instance
464 }
465
466 break;
467
468 #ifdef TIERED
469 case counter_overflow_id:
470 // G4 contains bci
471 oop_maps = generate_stub_call(sasm, noreg, CAST_FROM_FN_PTR(address, counter_overflow), G4);
472 break;
473 #endif // TIERED
474
475 case new_type_array_id:
476 case new_object_array_id:
477 {
478 Register G5_klass = G5; // Incoming
479 Register G4_length = G4; // Incoming
480 Register O0_obj = O0; // Outgoing
481
482 Address klass_lh(G5_klass, 0, ((klassOopDesc::header_size() * HeapWordSize)
483 + Klass::layout_helper_offset_in_bytes()));
484 assert(Klass::_lh_header_size_shift % BitsPerByte == 0, "bytewise");
485 assert(Klass::_lh_header_size_mask == 0xFF, "bytewise");
486 // Use this offset to pick out an individual byte of the layout_helper:
487 const int klass_lh_header_size_offset = ((BytesPerInt - 1) // 3 - 2 selects byte {0,1,0,0}
488 - Klass::_lh_header_size_shift / BitsPerByte);
489
490 if (id == new_type_array_id) {
491 __ set_info("new_type_array", dont_gc_arguments);
492 } else {
493 __ set_info("new_object_array", dont_gc_arguments);
494 }
495
496 #ifdef ASSERT
497 // assert object type is really an array of the proper kind
498 {
499 Label ok;
500 Register G3_t1 = G3;
501 __ ld(klass_lh, G3_t1);
502 __ sra(G3_t1, Klass::_lh_array_tag_shift, G3_t1);
503 int tag = ((id == new_type_array_id)
504 ? Klass::_lh_array_tag_type_value
505 : Klass::_lh_array_tag_obj_value);
506 __ cmp(G3_t1, tag);
507 __ brx(Assembler::equal, false, Assembler::pt, ok);
508 __ delayed()->nop();
509 __ stop("assert(is an array klass)");
510 __ should_not_reach_here();
511 __ bind(ok);
512 }
513 #endif // ASSERT
514
515 if (UseTLAB && FastTLABRefill) {
516 Label slow_path;
517 Register G1_arr_size = G1;
518 Register G3_t1 = G3;
519 Register O1_t2 = O1;
520 assert_different_registers(G5_klass, G4_length, G1_arr_size, G3_t1, O1_t2);
521
522 // check that array length is small enough for fast path
523 __ set(C1_MacroAssembler::max_array_allocation_length, G3_t1);
524 __ cmp(G4_length, G3_t1);
525 __ br(Assembler::greaterUnsigned, false, Assembler::pn, slow_path);
526 __ delayed()->nop();
527
528 // if we got here then the TLAB allocation failed, so try
529 // refilling the TLAB or allocating directly from eden.
530 Label retry_tlab, try_eden;
531 __ tlab_refill(retry_tlab, try_eden, slow_path); // preserves G4_length and G5_klass
532
533 __ bind(retry_tlab);
534
535 // get the allocation size: (length << (layout_helper & 0x1F)) + header_size
536 __ ld(klass_lh, G3_t1);
537 __ sll(G4_length, G3_t1, G1_arr_size);
538 __ srl(G3_t1, Klass::_lh_header_size_shift, G3_t1);
539 __ and3(G3_t1, Klass::_lh_header_size_mask, G3_t1);
540 __ add(G1_arr_size, G3_t1, G1_arr_size);
541 __ add(G1_arr_size, MinObjAlignmentInBytesMask, G1_arr_size); // align up
542 __ and3(G1_arr_size, ~MinObjAlignmentInBytesMask, G1_arr_size);
543
544 __ tlab_allocate(O0_obj, G1_arr_size, 0, G3_t1, slow_path); // preserves G1_arr_size
545
546 __ initialize_header(O0_obj, G5_klass, G4_length, G3_t1, O1_t2);
547 __ ldub(klass_lh, G3_t1, klass_lh_header_size_offset);
548 __ sub(G1_arr_size, G3_t1, O1_t2); // body length
549 __ add(O0_obj, G3_t1, G3_t1); // body start
550 __ initialize_body(G3_t1, O1_t2);
551 __ verify_oop(O0_obj);
552 __ retl();
553 __ delayed()->nop();
554
555 __ bind(try_eden);
556 // get the allocation size: (length << (layout_helper & 0x1F)) + header_size
557 __ ld(klass_lh, G3_t1);
558 __ sll(G4_length, G3_t1, G1_arr_size);
559 __ srl(G3_t1, Klass::_lh_header_size_shift, G3_t1);
560 __ and3(G3_t1, Klass::_lh_header_size_mask, G3_t1);
561 __ add(G1_arr_size, G3_t1, G1_arr_size);
562 __ add(G1_arr_size, MinObjAlignmentInBytesMask, G1_arr_size);
563 __ and3(G1_arr_size, ~MinObjAlignmentInBytesMask, G1_arr_size);
564
565 __ eden_allocate(O0_obj, G1_arr_size, 0, G3_t1, O1_t2, slow_path); // preserves G1_arr_size
566
567 __ initialize_header(O0_obj, G5_klass, G4_length, G3_t1, O1_t2);
568 __ ldub(klass_lh, G3_t1, klass_lh_header_size_offset);
569 __ sub(G1_arr_size, G3_t1, O1_t2); // body length
570 __ add(O0_obj, G3_t1, G3_t1); // body start
571 __ initialize_body(G3_t1, O1_t2);
572 __ verify_oop(O0_obj);
573 __ retl();
574 __ delayed()->nop();
575
576 __ bind(slow_path);
577 }
578
579 if (id == new_type_array_id) {
580 oop_maps = generate_stub_call(sasm, I0, CAST_FROM_FN_PTR(address, new_type_array), G5_klass, G4_length);
581 } else {
582 oop_maps = generate_stub_call(sasm, I0, CAST_FROM_FN_PTR(address, new_object_array), G5_klass, G4_length);
583 }
584 // I0 -> O0: new array
585 }
586 break;
587
588 case new_multi_array_id:
589 { // O0: klass
590 // O1: rank
591 // O2: address of 1st dimension
592 __ set_info("new_multi_array", dont_gc_arguments);
593 oop_maps = generate_stub_call(sasm, I0, CAST_FROM_FN_PTR(address, new_multi_array), I0, I1, I2);
594 // I0 -> O0: new multi array
595 }
|
326 __ brx(Assembler::equal, false, Assembler::pt, no_deopt);
327 __ delayed()->nop();
328
329 // return to the deoptimization handler entry for unpacking and rexecute
330 // if we simply returned the we'd deopt as if any call we patched had just
331 // returned.
332
333 restore_live_registers(sasm);
334 __ restore();
335 __ br(Assembler::always, false, Assembler::pt, deopt_blob->unpack_with_reexecution(), relocInfo::runtime_call_type);
336 __ delayed()->nop();
337
338 __ bind(no_deopt);
339 restore_live_registers(sasm);
340 __ ret();
341 __ delayed()->restore();
342
343 return oop_maps;
344 }
345
346 inline Address layout_helper_addr(Register klass) {
347 return Address(klass, 0, (klassOopDesc::header_size() * HeapWordSize
348 + Klass::layout_helper_offset_in_bytes()));
349 }
350
351 static void compute_instance_size(Register obj_size, Register klass,
352 Label& have_obj_size, Label& size_is_variable,
353 Register t1,
354 StubAssembler* sasm, bool hot_part) {
355 assert_different_registers(obj_size, klass, t1);
356
357 if (hot_part) {
358 __ lduw(layout_helper_addr(klass), obj_size);
359 __ andcc(obj_size, ~LayoutHelper::_size_low_mask, obj_size);
360 if (mixed_arrays) {
361 __ jcc(Assembler::negative, size_is_variable);
362 __ bind(have_obj_size);
363 }
364 } else {
365 if (MixedArrays) {
366 // Side path for fixing up the initial size of a variable object.
367 // Must round from int to object alignment, and clear high bits.
368 __ bind(size_is_variable);
369 __ add(obj_size, LayoutHelper::_header_size_odd_mask, obj_size);
370 __ set((LayoutHelper::_header_size_mask & ~MinObjAlignmentInBytesMask), t1);
371 __ and3(obj_size, t1, obj_size);
372 __ jmp(have_obj_size);
373 }
374 }
375 }
376
377 static void compute_array_size(Register arr_size, Register klass, Register length,
378 Label& have_scaled_length, Label& need_multiply,
379 Register t1, Register t2,
380 StubAssembler* sasm, bool hot_part) {
381 assert_different_registers(arr_size, klass, length, t1, t2);
382
383 if (hot_part) {
384 // get the allocation size: round_up(hdr + length << (lh>>16 & 0x1F))
385 __ lduw(layout_helper_addr(klass), t1);
386 // int scale = (lh >> LayoutHelper::_element_size_shift);
387 __ mov(t1, t2); // spill layout helper
388 __ srl(t1, LayoutHelper::_element_size_shift); // lh>>16, no mask needed
389 // size_t arr_size = (array_length << scale);
390 __ sllx(length, t1, arr_size);
391 if (MixedArrays) {
392 // int sizem_ip = (scale & (LayoutHelper::_element_sizem_mask_ip));
393 __ andcc(t1, LayoutHelper::_element_sizem_mask_ip, t1);
394 __ jcc(Assembler::notZero, need_multiply);
395 __ bind(have_scaled_length);
396 }
397 // arr_size += Klass::layout_helper_header_size_in_bytes(lh);
398 assert(LayoutHelper::_header_size_shift == 0, "");
399 // sll(t2, LayoutHelper::_header_size_shift, t2);
400 __ set((LayoutHelper::_header_size_mask & ~MinObjAlignmentInBytesMask), t1);
401 __ and(t2, t1, t2); // t2 = lh & _header_size_mask
402 __ add(arr_size, t2, arr_size);
403 __ add(arr_size, MinObjAlignmentInBytesMask, arr_size); // align up
404 __ and3(arr_size, ~MinObjAlignmentInBytesMask, arr_size);
405 } else {
406 if (MixedArrays) {
407 // Side path for scaling by a non-power-of-two array element size.
408 __ bind(need_multiply);
409 // int sizem = (sizem_ip >> LayoutHelper::_element_scale_bits);
410 __ srl(t1, LayoutHelper::_element_scale_bits, t1);
411 // arr_size = (array_length * (1+sizem)) << scale;
412 __ add(t1, 1, t1);
413 // previous value of arr_size is junk; start from length again
414 assert(wordSize == jintSize, "else use mulx");
415 __ smul(length, t1, arr_size);
416 __ srl(t2, LayoutHelper::_element_size_shift, t1); // lh>>16, mask needed
417 __ and3(t1, LayoutHelper::_element_scale_mask, t1);
418 __ sllx(arr_size, t1, arr_size);
419 __ jmp(have_scaled_length);
420 }
421 }
422 }
423
424 static void initialize_array_body(Register obj, Register arr_size, Register t1, Register t2, StubAssembler* sasm) {
425 assert_different_registers(obj, arr_size, t1, t2);
426
427 int min_header_size = arrayOopDesc::header_size(T_BYTE);
428 __ sub(arr_size, min_header_size, arr_size); // body length
429 __ add(obj, min_header_size, t1); // body start
430 __ initialize_body(t1, arr_size, 0, t2);
431 }
432
433
434 OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) {
435
436 OopMapSet* oop_maps = NULL;
437 // for better readability
438 const bool must_gc_arguments = true;
439 const bool dont_gc_arguments = false;
440
441 // stub code & info for the different stubs
442 switch (id) {
443 case forward_exception_id:
444 {
445 // we're handling an exception in the context of a compiled
446 // frame. The registers have been saved in the standard
447 // places. Perform an exception lookup in the caller and
448 // dispatch to the handler if found. Otherwise unwind and
449 // dispatch to the callers exception handler.
450
451 oop_maps = new OopMapSet();
452 OopMap* oop_map = generate_oop_map(sasm, true);
453
484 Register G1_obj_size = G1;
485 Register G3_t1 = G3;
486 Register G4_t2 = G4;
487 assert_different_registers(G5_klass, G1_obj_size, G3_t1, G4_t2);
488
489 // Push a frame since we may do dtrace notification for the
490 // allocation which requires calling out and we don't want
491 // to stomp the real return address.
492 __ save_frame(0);
493
494 if (id == fast_new_instance_init_check_id) {
495 // make sure the klass is initialized
496 __ ld(G5_klass, instanceKlass::init_state_offset_in_bytes() + sizeof(oopDesc), G3_t1);
497 __ cmp(G3_t1, instanceKlass::fully_initialized);
498 __ br(Assembler::notEqual, false, Assembler::pn, slow_path);
499 __ delayed()->nop();
500 }
501 #ifdef ASSERT
502 // assert object can be fast path allocated
503 {
504 Label ok;
505 __ ld(G5_klass, Klass::layout_helper_offset_in_bytes() + sizeof(oopDesc), G1_obj_size);
506 __ btst(LayoutHelper::_slow_path_low_bit, G1_obj_size);
507 __ br(Assembler::zero, false, Assembler::pn, ok);
508 __ delayed()->nop();
509 __ stop("assert(can be fast path allocated)");
510 __ should_not_reach_here();
511 __ bind(ok);
512 }
513 #endif // ASSERT
514 // if we got here then the TLAB allocation failed, so try
515 // refilling the TLAB or allocating directly from eden.
516 Label retry_tlab, try_eden;
517 __ tlab_refill(retry_tlab, try_eden, slow_path); // preserves G5_klass
518
519 __ bind(retry_tlab);
520
521 // get the instance size
522 Label have_obj_size, size_is_variable;
523 compute_instance_size(G1_obj_size, G5_klass,
524 have_obj_size, size_is_variable,
525 G3_t1, sasm, true);
526 __ tlab_allocate(O0_obj, G1_obj_size, 0, G3_t1, slow_path);
527 __ initialize_object(O0_obj, G5_klass, G1_obj_size, 0, G3_t1, G4_t2);
528 __ verify_oop(O0_obj);
529 __ mov(O0, I0);
530 __ ret();
531 __ delayed()->restore();
532
533 // generate side path, if any
534 compute_instance_size(G1_obj_size, G5_klass,
535 have_obj_size, size_is_variable,
536 G3_t1, sasm, false);
537
538 __ bind(try_eden);
539 // get the instance size
540 Label have_obj_size_2, size_is_variable_2;
541 compute_instance_size(G1_obj_size, G5_klass,
542 have_obj_size_2, size_is_variable_2,
543 G3_t1, sasm, true);
544 __ eden_allocate(O0_obj, G1_obj_size, 0, G3_t1, G4_t2, slow_path);
545 __ initialize_object(O0_obj, G5_klass, G1_obj_size, 0, G3_t1, G4_t2);
546 __ verify_oop(O0_obj);
547 __ mov(O0, I0);
548 __ ret();
549 __ delayed()->restore();
550
551 // generate side path, if any
552 compute_instance_size(G1_obj_size, G5_klass,
553 have_obj_size_2, size_is_variable_2,
554 G3_t1, sasm, false);
555
556 __ bind(slow_path);
557
558 // pop this frame so generate_stub_call can push it's own
559 __ restore();
560 }
561
562 oop_maps = generate_stub_call(sasm, I0, CAST_FROM_FN_PTR(address, new_instance), G5_klass);
563 // I0->O0: new instance
564 }
565
566 break;
567
568 #ifdef TIERED
569 case counter_overflow_id:
570 // G4 contains bci
571 oop_maps = generate_stub_call(sasm, noreg, CAST_FROM_FN_PTR(address, counter_overflow), G4);
572 break;
573 #endif // TIERED
574
575 case new_type_array_id:
576 case new_object_array_id:
577 {
578 Register G5_klass = G5; // Incoming
579 Register G4_length = G4; // Incoming
580 Register O0_obj = O0; // Outgoing
581
582 if (id == new_type_array_id) {
583 __ set_info("new_type_array", dont_gc_arguments);
584 } else {
585 __ set_info("new_object_array", dont_gc_arguments);
586 }
587
588 #ifdef ASSERT
589 // assert object type is really an array of the proper kind
590 {
591 Label ok;
592 Register G3_t1 = G3;
593 __ lduw(layout_helper_addr(G5_klass), G3_t1);
594 int flag_shift = LayoutHelper::_flags_shift;
595 flag_shift += LayoutHelper::_flags_low_bits; // shift out BasicType also
596 int tag = LayoutHelper::for_array((id == new_type_array_id) ? T_BYTE : T_OBJECT).as_int();
597 tag >>= flag_shift;
598 __ sra(G3_t1, flag_shift, G3_t1);
599 assert(id == new_object_array_id ||
600 tag == (LayoutHelper::for_array(T_DOUBLE).as_int() >> flag_shift),
601 "same tag for all type arrays");
602 __ cmp(G3_t1, tag);
603 __ brx(Assembler::equal, false, Assembler::pt, ok);
604 __ delayed()->nop();
605 __ stop("assert(is an array klass)");
606 __ should_not_reach_here();
607 __ bind(ok);
608 }
609 #endif // ASSERT
610
611 if (UseTLAB && FastTLABRefill) {
612 Label slow_path;
613 Register G1_arr_size = G1;
614 Register G3_t1 = G3;
615 Register O1_t2 = O1;
616 assert_different_registers(G5_klass, G4_length, G1_arr_size, G3_t1, O1_t2);
617
618 // check that array length is small enough for fast path
619 __ set(C1_MacroAssembler::max_array_allocation_length, G3_t1);
620 __ cmp(G4_length, G3_t1);
621 __ br(Assembler::greaterUnsigned, false, Assembler::pn, slow_path);
622 __ delayed()->nop();
623
624 // if we got here then the TLAB allocation failed, so try
625 // refilling the TLAB or allocating directly from eden.
626 Label retry_tlab, try_eden;
627 __ tlab_refill(retry_tlab, try_eden, slow_path); // preserves G4_length and G5_klass
628
629 __ bind(retry_tlab);
630
631 // get the allocation size: (length << (layout_helper & 0x1F)) + header_size
632 Label have_scaled_length, need_multiply;
633 compute_array_size(G1_arr_size, G5_klass, G4_length,
634 have_scaled_length, need_multiply,
635 G3_t1, O1_t2, sasm, true);
636 __ tlab_allocate(O0_obj, G1_arr_size, 0, G3_t1, slow_path); // preserves G1_arr_size
637
638 __ initialize_header(O0_obj, G5_klass, G4_length, G3_t1, O1_t2);
639 initialize_array_body(O0_obj, G1_arr_size, G3_t1, O1_t2, sasm);
640 __ verify_oop(O0_obj);
641 __ retl();
642 __ delayed()->nop();
643
644 // generate side path, if any
645 compute_array_size(G1_arr_size, G5_klass, G4_length,
646 have_scaled_length, need_multiply,
647 G3_t1, O1_t2, sasm, false);
648
649 __ bind(try_eden);
650 Label have_scaled_length_2, need_multiply_2;
651 // get the allocation size: (length << (layout_helper & 0x1F)) + header_size
652 compute_array_size(G1_arr_size, G5_klass, G4_length,
653 have_scaled_length_2, need_multiply_2,
654 G3_t1, O1_t2, sasm, true);
655 __ eden_allocate(O0_obj, G1_arr_size, 0, G3_t1, O1_t2, slow_path); // preserves G1_arr_size
656
657 __ initialize_header(O0_obj, G5_klass, G4_length, G3_t1, O1_t2);
658 initialize_array_body(O0_obj, G1_arr_size, G3_t1, O1_t2, sasm);
659 __ verify_oop(O0_obj);
660 __ retl();
661 __ delayed()->nop();
662
663 // generate side path, if any
664 compute_array_size(G1_arr_size, G5_klass, G4_length,
665 have_scaled_length_2, need_multiply_2,
666 G3_t1, O1_t2, sasm, false);
667
668 __ bind(slow_path);
669 }
670
671 if (id == new_type_array_id) {
672 oop_maps = generate_stub_call(sasm, I0, CAST_FROM_FN_PTR(address, new_type_array), G5_klass, G4_length);
673 } else {
674 oop_maps = generate_stub_call(sasm, I0, CAST_FROM_FN_PTR(address, new_object_array), G5_klass, G4_length);
675 }
676 // I0 -> O0: new array
677 }
678 break;
679
680 case new_multi_array_id:
681 { // O0: klass
682 // O1: rank
683 // O2: address of 1st dimension
684 __ set_info("new_multi_array", dont_gc_arguments);
685 oop_maps = generate_stub_call(sasm, I0, CAST_FROM_FN_PTR(address, new_multi_array), I0, I1, I2);
686 // I0 -> O0: new multi array
687 }
|