12faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes/* 22faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * Copyright (C) 2011 The Android Open Source Project 32faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * 42faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * Licensed under the Apache License, Version 2.0 (the "License"); 52faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * you may not use this file except in compliance with the License. 62faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * You may obtain a copy of the License at 72faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * 82faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * http://www.apache.org/licenses/LICENSE-2.0 92faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * 102faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * Unless required by applicable law or agreed to in writing, software 112faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * distributed under the License is distributed on an "AS IS" BASIS, 122faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 132faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * See the License for the specific language governing permissions and 142faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * limitations under the License. 152faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes */ 16b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 172c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers#include "calling_convention_x86.h" 1857b86d47b66322693a070185fadfb43cb9c12eabIan Rogers 1907ed66b5ae659c452cbe1ab20c3dbf1d6f546461Elliott Hughes#include "base/logging.h" 203e0acf673ce1fbb3932d288d7b52a6dc551a920fMathieu Chartier#include "handle_scope-inl.h" 21166db04e259ca51838c311891598664deeed85adIan Rogers#include "utils/x86/managed_register_x86.h" 22b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 23b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersnamespace art { 242c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersnamespace x86 { 25b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 262c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers// Calling convention 272c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers 282c8f653c98d658419f464b6147c10e11a664d2e6Ian RogersManagedRegister X86ManagedRuntimeCallingConvention::InterproceduralScratchRegister() { 292c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers return X86ManagedRegister::FromCpuRegister(ECX); 30b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers} 31b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 322c8f653c98d658419f464b6147c10e11a664d2e6Ian RogersManagedRegister X86JniCallingConvention::InterproceduralScratchRegister() { 332c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers return X86ManagedRegister::FromCpuRegister(ECX); 34b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers} 35b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 36dc51b79e65abcdad094ccd5e5a2caf5153433d49Ian RogersManagedRegister X86JniCallingConvention::ReturnScratchRegister() const { 37dc51b79e65abcdad094ccd5e5a2caf5153433d49Ian Rogers return ManagedRegister::NoRegister(); // No free regs, so assembler uses push/pop 38dc51b79e65abcdad094ccd5e5a2caf5153433d49Ian Rogers} 39dc51b79e65abcdad094ccd5e5a2caf5153433d49Ian Rogers 40b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogersstatic ManagedRegister ReturnRegisterForShorty(const char* shorty, bool jni) { 41169c9a7f46776b235d0a37d5e0ff27682deffe06Ian Rogers if (shorty[0] == 'F' || shorty[0] == 'D') { 42b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers if (jni) { 43b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers return X86ManagedRegister::FromX87Register(ST0); 44b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers } else { 45b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers return X86ManagedRegister::FromXmmRegister(XMM0); 46b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers } 47169c9a7f46776b235d0a37d5e0ff27682deffe06Ian Rogers } else if (shorty[0] == 'J') { 482c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers return X86ManagedRegister::FromRegisterPair(EAX_EDX); 49169c9a7f46776b235d0a37d5e0ff27682deffe06Ian Rogers } else if (shorty[0] == 'V') { 5045a76cb99104a222d6a9bd768a084893dcb7cf30Ian Rogers return ManagedRegister::NoRegister(); 51b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } else { 522c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers return X86ManagedRegister::FromCpuRegister(EAX); 53b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 54b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers} 55b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 562c8f653c98d658419f464b6147c10e11a664d2e6Ian RogersManagedRegister X86ManagedRuntimeCallingConvention::ReturnRegister() { 57b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers return ReturnRegisterForShorty(GetShorty(), false); 582c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers} 592c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers 602c8f653c98d658419f464b6147c10e11a664d2e6Ian RogersManagedRegister X86JniCallingConvention::ReturnRegister() { 61b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers return ReturnRegisterForShorty(GetShorty(), true); 622c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers} 632c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers 6400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan RogersManagedRegister X86JniCallingConvention::IntReturnRegister() { 6500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return X86ManagedRegister::FromCpuRegister(EAX); 6600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers} 6700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers 68b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// Managed runtime calling convention 69b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 702c8f653c98d658419f464b6147c10e11a664d2e6Ian RogersManagedRegister X86ManagedRuntimeCallingConvention::MethodRegister() { 7167375acd9fec74cc2054554fe1ed0a7d213e1e47Ian Rogers return X86ManagedRegister::FromCpuRegister(EAX); 722c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers} 732c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers 742c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersbool X86ManagedRuntimeCallingConvention::IsCurrentParamInRegister() { 75b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers return false; // Everything is passed by stack 76b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers} 77b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 782c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersbool X86ManagedRuntimeCallingConvention::IsCurrentParamOnStack() { 79966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell // We assume all parameters are on stack, args coming via registers are spilled as entry_spills. 80966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell return true; 81b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers} 82b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 832c8f653c98d658419f464b6147c10e11a664d2e6Ian RogersManagedRegister X86ManagedRuntimeCallingConvention::CurrentParamRegister() { 84966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell ManagedRegister res = ManagedRegister::NoRegister(); 85966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell if (!IsCurrentParamAFloatOrDouble()) { 86966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell switch (gpr_arg_count_) { 873e6a3bf797e49b7f449256455c7e522e888687d8Mark Mendell case 0: 883e6a3bf797e49b7f449256455c7e522e888687d8Mark Mendell res = X86ManagedRegister::FromCpuRegister(ECX); 893e6a3bf797e49b7f449256455c7e522e888687d8Mark Mendell break; 903e6a3bf797e49b7f449256455c7e522e888687d8Mark Mendell case 1: 913e6a3bf797e49b7f449256455c7e522e888687d8Mark Mendell res = X86ManagedRegister::FromCpuRegister(EDX); 923e6a3bf797e49b7f449256455c7e522e888687d8Mark Mendell break; 933e6a3bf797e49b7f449256455c7e522e888687d8Mark Mendell case 2: 943e6a3bf797e49b7f449256455c7e522e888687d8Mark Mendell // Don't split a long between the last register and the stack. 953e6a3bf797e49b7f449256455c7e522e888687d8Mark Mendell if (IsCurrentParamALong()) { 963e6a3bf797e49b7f449256455c7e522e888687d8Mark Mendell return ManagedRegister::NoRegister(); 973e6a3bf797e49b7f449256455c7e522e888687d8Mark Mendell } 983e6a3bf797e49b7f449256455c7e522e888687d8Mark Mendell res = X86ManagedRegister::FromCpuRegister(EBX); 993e6a3bf797e49b7f449256455c7e522e888687d8Mark Mendell break; 100966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell } 101966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell } else if (itr_float_and_doubles_ < 4) { 102966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell // First four float parameters are passed via XMM0..XMM3 103966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell res = X86ManagedRegister::FromXmmRegister( 104966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell static_cast<XmmRegister>(XMM0 + itr_float_and_doubles_)); 105966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell } 106966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell return res; 107966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell} 108966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell 109966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P MendellManagedRegister X86ManagedRuntimeCallingConvention::CurrentParamHighLongRegister() { 110966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell ManagedRegister res = ManagedRegister::NoRegister(); 111966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell DCHECK(IsCurrentParamALong()); 112966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell switch (gpr_arg_count_) { 113966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell case 0: res = X86ManagedRegister::FromCpuRegister(EDX); break; 114966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell case 1: res = X86ManagedRegister::FromCpuRegister(EBX); break; 115966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell } 116966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell return res; 117b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers} 118b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 1192c8f653c98d658419f464b6147c10e11a664d2e6Ian RogersFrameOffset X86ManagedRuntimeCallingConvention::CurrentParamStackOffset() { 120cdd1d2d3fee0711b8b11db99f2dfb80113520100Ian Rogers return FrameOffset(displacement_.Int32Value() + // displacement 121790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers kFramePointerSize + // Method* 122790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers (itr_slots_ * kFramePointerSize)); // offset into in args 123b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers} 124b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 125fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkoconst ManagedRegisterEntrySpills& X86ManagedRuntimeCallingConvention::EntrySpills() { 126b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers // We spill the argument registers on X86 to free them up for scratch use, we then assume 127b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers // all arguments are on the stack. 128b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers if (entry_spills_.size() == 0) { 129966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell ResetIterator(FrameOffset(0)); 130966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell while (HasNext()) { 131966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell ManagedRegister in_reg = CurrentParamRegister(); 1323e6a3bf797e49b7f449256455c7e522e888687d8Mark Mendell bool is_long = IsCurrentParamALong(); 133966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell if (!in_reg.IsNoRegister()) { 134966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell int32_t size = IsParamADouble(itr_args_) ? 8 : 4; 135966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell int32_t spill_offset = CurrentParamStackOffset().Uint32Value(); 136966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell ManagedRegisterSpill spill(in_reg, size, spill_offset); 137966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell entry_spills_.push_back(spill); 1383e6a3bf797e49b7f449256455c7e522e888687d8Mark Mendell if (is_long) { 1393e6a3bf797e49b7f449256455c7e522e888687d8Mark Mendell // special case, as we need a second register here. 140966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell in_reg = CurrentParamHighLongRegister(); 1413e6a3bf797e49b7f449256455c7e522e888687d8Mark Mendell DCHECK(!in_reg.IsNoRegister()); 1423e6a3bf797e49b7f449256455c7e522e888687d8Mark Mendell // We have to spill the second half of the long. 1433e6a3bf797e49b7f449256455c7e522e888687d8Mark Mendell ManagedRegisterSpill spill2(in_reg, size, spill_offset + 4); 1443e6a3bf797e49b7f449256455c7e522e888687d8Mark Mendell entry_spills_.push_back(spill2); 145966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell } 146966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell 147966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell // Keep track of the number of GPRs allocated. 148966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell if (!IsCurrentParamAFloatOrDouble()) { 1493e6a3bf797e49b7f449256455c7e522e888687d8Mark Mendell if (is_long) { 1503e6a3bf797e49b7f449256455c7e522e888687d8Mark Mendell // Long was allocated in 2 registers. 1513e6a3bf797e49b7f449256455c7e522e888687d8Mark Mendell gpr_arg_count_ += 2; 1523e6a3bf797e49b7f449256455c7e522e888687d8Mark Mendell } else { 1533e6a3bf797e49b7f449256455c7e522e888687d8Mark Mendell gpr_arg_count_++; 1543e6a3bf797e49b7f449256455c7e522e888687d8Mark Mendell } 155b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers } 1563e6a3bf797e49b7f449256455c7e522e888687d8Mark Mendell } else if (is_long) { 1573e6a3bf797e49b7f449256455c7e522e888687d8Mark Mendell // We need to skip the unused last register, which is empty. 1583e6a3bf797e49b7f449256455c7e522e888687d8Mark Mendell // If we are already out of registers, this is harmless. 1593e6a3bf797e49b7f449256455c7e522e888687d8Mark Mendell gpr_arg_count_ += 2; 160b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers } 161966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell Next(); 162b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers } 163b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers } 164b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers return entry_spills_; 165b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers} 166b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers 167b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// JNI calling convention 168b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 169703f2cd1f4d1eb5ab5c9792ca2de9ffb39378203jeffhaoX86JniCallingConvention::X86JniCallingConvention(bool is_static, bool is_synchronized, 170703f2cd1f4d1eb5ab5c9792ca2de9ffb39378203jeffhao const char* shorty) 171790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers : JniCallingConvention(is_static, is_synchronized, shorty, kFramePointerSize) { 172703f2cd1f4d1eb5ab5c9792ca2de9ffb39378203jeffhao callee_save_regs_.push_back(X86ManagedRegister::FromCpuRegister(EBP)); 173703f2cd1f4d1eb5ab5c9792ca2de9ffb39378203jeffhao callee_save_regs_.push_back(X86ManagedRegister::FromCpuRegister(ESI)); 174703f2cd1f4d1eb5ab5c9792ca2de9ffb39378203jeffhao callee_save_regs_.push_back(X86ManagedRegister::FromCpuRegister(EDI)); 175703f2cd1f4d1eb5ab5c9792ca2de9ffb39378203jeffhao} 176703f2cd1f4d1eb5ab5c9792ca2de9ffb39378203jeffhao 177703f2cd1f4d1eb5ab5c9792ca2de9ffb39378203jeffhaouint32_t X86JniCallingConvention::CoreSpillMask() const { 178703f2cd1f4d1eb5ab5c9792ca2de9ffb39378203jeffhao return 1 << EBP | 1 << ESI | 1 << EDI | 1 << kNumberOfCpuRegisters; 179703f2cd1f4d1eb5ab5c9792ca2de9ffb39378203jeffhao} 180bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers 1812c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogerssize_t X86JniCallingConvention::FrameSize() { 182703f2cd1f4d1eb5ab5c9792ca2de9ffb39378203jeffhao // Method*, return address and callee save area size, local reference segment state 183e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier size_t frame_data_size = kX86PointerSize + 184cf4035a4c41ccfcc3e89a0cee25f5218a11b0705Andreas Gampe (2 + CalleeSaveRegisters().size()) * kFramePointerSize; 185eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier // References plus 2 words for HandleScope header 186cf4035a4c41ccfcc3e89a0cee25f5218a11b0705Andreas Gampe size_t handle_scope_size = HandleScope::SizeOf(kFramePointerSize, ReferenceCount()); 1870d666d8769714dcbc2acc4dd5b06f0deffa6e0a1Ian Rogers // Plus return value spill area size 188eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier return RoundUp(frame_data_size + handle_scope_size + SizeOfReturnValue(), kStackAlignment); 1890d666d8769714dcbc2acc4dd5b06f0deffa6e0a1Ian Rogers} 1900d666d8769714dcbc2acc4dd5b06f0deffa6e0a1Ian Rogers 1912c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogerssize_t X86JniCallingConvention::OutArgSize() { 192790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers return RoundUp(NumberOfOutgoingStackArgs() * kFramePointerSize, kStackAlignment); 1937a99c11d220ec68c208b507570e3a78c2c18a7a1Ian Rogers} 1947a99c11d220ec68c208b507570e3a78c2c18a7a1Ian Rogers 1952c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersbool X86JniCallingConvention::IsCurrentParamInRegister() { 196b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers return false; // Everything is passed by stack. 197b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers} 198b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 1992c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersbool X86JniCallingConvention::IsCurrentParamOnStack() { 200b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers return true; // Everything is passed by stack. 201b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers} 202b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 2032c8f653c98d658419f464b6147c10e11a664d2e6Ian RogersManagedRegister X86JniCallingConvention::CurrentParamRegister() { 204b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers LOG(FATAL) << "Should not reach here"; 205b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers return ManagedRegister::NoRegister(); 206b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers} 207b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 2082c8f653c98d658419f464b6147c10e11a664d2e6Ian RogersFrameOffset X86JniCallingConvention::CurrentParamStackOffset() { 209790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers return FrameOffset(displacement_.Int32Value() - OutArgSize() + (itr_slots_ * kFramePointerSize)); 210b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers} 211b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 2122c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogerssize_t X86JniCallingConvention::NumberOfOutgoingStackArgs() { 213169c9a7f46776b235d0a37d5e0ff27682deffe06Ian Rogers size_t static_args = IsStatic() ? 1 : 0; // count jclass 2147a99c11d220ec68c208b507570e3a78c2c18a7a1Ian Rogers // regular argument parameters and this 215169c9a7f46776b235d0a37d5e0ff27682deffe06Ian Rogers size_t param_args = NumArgs() + NumLongOrDoubleArgs(); 21600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers // count JNIEnv* and return pc (pushed after Method*) 21700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers size_t total_args = static_args + param_args + 2; 21800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return total_args; 219b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers} 220b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 2212c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers} // namespace x86 222b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers} // namespace art 223