calling_convention.h revision df20fe0c097073f75f22d16e72fd3636a31d3ca1
1b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// Copyright 2011 Google Inc. All Rights Reserved. 2b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// Author: irogers@google.com (Ian Rogers) 3b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 4b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers#ifndef ART_SRC_CALLING_CONVENTION_H_ 5b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers#define ART_SRC_CALLING_CONVENTION_H_ 6b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 7b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers#include "src/managed_register.h" 8b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers#include "src/object.h" 9b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers#include "src/thread.h" 10b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 11b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersnamespace art { 12b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 13b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// Top-level abstraction for different calling conventions 14b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersclass CallingConvention { 15b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers public: 16b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers CallingConvention* GetCallingConvention(Method* method); 17b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 18b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers bool IsReturnAReference() const { return method_->IsReturnAReference(); } 19b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 20df20fe0c097073f75f22d16e72fd3636a31d3ca1Ian Rogers size_t SizeOfReturnValue() const { return method_->ReturnSize(); } 21df20fe0c097073f75f22d16e72fd3636a31d3ca1Ian Rogers 22b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers // Register that holds the incoming method argument 23b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers ManagedRegister MethodRegister(); 24b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers // Register that holds result of this method 25b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers ManagedRegister ReturnRegister(); 26b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers // Register reserved for scratch usage during procedure calls 27b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers ManagedRegister InterproceduralScratchRegister(); 28b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 29b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers // Iterator interface 30b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 31b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers // Place iterator at start of arguments. The displacement is applied to 32b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers // frame offset methods to account for frames which may be on the stack 33b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers // below the one being iterated over. 34b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers void ResetIterator(FrameOffset displacement) { 35b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers displacement_ = displacement; 36b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers itr_position_ = 0; 37b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers itr_longs_and_doubles_ = 0; 38b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 39b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 40b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers protected: 41b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers explicit CallingConvention(Method* method) : displacement_(0), 42b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers method_(method) {} 43b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers const Method* GetMethod() const { return method_; } 44b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 45b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers // position along argument list 46b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers unsigned int itr_position_; 47b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers // number of longs and doubles seen along argument list 48b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers unsigned int itr_longs_and_doubles_; 49b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers // Space for frames below this on the stack 50b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers FrameOffset displacement_; 51b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 52b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers private: 53b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers const Method* method_; 54b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers}; 55b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 56b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// Abstraction for managed code's calling conventions 57b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersclass ManagedRuntimeCallingConvention : public CallingConvention { 58b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers public: 59b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers explicit ManagedRuntimeCallingConvention(Method* method) : 60b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers CallingConvention(method) {} 61b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 62b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers size_t FrameSize(); 63b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 64b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers // Iterator interface 65b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers bool HasNext(); 66b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers void Next(); 67b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers bool IsCurrentParamAReference(); 68b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers bool IsCurrentParamInRegister(); 69b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers bool IsCurrentParamOnStack(); 70b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers bool IsCurrentParamPossiblyNull(); 71df20fe0c097073f75f22d16e72fd3636a31d3ca1Ian Rogers size_t CurrentParamSize(); 72b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers ManagedRegister CurrentParamRegister(); 73b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers FrameOffset CurrentParamStackOffset(); 74b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 75b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers DISALLOW_COPY_AND_ASSIGN(ManagedRuntimeCallingConvention); 76b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers}; 77b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 78b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// Abstraction for JNI calling conventions 79b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// | incoming stack args | <-- Prior SP 80b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// | { Spilled registers | 81b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// | & return address } | 82df20fe0c097073f75f22d16e72fd3636a31d3ca1Ian Rogers// | { Return value spill } | (live on return slow paths) 83b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// | { Stack Handle Block | 84b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// | ... | 85df20fe0c097073f75f22d16e72fd3636a31d3ca1Ian Rogers// | num. refs./link } | (here to prior SP is frame size) 86b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// | Method* | <-- Anchor SP written to thread 87b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// | { Outgoing stack args | 88b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// | ... } | <-- SP at point of call 89b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// | Native frame | 90b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersclass JniCallingConvention : public CallingConvention { 91b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers public: 92b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers explicit JniCallingConvention(Method* native_method) : 93b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers CallingConvention(native_method) {} 94b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 95b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers // Size of frame excluding space for outgoing args (its assumed Method* is 96b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers // always at the bottom of a frame, but this doesn't work for outgoing 97b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers // native args). Includes alignment. 98b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers size_t FrameSize(); 99b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers // Size of outgoing arguments, including alignment 100b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers size_t OutArgSize(); 101b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers // Number of handles in stack handle block 102b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers size_t HandleCount(); 103df20fe0c097073f75f22d16e72fd3636a31d3ca1Ian Rogers // Location where the return value of a call can be squirreled if another 104df20fe0c097073f75f22d16e72fd3636a31d3ca1Ian Rogers // call is made following the native call 105df20fe0c097073f75f22d16e72fd3636a31d3ca1Ian Rogers FrameOffset ReturnValueSaveLocation(); 106b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 107b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers // Iterator interface 108b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers bool HasNext(); 109b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers void Next(); 110b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers bool IsCurrentParamAReference(); 111b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers bool IsCurrentParamInRegister(); 112b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers bool IsCurrentParamOnStack(); 113df20fe0c097073f75f22d16e72fd3636a31d3ca1Ian Rogers size_t CurrentParamSize(); 114b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers ManagedRegister CurrentParamRegister(); 115b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers FrameOffset CurrentParamStackOffset(); 116b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 117b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers // Iterator interface extension for JNI 118b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers FrameOffset CurrentParamHandleOffset(); 119b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 120b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers // Position of stack handle block and interior fields 121b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers FrameOffset ShbOffset() { 122b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers return FrameOffset(displacement_.Int32Value() + 123b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers kPointerSize); // above Method* 124b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 125b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers FrameOffset ShbNumRefsOffset() { 126b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers return FrameOffset(ShbOffset().Int32Value() + 127b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers StackHandleBlock::NumberOfReferencesOffset()); 128b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 129b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers FrameOffset ShbLinkOffset() { 130b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers return FrameOffset(ShbOffset().Int32Value() + 131b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers StackHandleBlock::LinkOffset()); 132b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 133b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 134b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers private: 135b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers // Named iterator positions 136b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers enum IteratorPos { 137b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers kJniEnv = 0, 138b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers kObjectOrClass = 1 139b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers }; 140b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 141b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers // Number of stack slots for outgoing arguments, above which handles are 142b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers // located 143b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers size_t NumberOfOutgoingStackArgs(); 144b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 145b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers DISALLOW_COPY_AND_ASSIGN(JniCallingConvention); 146b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers}; 147b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 148b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers} // namespace art 149b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 150b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers#endif // ART_SRC_CALLING_CONVENTION_H_ 151