x86 JNI compiler and unit tests.

Change-Id: I4c2e10328961a2e8e27c90777fe2a93737b21143
diff --git a/src/calling_convention.h b/src/calling_convention.h
new file mode 100644
index 0000000..cf12692
--- /dev/null
+++ b/src/calling_convention.h
@@ -0,0 +1,145 @@
+// Copyright 2011 Google Inc. All Rights Reserved.
+// Author: irogers@google.com (Ian Rogers)
+
+#ifndef ART_SRC_CALLING_CONVENTION_H_
+#define ART_SRC_CALLING_CONVENTION_H_
+
+#include "src/managed_register.h"
+#include "src/object.h"
+#include "src/thread.h"
+
+namespace art {
+
+// Top-level abstraction for different calling conventions
+class CallingConvention {
+ public:
+  CallingConvention* GetCallingConvention(Method* method);
+
+  bool IsReturnAReference() const { return method_->IsReturnAReference(); }
+
+  // Register that holds the incoming method argument
+  ManagedRegister MethodRegister();
+  // Register that holds result of this method
+  ManagedRegister ReturnRegister();
+  // Register reserved for scratch usage during procedure calls
+  ManagedRegister InterproceduralScratchRegister();
+
+  // Iterator interface
+
+  // Place iterator at start of arguments. The displacement is applied to
+  // frame offset methods to account for frames which may be on the stack
+  // below the one being iterated over.
+  void ResetIterator(FrameOffset displacement) {
+    displacement_ = displacement;
+    itr_position_ = 0;
+    itr_longs_and_doubles_ = 0;
+  }
+
+ protected:
+  explicit CallingConvention(Method* method) : displacement_(0),
+                                               method_(method) {}
+  const Method* GetMethod() const { return method_; }
+
+  // position along argument list
+  unsigned int itr_position_;
+  // number of longs and doubles seen along argument list
+  unsigned int itr_longs_and_doubles_;
+  // Space for frames below this on the stack
+  FrameOffset displacement_;
+
+ private:
+  const Method* method_;
+};
+
+// Abstraction for managed code's calling conventions
+class ManagedRuntimeCallingConvention : public CallingConvention {
+ public:
+  explicit ManagedRuntimeCallingConvention(Method* method) :
+                                          CallingConvention(method) {}
+
+  size_t FrameSize();
+
+  // Iterator interface
+  bool HasNext();
+  void Next();
+  bool IsCurrentParamAReference();
+  bool IsCurrentParamInRegister();
+  bool IsCurrentParamOnStack();
+  bool IsCurrentParamPossiblyNull();
+  size_t CurrentParamSizeInBytes();
+  ManagedRegister CurrentParamRegister();
+  FrameOffset CurrentParamStackOffset();
+
+  DISALLOW_COPY_AND_ASSIGN(ManagedRuntimeCallingConvention);
+};
+
+// Abstraction for JNI calling conventions
+// | incoming stack args    | <-- Prior SP
+// | { Spilled registers    |
+// |   & return address }   |
+// | { Saved JNI Env Data } |
+// | { Stack Handle Block   |
+// |   ...                  |
+// |   length/link }        |     (here to prior SP is frame size)
+// | Method*                | <-- Anchor SP written to thread
+// | { Outgoing stack args  |
+// |   ... }                | <-- SP at point of call
+// | Native frame           |
+class JniCallingConvention : public CallingConvention {
+ public:
+  explicit JniCallingConvention(Method* native_method) :
+                      CallingConvention(native_method) {}
+
+  // Size of frame excluding space for outgoing args (its assumed Method* is
+  // always at the bottom of a frame, but this doesn't work for outgoing
+  // native args). Includes alignment.
+  size_t FrameSize();
+  // Size of outgoing arguments, including alignment
+  size_t OutArgSize();
+  // Number of handles in stack handle block
+  size_t HandleCount();
+
+  // Iterator interface
+  bool HasNext();
+  void Next();
+  bool IsCurrentParamAReference();
+  bool IsCurrentParamInRegister();
+  bool IsCurrentParamOnStack();
+  size_t CurrentParamSizeInBytes();
+  ManagedRegister CurrentParamRegister();
+  FrameOffset CurrentParamStackOffset();
+
+  // Iterator interface extension for JNI
+  FrameOffset CurrentParamHandleOffset();
+
+  // Position of stack handle block and interior fields
+  FrameOffset ShbOffset() {
+    return FrameOffset(displacement_.Int32Value() +
+                       kPointerSize);  // above Method*
+  }
+  FrameOffset ShbNumRefsOffset() {
+    return FrameOffset(ShbOffset().Int32Value() +
+                       StackHandleBlock::NumberOfReferencesOffset());
+  }
+  FrameOffset ShbLinkOffset() {
+    return FrameOffset(ShbOffset().Int32Value() +
+                       StackHandleBlock::LinkOffset());
+  }
+
+ private:
+  // Named iterator positions
+  enum IteratorPos {
+    kJniEnv = 0,
+    kObjectOrClass = 1
+  };
+
+  // Number of stack slots for outgoing arguments, above which handles are
+  // located
+  size_t NumberOfOutgoingStackArgs();
+
+  DISALLOW_COPY_AND_ASSIGN(JniCallingConvention);
+};
+
+}  // namespace art
+
+#endif  // ART_SRC_CALLING_CONVENTION_H_