1%def op_invoke_custom(): 2 EXPORT_PC 3 FETCH w0, 1 // call_site index, first argument of runtime call. 4 b NterpCommonInvokeCustom 5 6%def op_invoke_custom_range(): 7 EXPORT_PC 8 FETCH w0, 1 // call_site index, first argument of runtime call. 9 b NterpCommonInvokeCustomRange 10 11%def invoke_direct_or_super(helper="", range="", is_super=""): 12 EXPORT_PC 13 // Fast-path which gets the method from thread-local cache. 14% fetch_from_thread_cache("x0", miss_label="2f") 151: 16 // Load the first argument (the 'this' pointer). 17 FETCH w1, 2 18 .if !$range 19 and w1, w1, #0xf 20 .endif 21 GET_VREG w1, w1 22 cbz w1, common_errNullObject // bail if null 23 b $helper 242: 25 mov x0, xSELF 26 ldr x1, [sp] 27 mov x2, xPC 28 bl nterp_get_method 29 .if $is_super 30 b 1b 31 .else 32 tbz x0, #0, 1b 33 and x0, x0, #-2 // Remove the extra bit that marks it's a String.<init> method. 34 .if $range 35 b NterpHandleStringInitRange 36 .else 37 b NterpHandleStringInit 38 .endif 39 .endif 40 41%def op_invoke_direct(): 42% invoke_direct_or_super(helper="NterpCommonInvokeInstance", range="0", is_super="0") 43 44%def op_invoke_direct_range(): 45% invoke_direct_or_super(helper="NterpCommonInvokeInstanceRange", range="1", is_super="0") 46 47%def op_invoke_super(): 48% invoke_direct_or_super(helper="NterpCommonInvokeInstance", range="0", is_super="1") 49 50%def op_invoke_super_range(): 51% invoke_direct_or_super(helper="NterpCommonInvokeInstanceRange", range="1", is_super="1") 52 53%def op_invoke_polymorphic(): 54 EXPORT_PC 55 // No need to fetch the target method. 56 // Load the first argument (the 'this' pointer). 57 FETCH w1, 2 58 and w1, w1, #0xf 59 GET_VREG w1, w1 60 cbz w1, common_errNullObject // bail if null 61 b NterpCommonInvokePolymorphic 62 63%def op_invoke_polymorphic_range(): 64 EXPORT_PC 65 // No need to fetch the target method. 66 // Load the first argument (the 'this' pointer). 67 FETCH w1, 2 68 GET_VREG w1, w1 69 cbz w1, common_errNullObject // bail if null 70 b NterpCommonInvokePolymorphicRange 71 72%def invoke_interface(range=""): 73% slow_path = add_slow_path(invoke_interface_slow_path, range) 74 EXPORT_PC 75 // Fast-path which gets the method from thread-local cache. 76% fetch_from_thread_cache("x26", miss_label=slow_path) 77.L${opcode}_resume: 78 // First argument is the 'this' pointer. 79 FETCH w1, 2 80 .if !$range 81 and w1, w1, #0xf 82 .endif 83 GET_VREG w1, w1 84 // Note: if w1 is null, this will be handled by our SIGSEGV handler. 85 ldr w2, [x1, #MIRROR_OBJECT_CLASS_OFFSET] 86 UNPOISON_HEAP_REF w2 87 // Test the first two bits of the fetched ArtMethod: 88 // - If the first bit is set, this is a method on j.l.Object 89 // - If the second bit is set, this is a default method. 90 tst w26, #0x3 91 b.ne 2f 92 ldrh w3, [x26, #ART_METHOD_IMT_INDEX_OFFSET] 931: 94 ldr x2, [x2, #MIRROR_CLASS_IMT_PTR_OFFSET_64] 95 ldr x0, [x2, w3, uxtw #3] 96 .if $range 97 b NterpCommonInvokeInterfaceRange 98 .else 99 b NterpCommonInvokeInterface 100 .endif 1012: 102 tbnz w26, #0, 3f 103 and x26, x26, #-4 104 ldrh w3, [x26, #ART_METHOD_METHOD_INDEX_OFFSET] 105 and w3, w3, #ART_METHOD_IMT_MASK 106 b 1b 1073: 108 lsr w26, w26, #16 109 add w2, w2, #MIRROR_CLASS_VTABLE_OFFSET_64 110 ldr x0, [x2, w26, uxtw #3] 111 .if $range 112 b NterpCommonInvokeInstanceRange 113 .else 114 b NterpCommonInvokeInstance 115 .endif 116 117%def invoke_interface_slow_path(range): 118 mov x0, xSELF 119 ldr x1, [sp] 120 mov x2, xPC 121 bl nterp_get_method 122 mov x26, x0 123 b .L${opcode}_resume 124 125%def op_invoke_interface(): 126% invoke_interface(range="0") 127 128%def op_invoke_interface_range(): 129% invoke_interface(range="1") 130 131%def invoke_static(helper=""): 132 EXPORT_PC 133 // Fast-path which gets the method from thread-local cache. 134% fetch_from_thread_cache("x0", miss_label="1f") 135 b $helper 1361: 137 mov x0, xSELF 138 ldr x1, [sp] 139 mov x2, xPC 140 bl nterp_get_method 141 b $helper 142 143%def op_invoke_static(): 144% invoke_static(helper="NterpCommonInvokeStatic") 145 146%def op_invoke_static_range(): 147% invoke_static(helper="NterpCommonInvokeStaticRange") 148 149%def invoke_virtual(helper="", range=""): 150 EXPORT_PC 151 // Fast-path which gets the method from thread-local cache. 152% fetch_from_thread_cache("x2", miss_label="2f") 1531: 154 FETCH w1, 2 155 .if !$range 156 and w1, w1, #0xf 157 .endif 158 GET_VREG w1, w1 159 // Note: if w1 is null, this will be handled by our SIGSEGV handler. 160 ldr w0, [x1, #MIRROR_OBJECT_CLASS_OFFSET] 161 UNPOISON_HEAP_REF w0 162 add w0, w0, #MIRROR_CLASS_VTABLE_OFFSET_64 163 ldr x0, [x0, w2, uxtw #3] 164 b $helper 1652: 166 mov x0, xSELF 167 ldr x1, [sp] 168 mov x2, xPC 169 bl nterp_get_method 170 mov x2, x0 171 b 1b 172 173%def op_invoke_virtual(): 174% invoke_virtual(helper="NterpCommonInvokeInstance", range="0") 175 176%def op_invoke_virtual_range(): 177% invoke_virtual(helper="NterpCommonInvokeInstanceRange", range="1") 178