src/cpu/sparc/vm/templateTable_sparc.cpp

changeset 8997
f8a45a60bc6b
parent 8368
32b682649973
child 9041
95a08233f46c
     1.1 --- a/src/cpu/sparc/vm/templateTable_sparc.cpp	Tue Aug 08 12:02:01 2017 +0100
     1.2 +++ b/src/cpu/sparc/vm/templateTable_sparc.cpp	Fri Sep 29 14:30:05 2017 -0400
     1.3 @@ -1,5 +1,5 @@
     1.4  /*
     1.5 - * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
     1.6 + * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
     1.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     1.8   *
     1.9   * This code is free software; you can redistribute it and/or modify it
    1.10 @@ -3165,15 +3165,15 @@
    1.11    assert(byte_no == f1_byte, "use this argument");
    1.12  
    1.13    const Register Rinterface  = G1_scratch;
    1.14 +  const Register Rmethod     = Lscratch;
    1.15    const Register Rret        = G3_scratch;
    1.16 -  const Register Rindex      = Lscratch;
    1.17    const Register O0_recv     = O0;
    1.18    const Register O1_flags    = O1;
    1.19    const Register O2_Klass    = O2;
    1.20    const Register Rscratch    = G4_scratch;
    1.21    assert_different_registers(Rscratch, G5_method);
    1.22  
    1.23 -  prepare_invoke(byte_no, Rinterface, Rret, Rindex, O0_recv, O1_flags);
    1.24 +  prepare_invoke(byte_no, Rinterface, Rret, Rmethod, O0_recv, O1_flags);
    1.25  
    1.26    // get receiver klass
    1.27    __ null_check(O0_recv, oopDesc::klass_offset_in_bytes());
    1.28 @@ -3193,58 +3193,40 @@
    1.29  
    1.30    __ bind(notMethod);
    1.31  
    1.32 +  Register Rtemp = O1_flags;
    1.33 +
    1.34 +  Label L_no_such_interface;
    1.35 +
    1.36 +  // Receiver subtype check against REFC.
    1.37 +  __ lookup_interface_method(// inputs: rec. class, interface, itable index
    1.38 +                             O2_Klass, Rinterface, noreg,
    1.39 +                             // outputs: temp reg1, temp reg2, temp reg3
    1.40 +                             G5_method, Rscratch, Rtemp,
    1.41 +                             L_no_such_interface,
    1.42 +                             /*return_method=*/false);
    1.43 +
    1.44    __ profile_virtual_call(O2_Klass, O4);
    1.45  
    1.46    //
    1.47    // find entry point to call
    1.48    //
    1.49  
    1.50 -  // compute start of first itableOffsetEntry (which is at end of vtable)
    1.51 -  const int base = InstanceKlass::vtable_start_offset() * wordSize;
    1.52 -  Label search;
    1.53 -  Register Rtemp = O1_flags;
    1.54 -
    1.55 -  __ ld(O2_Klass, InstanceKlass::vtable_length_offset() * wordSize, Rtemp);
    1.56 -  if (align_object_offset(1) > 1) {
    1.57 -    __ round_to(Rtemp, align_object_offset(1));
    1.58 -  }
    1.59 -  __ sll(Rtemp, LogBytesPerWord, Rtemp);   // Rscratch *= 4;
    1.60 -  if (Assembler::is_simm13(base)) {
    1.61 -    __ add(Rtemp, base, Rtemp);
    1.62 -  } else {
    1.63 -    __ set(base, Rscratch);
    1.64 -    __ add(Rscratch, Rtemp, Rtemp);
    1.65 -  }
    1.66 -  __ add(O2_Klass, Rtemp, Rscratch);
    1.67 -
    1.68 -  __ bind(search);
    1.69 -
    1.70 -  __ ld_ptr(Rscratch, itableOffsetEntry::interface_offset_in_bytes(), Rtemp);
    1.71 -  {
    1.72 -    Label ok;
    1.73 -
    1.74 -    // Check that entry is non-null.  Null entries are probably a bytecode
    1.75 -    // problem.  If the interface isn't implemented by the receiver class,
    1.76 -    // the VM should throw IncompatibleClassChangeError.  linkResolver checks
    1.77 -    // this too but that's only if the entry isn't already resolved, so we
    1.78 -    // need to check again.
    1.79 -    __ br_notnull_short( Rtemp, Assembler::pt, ok);
    1.80 -    call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::throw_IncompatibleClassChangeError));
    1.81 -    __ should_not_reach_here();
    1.82 -    __ bind(ok);
    1.83 -  }
    1.84 -
    1.85 -  __ cmp(Rinterface, Rtemp);
    1.86 -  __ brx(Assembler::notEqual, true, Assembler::pn, search);
    1.87 -  __ delayed()->add(Rscratch, itableOffsetEntry::size() * wordSize, Rscratch);
    1.88 -
    1.89 -  // entry found and Rscratch points to it
    1.90 -  __ ld(Rscratch, itableOffsetEntry::offset_offset_in_bytes(), Rscratch);
    1.91 -
    1.92 -  assert(itableMethodEntry::method_offset_in_bytes() == 0, "adjust instruction below");
    1.93 -  __ sll(Rindex, exact_log2(itableMethodEntry::size() * wordSize), Rindex);       // Rindex *= 8;
    1.94 -  __ add(Rscratch, Rindex, Rscratch);
    1.95 -  __ ld_ptr(O2_Klass, Rscratch, G5_method);
    1.96 +  // Get declaring interface class from method
    1.97 +  __ ld_ptr(Rmethod, Method::const_offset(), Rinterface);
    1.98 +  __ ld_ptr(Rinterface, ConstMethod::constants_offset(), Rinterface);
    1.99 +  __ ld_ptr(Rinterface, ConstantPool::pool_holder_offset_in_bytes(), Rinterface);
   1.100 +
   1.101 +  // Get itable index from method
   1.102 +  const Register Rindex = G5_method;
   1.103 +  __ ld(Rmethod, Method::itable_index_offset(), Rindex);
   1.104 +  __ sub(Rindex, Method::itable_index_max, Rindex);
   1.105 +  __ neg(Rindex);
   1.106 +
   1.107 +  __ lookup_interface_method(// inputs: rec. class, interface, itable index
   1.108 +                             O2_Klass, Rinterface, Rindex,
   1.109 +                             // outputs: method, scan temp reg, temp reg
   1.110 +                             G5_method, Rscratch, Rtemp,
   1.111 +                             L_no_such_interface);
   1.112  
   1.113    // Check for abstract method error.
   1.114    {
   1.115 @@ -3260,6 +3242,10 @@
   1.116  
   1.117    __ profile_arguments_type(G5_method, Rcall, Gargs, true);
   1.118    __ call_from_interpreter(Rcall, Gargs, Rret);
   1.119 +
   1.120 +  __ bind(L_no_such_interface);
   1.121 +  call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::throw_IncompatibleClassChangeError));
   1.122 +  __ should_not_reach_here();
   1.123  }
   1.124  
   1.125  void TemplateTable::invokehandle(int byte_no) {

mercurial