calling_convention_x86.cc revision 3e6a3bf797e49b7f449256455c7e522e888687d8
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" 22578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom#include "utils.h" 23b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 24b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersnamespace art { 252c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersnamespace x86 { 26b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 272c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers// Calling convention 282c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers 292c8f653c98d658419f464b6147c10e11a664d2e6Ian RogersManagedRegister X86ManagedRuntimeCallingConvention::InterproceduralScratchRegister() { 302c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers return X86ManagedRegister::FromCpuRegister(ECX); 31b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers} 32b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 332c8f653c98d658419f464b6147c10e11a664d2e6Ian RogersManagedRegister X86JniCallingConvention::InterproceduralScratchRegister() { 342c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers return X86ManagedRegister::FromCpuRegister(ECX); 35b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers} 36b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 37dc51b79e65abcdad094ccd5e5a2caf5153433d49Ian RogersManagedRegister X86JniCallingConvention::ReturnScratchRegister() const { 38dc51b79e65abcdad094ccd5e5a2caf5153433d49Ian Rogers return ManagedRegister::NoRegister(); // No free regs, so assembler uses push/pop 39dc51b79e65abcdad094ccd5e5a2caf5153433d49Ian Rogers} 40dc51b79e65abcdad094ccd5e5a2caf5153433d49Ian Rogers 41b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogersstatic ManagedRegister ReturnRegisterForShorty(const char* shorty, bool jni) { 42169c9a7f46776b235d0a37d5e0ff27682deffe06Ian Rogers if (shorty[0] == 'F' || shorty[0] == 'D') { 43b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers if (jni) { 44b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers return X86ManagedRegister::FromX87Register(ST0); 45b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers } else { 46b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers return X86ManagedRegister::FromXmmRegister(XMM0); 47b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers } 48169c9a7f46776b235d0a37d5e0ff27682deffe06Ian Rogers } else if (shorty[0] == 'J') { 492c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers return X86ManagedRegister::FromRegisterPair(EAX_EDX); 50169c9a7f46776b235d0a37d5e0ff27682deffe06Ian Rogers } else if (shorty[0] == 'V') { 5145a76cb99104a222d6a9bd768a084893dcb7cf30Ian Rogers return ManagedRegister::NoRegister(); 52b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } else { 532c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers return X86ManagedRegister::FromCpuRegister(EAX); 54b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 55b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers} 56b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 572c8f653c98d658419f464b6147c10e11a664d2e6Ian RogersManagedRegister X86ManagedRuntimeCallingConvention::ReturnRegister() { 58b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers return ReturnRegisterForShorty(GetShorty(), false); 592c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers} 602c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers 612c8f653c98d658419f464b6147c10e11a664d2e6Ian RogersManagedRegister X86JniCallingConvention::ReturnRegister() { 62b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers return ReturnRegisterForShorty(GetShorty(), true); 632c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers} 642c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers 6500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan RogersManagedRegister X86JniCallingConvention::IntReturnRegister() { 6600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return X86ManagedRegister::FromCpuRegister(EAX); 6700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers} 6800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers 69b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// Managed runtime calling convention 70b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 712c8f653c98d658419f464b6147c10e11a664d2e6Ian RogersManagedRegister X86ManagedRuntimeCallingConvention::MethodRegister() { 7267375acd9fec74cc2054554fe1ed0a7d213e1e47Ian Rogers return X86ManagedRegister::FromCpuRegister(EAX); 732c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers} 742c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers 752c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersbool X86ManagedRuntimeCallingConvention::IsCurrentParamInRegister() { 76b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers return false; // Everything is passed by stack 77b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers} 78b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 792c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersbool X86ManagedRuntimeCallingConvention::IsCurrentParamOnStack() { 80966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell // We assume all parameters are on stack, args coming via registers are spilled as entry_spills. 81966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell return true; 82b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers} 83b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 842c8f653c98d658419f464b6147c10e11a664d2e6Ian RogersManagedRegister X86ManagedRuntimeCallingConvention::CurrentParamRegister() { 85966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell ManagedRegister res = ManagedRegister::NoRegister(); 86966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell if (!IsCurrentParamAFloatOrDouble()) { 87966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell switch (gpr_arg_count_) { 883e6a3bf797e49b7f449256455c7e522e888687d8Mark Mendell case 0: 893e6a3bf797e49b7f449256455c7e522e888687d8Mark Mendell res = X86ManagedRegister::FromCpuRegister(ECX); 903e6a3bf797e49b7f449256455c7e522e888687d8Mark Mendell break; 913e6a3bf797e49b7f449256455c7e522e888687d8Mark Mendell case 1: 923e6a3bf797e49b7f449256455c7e522e888687d8Mark Mendell res = X86ManagedRegister::FromCpuRegister(EDX); 933e6a3bf797e49b7f449256455c7e522e888687d8Mark Mendell break; 943e6a3bf797e49b7f449256455c7e522e888687d8Mark Mendell case 2: 953e6a3bf797e49b7f449256455c7e522e888687d8Mark Mendell // Don't split a long between the last register and the stack. 963e6a3bf797e49b7f449256455c7e522e888687d8Mark Mendell if (IsCurrentParamALong()) { 973e6a3bf797e49b7f449256455c7e522e888687d8Mark Mendell return ManagedRegister::NoRegister(); 983e6a3bf797e49b7f449256455c7e522e888687d8Mark Mendell } 993e6a3bf797e49b7f449256455c7e522e888687d8Mark Mendell res = X86ManagedRegister::FromCpuRegister(EBX); 1003e6a3bf797e49b7f449256455c7e522e888687d8Mark Mendell break; 101966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell } 102966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell } else if (itr_float_and_doubles_ < 4) { 103966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell // First four float parameters are passed via XMM0..XMM3 104966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell res = X86ManagedRegister::FromXmmRegister( 105966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell static_cast<XmmRegister>(XMM0 + itr_float_and_doubles_)); 106966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell } 107966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell return res; 108966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell} 109966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell 110966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P MendellManagedRegister X86ManagedRuntimeCallingConvention::CurrentParamHighLongRegister() { 111966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell ManagedRegister res = ManagedRegister::NoRegister(); 112966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell DCHECK(IsCurrentParamALong()); 113966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell switch (gpr_arg_count_) { 114966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell case 0: res = X86ManagedRegister::FromCpuRegister(EDX); break; 115966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell case 1: res = X86ManagedRegister::FromCpuRegister(EBX); break; 116966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell } 117966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell return res; 118b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers} 119b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 1202c8f653c98d658419f464b6147c10e11a664d2e6Ian RogersFrameOffset X86ManagedRuntimeCallingConvention::CurrentParamStackOffset() { 121cdd1d2d3fee0711b8b11db99f2dfb80113520100Ian Rogers return FrameOffset(displacement_.Int32Value() + // displacement 122790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers kFramePointerSize + // Method* 123790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers (itr_slots_ * kFramePointerSize)); // offset into in args 124b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers} 125b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 126fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkoconst ManagedRegisterEntrySpills& X86ManagedRuntimeCallingConvention::EntrySpills() { 127b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers // We spill the argument registers on X86 to free them up for scratch use, we then assume 128b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers // all arguments are on the stack. 129b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers if (entry_spills_.size() == 0) { 130966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell ResetIterator(FrameOffset(0)); 131966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell while (HasNext()) { 132966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell ManagedRegister in_reg = CurrentParamRegister(); 1333e6a3bf797e49b7f449256455c7e522e888687d8Mark Mendell bool is_long = IsCurrentParamALong(); 134966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell if (!in_reg.IsNoRegister()) { 135966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell int32_t size = IsParamADouble(itr_args_) ? 8 : 4; 136966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell int32_t spill_offset = CurrentParamStackOffset().Uint32Value(); 137966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell ManagedRegisterSpill spill(in_reg, size, spill_offset); 138966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell entry_spills_.push_back(spill); 1393e6a3bf797e49b7f449256455c7e522e888687d8Mark Mendell if (is_long) { 1403e6a3bf797e49b7f449256455c7e522e888687d8Mark Mendell // special case, as we need a second register here. 141966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell in_reg = CurrentParamHighLongRegister(); 1423e6a3bf797e49b7f449256455c7e522e888687d8Mark Mendell DCHECK(!in_reg.IsNoRegister()); 1433e6a3bf797e49b7f449256455c7e522e888687d8Mark Mendell // We have to spill the second half of the long. 1443e6a3bf797e49b7f449256455c7e522e888687d8Mark Mendell ManagedRegisterSpill spill2(in_reg, size, spill_offset + 4); 1453e6a3bf797e49b7f449256455c7e522e888687d8Mark Mendell entry_spills_.push_back(spill2); 146966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell } 147966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell 148966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell // Keep track of the number of GPRs allocated. 149966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell if (!IsCurrentParamAFloatOrDouble()) { 1503e6a3bf797e49b7f449256455c7e522e888687d8Mark Mendell if (is_long) { 1513e6a3bf797e49b7f449256455c7e522e888687d8Mark Mendell // Long was allocated in 2 registers. 1523e6a3bf797e49b7f449256455c7e522e888687d8Mark Mendell gpr_arg_count_ += 2; 1533e6a3bf797e49b7f449256455c7e522e888687d8Mark Mendell } else { 1543e6a3bf797e49b7f449256455c7e522e888687d8Mark Mendell gpr_arg_count_++; 1553e6a3bf797e49b7f449256455c7e522e888687d8Mark Mendell } 156b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers } 1573e6a3bf797e49b7f449256455c7e522e888687d8Mark Mendell } else if (is_long) { 1583e6a3bf797e49b7f449256455c7e522e888687d8Mark Mendell // We need to skip the unused last register, which is empty. 1593e6a3bf797e49b7f449256455c7e522e888687d8Mark Mendell // If we are already out of registers, this is harmless. 1603e6a3bf797e49b7f449256455c7e522e888687d8Mark Mendell gpr_arg_count_ += 2; 161b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers } 162966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell Next(); 163b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers } 164b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers } 165b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers return entry_spills_; 166b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers} 167b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers 168b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// JNI calling convention 169b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 170703f2cd1f4d1eb5ab5c9792ca2de9ffb39378203jeffhaoX86JniCallingConvention::X86JniCallingConvention(bool is_static, bool is_synchronized, 171703f2cd1f4d1eb5ab5c9792ca2de9ffb39378203jeffhao const char* shorty) 172790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers : JniCallingConvention(is_static, is_synchronized, shorty, kFramePointerSize) { 173703f2cd1f4d1eb5ab5c9792ca2de9ffb39378203jeffhao callee_save_regs_.push_back(X86ManagedRegister::FromCpuRegister(EBP)); 174703f2cd1f4d1eb5ab5c9792ca2de9ffb39378203jeffhao callee_save_regs_.push_back(X86ManagedRegister::FromCpuRegister(ESI)); 175703f2cd1f4d1eb5ab5c9792ca2de9ffb39378203jeffhao callee_save_regs_.push_back(X86ManagedRegister::FromCpuRegister(EDI)); 176703f2cd1f4d1eb5ab5c9792ca2de9ffb39378203jeffhao} 177703f2cd1f4d1eb5ab5c9792ca2de9ffb39378203jeffhao 178703f2cd1f4d1eb5ab5c9792ca2de9ffb39378203jeffhaouint32_t X86JniCallingConvention::CoreSpillMask() const { 179703f2cd1f4d1eb5ab5c9792ca2de9ffb39378203jeffhao return 1 << EBP | 1 << ESI | 1 << EDI | 1 << kNumberOfCpuRegisters; 180703f2cd1f4d1eb5ab5c9792ca2de9ffb39378203jeffhao} 181bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers 1822c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogerssize_t X86JniCallingConvention::FrameSize() { 183703f2cd1f4d1eb5ab5c9792ca2de9ffb39378203jeffhao // Method*, return address and callee save area size, local reference segment state 184cf4035a4c41ccfcc3e89a0cee25f5218a11b0705Andreas Gampe size_t frame_data_size = sizeof(StackReference<mirror::ArtMethod>) + 185cf4035a4c41ccfcc3e89a0cee25f5218a11b0705Andreas Gampe (2 + CalleeSaveRegisters().size()) * kFramePointerSize; 186eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier // References plus 2 words for HandleScope header 187cf4035a4c41ccfcc3e89a0cee25f5218a11b0705Andreas Gampe size_t handle_scope_size = HandleScope::SizeOf(kFramePointerSize, ReferenceCount()); 1880d666d8769714dcbc2acc4dd5b06f0deffa6e0a1Ian Rogers // Plus return value spill area size 189eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier return RoundUp(frame_data_size + handle_scope_size + SizeOfReturnValue(), kStackAlignment); 1900d666d8769714dcbc2acc4dd5b06f0deffa6e0a1Ian Rogers} 1910d666d8769714dcbc2acc4dd5b06f0deffa6e0a1Ian Rogers 1922c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogerssize_t X86JniCallingConvention::OutArgSize() { 193790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers return RoundUp(NumberOfOutgoingStackArgs() * kFramePointerSize, kStackAlignment); 1947a99c11d220ec68c208b507570e3a78c2c18a7a1Ian Rogers} 1957a99c11d220ec68c208b507570e3a78c2c18a7a1Ian Rogers 1962c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersbool X86JniCallingConvention::IsCurrentParamInRegister() { 197b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers return false; // Everything is passed by stack. 198b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers} 199b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 2002c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersbool X86JniCallingConvention::IsCurrentParamOnStack() { 201b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers return true; // Everything is passed by stack. 202b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers} 203b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 2042c8f653c98d658419f464b6147c10e11a664d2e6Ian RogersManagedRegister X86JniCallingConvention::CurrentParamRegister() { 205b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers LOG(FATAL) << "Should not reach here"; 206b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers return ManagedRegister::NoRegister(); 207b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers} 208b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 2092c8f653c98d658419f464b6147c10e11a664d2e6Ian RogersFrameOffset X86JniCallingConvention::CurrentParamStackOffset() { 210790a6b7312979513710c366b411ba6791ddf78c2Ian Rogers return FrameOffset(displacement_.Int32Value() - OutArgSize() + (itr_slots_ * kFramePointerSize)); 211b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers} 212b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 2132c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogerssize_t X86JniCallingConvention::NumberOfOutgoingStackArgs() { 214169c9a7f46776b235d0a37d5e0ff27682deffe06Ian Rogers size_t static_args = IsStatic() ? 1 : 0; // count jclass 2157a99c11d220ec68c208b507570e3a78c2c18a7a1Ian Rogers // regular argument parameters and this 216169c9a7f46776b235d0a37d5e0ff27682deffe06Ian Rogers size_t param_args = NumArgs() + NumLongOrDoubleArgs(); 21700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers // count JNIEnv* and return pc (pushed after Method*) 21800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers size_t total_args = static_args + param_args + 2; 21900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return total_args; 220b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers} 221b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 2222c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers} // namespace x86 223b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers} // namespace art 224