Print this page
rev 1079 : 6829192: JSR 292 needs to support 64-bit x86
Summary: changes for method handles and invokedynamic
Reviewed-by: ?, ?
rev 1080 : [mq]: meth.walker.patch
rev 1081 : imported patch indy-cleanup-6893081.patch

Split Close
Expand all
Collapse all
          --- old/src/cpu/x86/vm/methodHandles_x86.cpp
          +++ new/src/cpu/x86/vm/methodHandles_x86.cpp
↓ open down ↓ 57 lines elided ↑ open up ↑
  58   58  
  59   59    return me;
  60   60  }
  61   61  
  62   62  #ifdef ASSERT
  63   63  static void verify_argslot(MacroAssembler* _masm, Register rax_argslot,
  64   64                             const char* error_message) {
  65   65    // Verify that argslot lies within (rsp, rbp].
  66   66    Label L_ok, L_bad;
  67   67    __ cmpptr(rax_argslot, rbp);
  68      -  __ jcc(Assembler::above, L_bad);
       68 +  __ jccb(Assembler::above, L_bad);
  69   69    __ cmpptr(rsp, rax_argslot);
  70      -  __ jcc(Assembler::below, L_ok);
       70 +  __ jccb(Assembler::below, L_ok);
  71   71    __ bind(L_bad);
  72   72    __ stop(error_message);
  73   73    __ bind(L_ok);
  74   74  }
  75   75  #endif
  76   76  
  77   77  
  78   78  // Code generation
  79   79  address MethodHandles::generate_method_handle_interpreter_entry(MacroAssembler* _masm) {
  80   80    // rbx: methodOop
↓ open down ↓ 48 lines elided ↑ open up ↑
 129  129                                       Register rax_argslot,
 130  130                                       Register rbx_temp, Register rdx_temp) {
 131  131    assert_different_registers(rax_argslot, rbx_temp, rdx_temp,
 132  132                               (!arg_slots.is_register() ? rsp : arg_slots.as_register()));
 133  133  
 134  134  #ifdef ASSERT
 135  135    verify_argslot(_masm, rax_argslot, "insertion point must fall within current frame");
 136  136    if (arg_slots.is_register()) {
 137  137      Label L_ok, L_bad;
 138  138      __ cmpptr(arg_slots.as_register(), (int32_t) NULL_WORD);
 139      -    __ jcc(Assembler::greater, L_bad);
      139 +    __ jccb(Assembler::greater, L_bad);
 140  140      __ testl(arg_slots.as_register(), -stack_move_unit() - 1);
 141      -    __ jcc(Assembler::zero, L_ok);
      141 +    __ jccb(Assembler::zero, L_ok);
 142  142      __ bind(L_bad);
 143  143      __ stop("assert arg_slots <= 0 and clear low bits");
 144  144      __ bind(L_ok);
 145  145    } else {
 146  146      assert(arg_slots.as_constant() <= 0, "");
 147  147      assert(arg_slots.as_constant() % -stack_move_unit() == 0, "");
 148  148    }
 149  149  #endif //ASSERT
 150  150  
 151  151  #ifdef _LP64
↓ open down ↓ 14 lines elided ↑ open up ↑
 166  166    __ mov(rdx_temp, rsp);                        // source pointer for copy
 167  167    __ lea(rsp, Address(rsp, arg_slots, Address::times_ptr));
 168  168    {
 169  169      Label loop;
 170  170      __ bind(loop);
 171  171      // pull one word down each time through the loop
 172  172      __ movptr(rbx_temp, Address(rdx_temp, 0));
 173  173      __ movptr(Address(rdx_temp, arg_slots, Address::times_ptr), rbx_temp);
 174  174      __ addptr(rdx_temp, wordSize);
 175  175      __ cmpptr(rdx_temp, rax_argslot);
 176      -    __ jcc(Assembler::less, loop);
      176 +    __ jccb(Assembler::less, loop);
 177  177    }
 178  178  
 179  179    // Now move the argslot down, to point to the opened-up space.
 180  180    __ lea(rax_argslot, Address(rax_argslot, arg_slots, Address::times_ptr));
 181  181  
 182  182    if (TaggedStackInterpreter && arg_mask != _INSERT_NO_MASK) {
 183  183      // The caller has specified a bitmask of tags to put into the opened space.
 184  184      // This only works when the arg_slots value is an assembly-time constant.
 185  185      int constant_arg_slots = arg_slots.as_constant() / stack_move_unit();
 186  186      int tag_offset = Interpreter::tag_offset_in_bytes() - Interpreter::value_offset_in_bytes();
↓ open down ↓ 17 lines elided ↑ open up ↑
 204  204                                      Register rbx_temp, Register rdx_temp) {
 205  205    assert_different_registers(rax_argslot, rbx_temp, rdx_temp,
 206  206                               (!arg_slots.is_register() ? rsp : arg_slots.as_register()));
 207  207  
 208  208  #ifdef ASSERT
 209  209    {
 210  210      // Verify that [argslot..argslot+size) lies within (rsp, rbp).
 211  211      Label L_ok, L_bad;
 212  212      __ lea(rbx_temp, Address(rax_argslot, arg_slots, Address::times_ptr));
 213  213      __ cmpptr(rbx_temp, rbp);
 214      -    __ jcc(Assembler::above, L_bad);
      214 +    __ jccb(Assembler::above, L_bad);
 215  215      __ cmpptr(rsp, rax_argslot);
 216      -    __ jcc(Assembler::below, L_ok);
      216 +    __ jccb(Assembler::below, L_ok);
 217  217      __ bind(L_bad);
 218  218      __ stop("deleted argument(s) must fall within current frame");
 219  219      __ bind(L_ok);
 220  220    }
 221  221    if (arg_slots.is_register()) {
 222  222      Label L_ok, L_bad;
 223  223      __ cmpptr(arg_slots.as_register(), (int32_t) NULL_WORD);
 224      -    __ jcc(Assembler::less, L_bad);
      224 +    __ jccb(Assembler::less, L_bad);
 225  225      __ testl(arg_slots.as_register(), -stack_move_unit() - 1);
 226      -    __ jcc(Assembler::zero, L_ok);
      226 +    __ jccb(Assembler::zero, L_ok);
 227  227      __ bind(L_bad);
 228  228      __ stop("assert arg_slots >= 0 and clear low bits");
 229  229      __ bind(L_ok);
 230  230    } else {
 231  231      assert(arg_slots.as_constant() >= 0, "");
 232  232      assert(arg_slots.as_constant() % -stack_move_unit() == 0, "");
 233  233    }
 234  234  #endif //ASSERT
 235  235  
 236  236  #ifdef _LP64
↓ open down ↓ 14 lines elided ↑ open up ↑
 251  251    //   rsp += size;
 252  252    __ lea(rdx_temp, Address(rax_argslot, -wordSize)); // source pointer for copy
 253  253    {
 254  254      Label loop;
 255  255      __ bind(loop);
 256  256      // pull one word up each time through the loop
 257  257      __ movptr(rbx_temp, Address(rdx_temp, 0));
 258  258      __ movptr(Address(rdx_temp, arg_slots, Address::times_ptr), rbx_temp);
 259  259      __ addptr(rdx_temp, -wordSize);
 260  260      __ cmpptr(rdx_temp, rsp);
 261      -    __ jcc(Assembler::greaterEqual, loop);
      261 +    __ jccb(Assembler::greaterEqual, loop);
 262  262    }
 263  263  
 264  264    // Now move the argslot up, to point to the just-copied block.
 265  265    __ lea(rsp, Address(rsp, arg_slots, Address::times_ptr));
 266  266    // And adjust the argslot address to point at the deletion point.
 267  267    __ lea(rax_argslot, Address(rax_argslot, arg_slots, Address::times_ptr));
 268  268  }
 269  269  
 270  270  #ifndef PRODUCT
 271  271  extern "C" void print_method_handle(oopDesc* mh);
↓ open down ↓ 105 lines elided ↑ open up ↑
 377  377        if (TaggedStackInterpreter)  __ push(frame::tag_for_basic_type(T_OBJECT));
 378  378        __ push(rcx_fail);
 379  379        if (TaggedStackInterpreter)  __ push(frame::tag_for_basic_type(T_OBJECT));
 380  380        __ push(rax_want);
 381  381  
 382  382        Register rbx_method = rbx_temp;
 383  383        Label no_method;
 384  384        // FIXME: fill in _raise_exception_method with a suitable sun.dyn method
 385  385        __ movptr(rbx_method, ExternalAddress((address) &_raise_exception_method));
 386  386        __ testptr(rbx_method, rbx_method);
 387      -      __ jcc(Assembler::zero, no_method);
      387 +      __ jccb(Assembler::zero, no_method);
 388  388        int jobject_oop_offset = 0;
 389  389        __ movptr(rbx_method, Address(rbx_method, jobject_oop_offset));  // dereference the jobject
 390  390        __ testptr(rbx_method, rbx_method);
 391      -      __ jcc(Assembler::zero, no_method);
      391 +      __ jccb(Assembler::zero, no_method);
 392  392        __ verify_oop(rbx_method);
 393  393        __ push(rdi_pc);          // and restore caller PC
 394  394        __ jmp(rbx_method_fie);
 395  395  
 396  396        // If we get here, the Java runtime did not do its job of creating the exception.
 397  397        // Do something that is at least causes a valid throw from the interpreter.
 398  398        __ bind(no_method);
 399  399        __ pop(rax_want);
 400  400        if (TaggedStackInterpreter)  __ pop(rcx_fail);
 401  401        __ pop(rcx_fail);
↓ open down ↓ 126 lines elided ↑ open up ↑
 528  528        __ lea(rax_argslot, __ argument_address(rax_argslot));
 529  529        insert_arg_slots(_masm, arg_slots * stack_move_unit(), arg_mask,
 530  530                         rax_argslot, rbx_temp, rdx_temp);
 531  531  
 532  532        // store bound argument into the new stack slot:
 533  533        __ movptr(rbx_temp, rcx_bmh_argument);
 534  534        Address prim_value_addr(rbx_temp, java_lang_boxing_object::value_offset_in_bytes(arg_type));
 535  535        if (arg_type == T_OBJECT) {
 536  536          __ movptr(Address(rax_argslot, 0), rbx_temp);
 537  537        } else {
 538      -        __ load_sized_value(rbx_temp, prim_value_addr,
      538 +        __ load_sized_value(rdx_temp, prim_value_addr,
 539  539                              type2aelembytes(arg_type), is_signed_subword_type(arg_type));
 540      -        __ movptr(Address(rax_argslot, 0), rbx_temp);
      540 +        __ movptr(Address(rax_argslot, 0), rdx_temp);
 541  541  #ifndef _LP64
 542  542          if (arg_slots == 2) {
 543      -          __ movl(rbx_temp, prim_value_addr.plus_disp(wordSize));
 544      -          __ movl(Address(rax_argslot, Interpreter::stackElementSize()), rbx_temp);
      543 +          __ movl(rdx_temp, prim_value_addr.plus_disp(wordSize));
      544 +          __ movl(Address(rax_argslot, Interpreter::stackElementSize()), rdx_temp);
 545  545          }
 546  546  #endif //_LP64
 547      -        break;
 548  547        }
 549  548  
 550  549        if (direct_to_method) {
 551  550          Register rbx_method = rbx_temp;
 552  551          __ movptr(rbx_method, rcx_mh_vmtarget);
 553  552          __ verify_oop(rbx_method);
 554  553          __ jmp(rbx_method_fie);
 555  554        } else {
 556  555          __ movptr(rcx_recv, rcx_mh_vmtarget);
 557  556          __ verify_oop(rcx_recv);
↓ open down ↓ 21 lines elided ↑ open up ↑
 579  578        __ movl(rax_argslot, rcx_amh_vmargslot);
 580  579        vmarg = __ argument_address(rax_argslot);
 581  580  
 582  581        // What class are we casting to?
 583  582        __ movptr(rbx_klass, rcx_amh_argument); // this is a Class object!
 584  583        __ movptr(rbx_klass, Address(rbx_klass, java_lang_Class::klass_offset_in_bytes()));
 585  584  
 586  585        Label done;
 587  586        __ movptr(rdx_temp, vmarg);
 588  587        __ testl(rdx_temp, rdx_temp);
 589      -      __ jcc(Assembler::zero, done);          // no cast if null
      588 +      __ jccb(Assembler::zero, done);         // no cast if null
 590  589        __ load_klass(rdx_temp, rdx_temp);
 591  590  
 592  591        // live at this point:
 593  592        // - rbx_klass:  klass required by the target method
 594  593        // - rdx_temp:   argument klass to test
 595  594        // - rcx_recv:   adapter method handle
 596  595        __ check_klass_subtype(rdx_temp, rbx_klass, rax_argslot, done);
 597  596  
 598  597        // If we get here, the type check failed!
 599  598        // Call the wrong_method_type stub, passing the failing argument type in rax.
↓ open down ↓ 70 lines elided ↑ open up ↑
 670  669      {
 671  670        Register rbx_vminfo = rbx_temp;
 672  671        __ movl(rbx_vminfo, rcx_amh_conversion);
 673  672        assert(CONV_VMINFO_SHIFT == 0, "preshifted");
 674  673  
 675  674        // get the new MH:
 676  675        __ movptr(rcx_recv, rcx_mh_vmtarget);
 677  676        // (now we are done with the old MH)
 678  677  
 679  678        // original 32-bit vmdata word must be of this form:
 680      -      //    | MBZ:16 | signBitCount:8 | srcDstTypes:8 | conversionOp:8 |
 681      -      __ xchgl(rcx, rbx_vminfo);                // free rcx for shifts
      679 +      //    | MBZ:6 | signBitCount:8 | srcDstTypes:8 | conversionOp:8 |
      680 +      __ xchgptr(rcx, rbx_vminfo);                // free rcx for shifts
 682  681        __ shll(rdx_temp /*, rcx*/);
 683  682        Label zero_extend, done;
 684  683        __ testl(rcx, CONV_VMINFO_SIGN_FLAG);
 685      -      __ jcc(Assembler::zero, zero_extend);
      684 +      __ jccb(Assembler::zero, zero_extend);
 686  685  
 687  686        // this path is taken for int->byte, int->short
 688  687        __ sarl(rdx_temp /*, rcx*/);
 689      -      __ jmp(done);
      688 +      __ jmpb(done);
 690  689  
 691  690        __ bind(zero_extend);
 692  691        // this is taken for int->char
 693  692        __ shrl(rdx_temp /*, rcx*/);
 694  693  
 695  694        __ bind(done);
 696      -      __ movptr(vmarg, rdx_temp);
 697      -      __ xchgl(rcx, rbx_vminfo);                // restore rcx_recv
      695 +      __ movl(vmarg, rdx_temp);
      696 +      __ xchgptr(rcx, rbx_vminfo);                // restore rcx_recv
 698  697  
 699  698        __ jump_to_method_handle_entry(rcx_recv, rdx_temp);
 700  699      }
 701  700      break;
 702  701  
 703  702    case _adapter_opt_i2l:        // optimized subcase of adapt_prim_to_prim
 704  703    case _adapter_opt_unboxl:     // optimized subcase of adapt_ref_to_prim
 705  704      {
 706  705        // perform an in-place int-to-long or ref-to-long conversion
 707  706        __ movl(rax_argslot, rcx_amh_vmargslot);
↓ open down ↓ 148 lines elided ↑ open up ↑
 856  855          }
 857  856  
 858  857          if (rotate > 0) {
 859  858            // rotate upward
 860  859            __ subptr(rax_argslot, swap_bytes);
 861  860  #ifdef ASSERT
 862  861            {
 863  862              // Verify that argslot > destslot, by at least swap_bytes.
 864  863              Label L_ok;
 865  864              __ cmpptr(rax_argslot, rbx_destslot);
 866      -            __ jcc(Assembler::aboveEqual, L_ok);
      865 +            __ jccb(Assembler::aboveEqual, L_ok);
 867  866              __ stop("source must be above destination (upward rotation)");
 868  867              __ bind(L_ok);
 869  868            }
 870  869  #endif
 871  870            // work argslot down to destslot, copying contiguous data upwards
 872  871            // pseudo-code:
 873  872            //   rax = src_addr - swap_bytes
 874  873            //   rbx = dest_addr
 875  874            //   while (rax >= rbx) *(rax + swap_bytes) = *(rax + 0), rax--;
 876  875            Label loop;
 877  876            __ bind(loop);
 878  877            __ movptr(rdx_temp, Address(rax_argslot, 0));
 879  878            __ movptr(Address(rax_argslot, swap_bytes), rdx_temp);
 880  879            __ addptr(rax_argslot, -wordSize);
 881  880            __ cmpptr(rax_argslot, rbx_destslot);
 882      -          __ jcc(Assembler::aboveEqual, loop);
      881 +          __ jccb(Assembler::aboveEqual, loop);
 883  882          } else {
 884  883            __ addptr(rax_argslot, swap_bytes);
 885  884  #ifdef ASSERT
 886  885            {
 887  886              // Verify that argslot < destslot, by at least swap_bytes.
 888  887              Label L_ok;
 889  888              __ cmpptr(rax_argslot, rbx_destslot);
 890      -            __ jcc(Assembler::belowEqual, L_ok);
      889 +            __ jccb(Assembler::belowEqual, L_ok);
 891  890              __ stop("source must be below destination (downward rotation)");
 892  891              __ bind(L_ok);
 893  892            }
 894  893  #endif
 895  894            // work argslot up to destslot, copying contiguous data downwards
 896  895            // pseudo-code:
 897  896            //   rax = src_addr + swap_bytes
 898  897            //   rbx = dest_addr
 899  898            //   while (rax <= rbx) *(rax - swap_bytes) = *(rax + 0), rax++;
 900  899            Label loop;
 901  900            __ bind(loop);
 902  901            __ movptr(rdx_temp, Address(rax_argslot, 0));
 903  902            __ movptr(Address(rax_argslot, -swap_bytes), rdx_temp);
 904  903            __ addptr(rax_argslot, wordSize);
 905  904            __ cmpptr(rax_argslot, rbx_destslot);
 906      -          __ jcc(Assembler::belowEqual, loop);
      905 +          __ jccb(Assembler::belowEqual, loop);
 907  906          }
 908  907  
 909  908          // pop the original first chunk into the destination slot, now free
 910  909          for (int i = 0; i < swap_bytes; i += wordSize) {
 911  910            __ pop(rdx_temp);
 912  911            __ movptr(Address(rbx_destslot, i), rdx_temp);
 913  912          }
 914  913        }
 915  914  
 916  915        __ movptr(rcx_recv, rcx_mh_vmtarget);
↓ open down ↓ 45 lines elided ↑ open up ↑
 962  961        //   rdx = new_rsp+1
 963  962        //   rax = argslot
 964  963        //   while (rdx < rbx) *rdx++ = *rax++
 965  964        Label loop;
 966  965        __ bind(loop);
 967  966        __ movptr(rdi, Address(rax_argslot, 0));
 968  967        __ movptr(Address(rdx_newarg, 0), rdi);
 969  968        __ addptr(rax_argslot, wordSize);
 970  969        __ addptr(rdx_newarg, wordSize);
 971  970        __ cmpptr(rdx_newarg, rbx_oldarg);
 972      -      __ jcc(Assembler::less, loop);
      971 +      __ jccb(Assembler::less, loop);
 973  972  
 974  973        __ pop(rdi);              // restore temp
 975  974  
 976  975        __ movptr(rcx_recv, rcx_mh_vmtarget);
 977  976        __ jump_to_method_handle_entry(rcx_recv, rdx_temp);
 978  977      }
 979  978      break;
 980  979  
 981  980    case _adapter_drop_args:
 982  981      {
↓ open down ↓ 131 lines elided ↑ open up ↑
1114 1113          __ bind(loop);
1115 1114          __ movptr(rbx_temp, Address(rsi_source, 0));
1116 1115          __ movptr(Address(rax_argslot, 0), rbx_temp);
1117 1116          __ addptr(rsi_source, type2aelembytes(elem_type));
1118 1117          if (TaggedStackInterpreter) {
1119 1118            __ movptr(Address(rax_argslot, tag_offset),
1120 1119                      frame::tag_for_basic_type(elem_type));
1121 1120          }
1122 1121          __ addptr(rax_argslot, Interpreter::stackElementSize());
1123 1122          __ cmpptr(rax_argslot, rdx_argslot_limit);
1124      -        __ jcc(Assembler::less, loop);
     1123 +        __ jccb(Assembler::less, loop);
1125 1124        } else if (length_constant == 0) {
1126 1125          __ bind(skip_array_check);
1127 1126          // nothing to copy
1128 1127        } else {
1129 1128          int elem_offset = elem0_offset;
1130 1129          int slot_offset = 0;
1131 1130          for (int index = 0; index < length_constant; index++) {
1132 1131            __ movptr(rbx_temp, Address(rsi_array, elem_offset));
1133 1132            __ movptr(Address(rax_argslot, slot_offset), rbx_temp);
1134 1133            elem_offset += type2aelembytes(elem_type);
↓ open down ↓ 45 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX