src/cpu/x86/vm/vtableStubs_x86_64.cpp

changeset 8997
f8a45a60bc6b
parent 6680
78bbf4d43a14
child 9041
95a08233f46c
child 9327
f96fcd9e1e1b
     1.1 --- a/src/cpu/x86/vm/vtableStubs_x86_64.cpp	Tue Aug 08 12:02:01 2017 +0100
     1.2 +++ b/src/cpu/x86/vm/vtableStubs_x86_64.cpp	Fri Sep 29 14:30:05 2017 -0400
     1.3 @@ -1,5 +1,5 @@
     1.4  /*
     1.5 - * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.
     1.6 + * Copyright (c) 2003, 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 @@ -27,6 +27,7 @@
    1.11  #include "code/vtableStubs.hpp"
    1.12  #include "interp_masm_x86.hpp"
    1.13  #include "memory/resourceArea.hpp"
    1.14 +#include "oops/compiledICHolder.hpp"
    1.15  #include "oops/instanceKlass.hpp"
    1.16  #include "oops/klassVtable.hpp"
    1.17  #include "runtime/sharedRuntime.hpp"
    1.18 @@ -149,36 +150,50 @@
    1.19  #endif
    1.20  
    1.21    // Entry arguments:
    1.22 -  //  rax: Interface
    1.23 +  //  rax: CompiledICHolder
    1.24    //  j_rarg0: Receiver
    1.25  
    1.26 -  // Free registers (non-args) are rax (interface), rbx
    1.27 -
    1.28 -  // get receiver (need to skip return address on top of stack)
    1.29 -
    1.30 -  assert(VtableStub::receiver_location() == j_rarg0->as_VMReg(), "receiver expected in j_rarg0");
    1.31 -  // get receiver klass (also an implicit null-check)
    1.32 -  address npe_addr = __ pc();
    1.33 -
    1.34    // Most registers are in use; we'll use rax, rbx, r10, r11
    1.35    // (various calling sequences use r[cd]x, r[sd]i, r[89]; stay away from them)
    1.36 -  __ load_klass(r10, j_rarg0);
    1.37 +  const Register recv_klass_reg     = r10;
    1.38 +  const Register holder_klass_reg   = rax; // declaring interface klass (DECC)
    1.39 +  const Register resolved_klass_reg = rbx; // resolved interface klass (REFC)
    1.40 +  const Register temp_reg           = r11;
    1.41 +
    1.42 +  Label L_no_such_interface;
    1.43 +
    1.44 +  const Register icholder_reg = rax;
    1.45 +  __ movptr(resolved_klass_reg, Address(icholder_reg, CompiledICHolder::holder_klass_offset()));
    1.46 +  __ movptr(holder_klass_reg,   Address(icholder_reg, CompiledICHolder::holder_metadata_offset()));
    1.47 +
    1.48 +  // get receiver klass (also an implicit null-check)
    1.49 +  assert(VtableStub::receiver_location() == j_rarg0->as_VMReg(), "receiver expected in j_rarg0");
    1.50 +  address npe_addr = __ pc();
    1.51 +  __ load_klass(recv_klass_reg, j_rarg0);
    1.52 +
    1.53 +  // Receiver subtype check against REFC.
    1.54 +  // Destroys recv_klass_reg value.
    1.55 +  __ lookup_interface_method(// inputs: rec. class, interface
    1.56 +                             recv_klass_reg, resolved_klass_reg, noreg,
    1.57 +                             // outputs:  scan temp. reg1, scan temp. reg2
    1.58 +                             recv_klass_reg, temp_reg,
    1.59 +                             L_no_such_interface,
    1.60 +                             /*return_method=*/false);
    1.61 +
    1.62 +  // Get selected method from declaring class and itable index
    1.63 +  const Register method = rbx;
    1.64 +  __ load_klass(recv_klass_reg, j_rarg0);   // restore recv_klass_reg
    1.65 +  __ lookup_interface_method(// inputs: rec. class, interface, itable index
    1.66 +                       recv_klass_reg, holder_klass_reg, itable_index,
    1.67 +                       // outputs: method, scan temp. reg
    1.68 +                       method, temp_reg,
    1.69 +                       L_no_such_interface);
    1.70  
    1.71    // If we take a trap while this arg is on the stack we will not
    1.72    // be able to walk the stack properly. This is not an issue except
    1.73    // when there are mistakes in this assembly code that could generate
    1.74    // a spurious fault. Ask me how I know...
    1.75  
    1.76 -  const Register method = rbx;
    1.77 -  Label throw_icce;
    1.78 -
    1.79 -  // Get Method* and entrypoint for compiler
    1.80 -  __ lookup_interface_method(// inputs: rec. class, interface, itable index
    1.81 -                             r10, rax, itable_index,
    1.82 -                             // outputs: method, scan temp. reg
    1.83 -                             method, r11,
    1.84 -                             throw_icce);
    1.85 -
    1.86    // method (rbx): Method*
    1.87    // j_rarg0: receiver
    1.88  
    1.89 @@ -199,7 +214,7 @@
    1.90    address ame_addr = __ pc();
    1.91    __ jmp(Address(method, Method::from_compiled_offset()));
    1.92  
    1.93 -  __ bind(throw_icce);
    1.94 +  __ bind(L_no_such_interface);
    1.95    __ jump(RuntimeAddress(StubRoutines::throw_IncompatibleClassChangeError_entry()));
    1.96  
    1.97    __ flush();
    1.98 @@ -226,8 +241,8 @@
    1.99             (UseCompressedClassPointers ?  MacroAssembler::instr_size_for_decode_klass_not_null() : 0);
   1.100    } else {
   1.101      // Itable stub size
   1.102 -    return (DebugVtables ? 512 : 74) + (CountCompiledCalls ? 13 : 0) +
   1.103 -           (UseCompressedClassPointers ?  MacroAssembler::instr_size_for_decode_klass_not_null() : 0);
   1.104 +    return (DebugVtables ? 512 : 140) + (CountCompiledCalls ? 13 : 0) +
   1.105 +           (UseCompressedClassPointers ? 2 * MacroAssembler::instr_size_for_decode_klass_not_null() : 0);
   1.106    }
   1.107    // In order to tune these parameters, run the JVM with VM options
   1.108    // +PrintMiscellaneous and +WizardMode to see information about

mercurial