Get PORTABLE + SMALL on x86.

Implemented the portable resolution trampoline and
the portable to interpreter bridge.
Also work on integrating SEA_IR in the PORTABLE+SMALL framework.
Refactor some naming and correct indenting.

Change-Id: Ibd97da5e5b6f5148274c9bff368e3654b661ef51
diff --git a/compiler/driver/compiler_driver.cc b/compiler/driver/compiler_driver.cc
index b8727fe..4659f7b 100644
--- a/compiler/driver/compiler_driver.cc
+++ b/compiler/driver/compiler_driver.cc
@@ -2231,13 +2231,18 @@
   } else if ((access_flags & kAccAbstract) != 0) {
   } else {
     bool compile = verifier::MethodVerifier::IsCandidateForCompilation(code_item, access_flags);
+#ifdef ART_SEA_IR_MODE
+    bool use_sea = Runtime::Current()->IsSeaIRMode();
+    use_sea = use_sea && (std::string::npos != PrettyMethod(method_idx, dex_file).find("fibonacci"));
+    if (use_sea) compile = true;
+#endif
+
     if (compile) {
       CompilerFn compiler = compiler_;
 #ifdef ART_SEA_IR_MODE
-      bool use_sea = Runtime::Current()->IsSeaIRMode();
-      use_sea = use_sea && (std::string::npos != PrettyMethod(method_idx, dex_file).find("fibonacci"));
       if (use_sea) {
         compiler = sea_ir_compiler_;
+        LOG(INFO) << "Using SEA IR to compile..." << std::endl;
       }
 #endif
       // NOTE: if compiler declines to compile this method, it will return NULL.
diff --git a/compiler/sea_ir/debug/dot_gen.h b/compiler/sea_ir/debug/dot_gen.h
index 5270582..05d97fa 100644
--- a/compiler/sea_ir/debug/dot_gen.h
+++ b/compiler/sea_ir/debug/dot_gen.h
@@ -20,6 +20,7 @@
 #include "safe_map.h"
 #include "base/stringprintf.h"
 #include "file_output_stream.h"
+#include "os.h"
 #include "sea_ir/ir/sea.h"
 #include "sea_ir/types/type_inference.h"
 
@@ -103,7 +104,7 @@
     LOG(INFO) << "Starting to write SEA string to file.";
     DotGenerationVisitor dgv = DotGenerationVisitor(&options_, types);
     graph->Accept(&dgv);
-    art::File* file = art::OS::OpenFile(filename.c_str(), O_RDWR | O_CREAT | O_TRUNC);
+    art::File* file = art::OS::OpenFileReadWrite(filename.c_str());
     art::FileOutputStream fos(file);
     std::string graph_as_string = dgv.GetResult();
     graph_as_string += "}";
diff --git a/compiler/sea_ir/frontend.cc b/compiler/sea_ir/frontend.cc
index e24d07d..421c3a4 100644
--- a/compiler/sea_ir/frontend.cc
+++ b/compiler/sea_ir/frontend.cc
@@ -16,18 +16,26 @@
 
 #ifdef ART_SEA_IR_MODE
 #include <llvm/Support/Threading.h>
+#include <llvm/Support/raw_ostream.h>
+#include <llvm/Bitcode/ReaderWriter.h>
+
 #include "base/logging.h"
+#include "llvm/llvm_compilation_unit.h"
 #include "dex/portable/mir_to_gbc.h"
 #include "driver/compiler_driver.h"
-#include "leb128.h"
-#include "llvm/llvm_compilation_unit.h"
+#include "verifier/method_verifier.h"
 #include "mirror/object.h"
+#include "utils.h"
+
 #include "runtime.h"
 #include "safe_map.h"
 
 #include "sea_ir/ir/sea.h"
 #include "sea_ir/debug/dot_gen.h"
 #include "sea_ir/types/types.h"
+#include "sea_ir/code_gen/code_gen.h"
+
+
 namespace art {
 
 static CompiledMethod* CompileMethodWithSeaIr(CompilerDriver& compiler,
@@ -44,12 +52,31 @@
   //       and silencing the cpplint.py warning, I just corrected the formatting.
   VLOG(compiler) << "Compiling " << PrettyMethod(method_idx, dex_file) << "...";
   sea_ir::SeaGraph* ir_graph = sea_ir::SeaGraph::GetGraph(dex_file);
-  ir_graph->CompileMethod(code_item, class_def_idx, method_idx, method_access_flags, dex_file);
+  sea_ir::CodeGenData* llvm_data =
+      ir_graph->CompileMethod(code_item, class_def_idx, method_idx, method_access_flags, dex_file);
   sea_ir::DotConversion dc;
   SafeMap<int, const sea_ir::Type*>*  types = ir_graph->ti_->GetTypeMap();
   dc.DumpSea(ir_graph, "/tmp/temp.dot", types);
   CHECK(0 && "No SEA compiled function exists yet.");
-  return NULL;
+
+  MethodReference mref(&dex_file, method_idx);
+
+  // TODO: Passing the LLVM code as string is ugly and inefficient,
+  //       but it is the way portable did it. I kept it for compatibility,
+  //       but actually it should not happen.
+  std::string llvm_code;
+  ::llvm::raw_string_ostream str_os(llvm_code);
+  ::llvm::WriteBitcodeToFile(&llvm_data->module_, str_os);
+
+  std::string symbol = "dex_";
+  symbol += MangleForJni(PrettyMethod(method_idx, dex_file));
+
+  CompiledMethod* compiled_method =  new CompiledMethod(
+                              compiler.GetInstructionSet(),
+                              llvm_code,
+                              *verifier::MethodVerifier::GetDexGcMap(mref),
+                              symbol);
+  return compiled_method;
 }
 
 CompiledMethod* SeaIrCompileOneMethod(CompilerDriver& compiler,
diff --git a/compiler/sea_ir/ir/sea.cc b/compiler/sea_ir/ir/sea.cc
index 08fe0e1..902839d 100644
--- a/compiler/sea_ir/ir/sea.cc
+++ b/compiler/sea_ir/ir/sea.cc
@@ -386,7 +386,7 @@
   scoped_table->CloseScope();
 }
 
-void SeaGraph::GenerateLLVM() {
+CodeGenData* SeaGraph::GenerateLLVM() {
   // Pass: Generate LLVM IR.
   CodeGenPrepassVisitor code_gen_prepass_visitor;
   std::cout << "Generating code..." << std::endl;
@@ -399,9 +399,11 @@
   CodeGenPostpassVisitor code_gen_postpass_visitor(code_gen_visitor.GetData());
   Accept(&code_gen_postpass_visitor);
   code_gen_postpass_visitor.Write(std::string("my_file.llvm"));
+  return code_gen_postpass_visitor.GetData();
 }
 
-void SeaGraph::CompileMethod(const art::DexFile::CodeItem* code_item, uint32_t class_def_idx,
+CodeGenData* SeaGraph::CompileMethod(
+    const art::DexFile::CodeItem* code_item, uint32_t class_def_idx,
     uint32_t method_idx, uint32_t method_access_flags, const art::DexFile& dex_file) {
   // Two passes: Builds the intermediate structure (non-SSA) of the sea-ir for the function.
   BuildMethodSeaGraph(code_item, dex_file, class_def_idx, method_idx, method_access_flags);
@@ -420,7 +422,8 @@
   // Pass: type inference
   ti_->ComputeTypes(this);
   // Pass: Generate LLVM IR.
-  GenerateLLVM();
+  CodeGenData* cgd = GenerateLLVM();
+  return cgd;
 }
 
 void SeaGraph::ComputeDominanceFrontier() {
diff --git a/compiler/sea_ir/ir/sea.h b/compiler/sea_ir/ir/sea.h
index 0b20ed7..df420ed 100644
--- a/compiler/sea_ir/ir/sea.h
+++ b/compiler/sea_ir/ir/sea.h
@@ -37,6 +37,7 @@
 };
 
 class TypeInference;
+class CodeGenData;
 
 class Region;
 class InstructionNode;
@@ -260,7 +261,7 @@
  public:
   static SeaGraph* GetGraph(const art::DexFile&);
 
-  void CompileMethod(const art::DexFile::CodeItem* code_item, uint32_t class_def_idx,
+  CodeGenData* CompileMethod(const art::DexFile::CodeItem* code_item, uint32_t class_def_idx,
       uint32_t method_idx, uint32_t method_access_flags, const art::DexFile& dex_file);
   // Returns all regions corresponding to this SeaGraph.
   std::vector<Region*>* GetRegions() {
@@ -337,7 +338,7 @@
   void RenameAsSSA(Region* node, utils::ScopedHashtable<int, InstructionNode*>* scoped_table);
   // Generate LLVM IR for the method.
   // Precondition: ConvertToSSA().
-  void GenerateLLVM();
+  CodeGenData* GenerateLLVM();
 
   static SeaGraph graph_;
   std::vector<Region*> regions_;
diff --git a/runtime/arch/arm/portable_entrypoints_arm.S b/runtime/arch/arm/portable_entrypoints_arm.S
index f21ae28..073efdc 100644
--- a/runtime/arch/arm/portable_entrypoints_arm.S
+++ b/runtime/arch/arm/portable_entrypoints_arm.S
@@ -114,7 +114,7 @@
     .cfi_rel_offset r10, 28
     .cfi_rel_offset r11, 32
     .cfi_rel_offset lr, 36
-    sub sp, #8                        @ 2 words of space, bottom word will hold Method*
+    sub sp, #8                     @ 2 words of space, bottom word will hold Method*
     .pad #8
     .cfi_adjust_cfa_offset 8
     mov     r2, r9                 @ pass Thread::Current
@@ -156,7 +156,7 @@
     .cfi_rel_offset r10, 28
     .cfi_rel_offset r11, 32
     .cfi_rel_offset lr, 36
-    sub sp, #8                        @ 2 words of space, bottom word will hold Method*
+    sub sp, #8                     @ 2 words of space, bottom word will hold Method*
     .pad #8
     .cfi_adjust_cfa_offset 8
     mov     r1, r9                 @ pass Thread::Current
diff --git a/runtime/arch/x86/portable_entrypoints_x86.S b/runtime/arch/x86/portable_entrypoints_x86.S
index 0313d4b..24fa98b 100644
--- a/runtime/arch/x86/portable_entrypoints_x86.S
+++ b/runtime/arch/x86/portable_entrypoints_x86.S
@@ -68,13 +68,13 @@
 DEFINE_FUNCTION art_portable_proxy_invoke_handler
     // Fake callee save ref and args frame set up, note portable doesn't use callee save frames.
     // TODO: just save the registers that are needed in artPortableProxyInvokeHandler.
-    PUSH edi  // Save callee saves
+    PUSH edi                      // Save callee saves
     PUSH esi
     PUSH ebp
-    PUSH ebx  // Save args
+    PUSH ebx                      // Save args
     PUSH edx
     PUSH ecx
-    PUSH eax   // Align stack, eax will be clobbered by Method*
+    PUSH eax                      // Align stack, eax will be clobbered by Method*
     // Begin argument set up.
     PUSH esp                      // pass SP
     pushl %fs:THREAD_SELF_OFFSET  // pass Thread::Current()
@@ -90,5 +90,35 @@
     ret
 END_FUNCTION art_portable_proxy_invoke_handler
 
-UNIMPLEMENTED art_portable_resolution_trampoline
-UNIMPLEMENTED art_portable_to_interpreter_bridge
+DEFINE_FUNCTION art_portable_resolution_trampoline
+  pushl %ebp
+  movl %esp, %ebp                 // save ESP
+  subl LITERAL(8), %esp           // Align stack
+  movl 8(%ebp), %eax              // Method* called
+  leal 8(%ebp), %edx              // Method** called_addr
+  pushl %edx                      // pass called_addr
+  pushl %fs:THREAD_SELF_OFFSET    // pass thread
+  pushl %ecx                      // pass receiver
+  pushl %eax                      // pass called
+  call SYMBOL(artPortableResolutionTrampoline)
+  leave
+  cmpl LITERAL(0), %eax
+  je resolve_fail
+  jmp * %eax
+resolve_fail:
+  ret
+END_FUNCTION art_portable_resolution_trampoline
+
+DEFINE_FUNCTION art_portable_to_interpreter_bridge
+  pushl %ebp
+  movl %esp, %ebp                 // save ESP
+  subl LITERAL(12), %esp          // Align stack
+  movl 8(%ebp), %eax              // Method* called
+  leal 8(%ebp), %edx              // Method** called_addr
+  pushl %edx                      // pass called_addr
+  pushl %fs:THREAD_SELF_OFFSET    // pass thread
+  pushl %eax                      // pass called
+  call SYMBOL(artPortableToInterpreterBridge)
+  leave
+  ret
+END_FUNCTION art_quick_to_interpreter_bridge
diff --git a/runtime/entrypoints/entrypoint_utils.cc b/runtime/entrypoints/entrypoint_utils.cc
index bf0fffa..52f8c81 100644
--- a/runtime/entrypoints/entrypoint_utils.cc
+++ b/runtime/entrypoints/entrypoint_utils.cc
@@ -23,6 +23,7 @@
 #include "mirror/art_method-inl.h"
 #include "mirror/class-inl.h"
 #include "mirror/object-inl.h"
+#include "object_utils.h"
 #include "mirror/object_array-inl.h"
 #include "mirror/proxy.h"
 #include "reflection.h"
diff --git a/runtime/entrypoints/entrypoint_utils.h b/runtime/entrypoints/entrypoint_utils.h
index 2b73af4..8b58cb3 100644
--- a/runtime/entrypoints/entrypoint_utils.h
+++ b/runtime/entrypoints/entrypoint_utils.h
@@ -16,7 +16,7 @@
 
 #ifndef ART_RUNTIME_ENTRYPOINTS_ENTRYPOINT_UTILS_H_
 #define ART_RUNTIME_ENTRYPOINTS_ENTRYPOINT_UTILS_H_
-
+#include "object_utils.h"
 #include "class_linker.h"
 #include "common_throws.h"
 #include "dex_file.h"
@@ -27,7 +27,7 @@
 #include "mirror/array.h"
 #include "mirror/class-inl.h"
 #include "mirror/throwable.h"
-#include "object_utils.h"
+
 #include "thread.h"
 
 namespace art {
diff --git a/runtime/entrypoints/portable/portable_trampoline_entrypoints.cc b/runtime/entrypoints/portable/portable_trampoline_entrypoints.cc
index e1ce11a..61f7440 100644
--- a/runtime/entrypoints/portable/portable_trampoline_entrypoints.cc
+++ b/runtime/entrypoints/portable/portable_trampoline_entrypoints.cc
@@ -42,8 +42,10 @@
 #define PORTABLE_CALLEE_SAVE_FRAME__REF_AND_ARGS__FRAME_SIZE 64
 #define PORTABLE_STACK_ARG_SKIP 16
 #elif defined(__i386__)
-#define PORTABLE_CALLEE_SAVE_FRAME__REF_AND_ARGS__R1_OFFSET 4
-#define PORTABLE_CALLEE_SAVE_FRAME__REF_AND_ARGS__FRAME_SIZE 32
+// For x86 there are no register arguments and the stack pointer will point directly to the called
+// method argument passed by the caller.
+#define PORTABLE_CALLEE_SAVE_FRAME__REF_AND_ARGS__R1_OFFSET 0
+#define PORTABLE_CALLEE_SAVE_FRAME__REF_AND_ARGS__FRAME_SIZE 0
 #define PORTABLE_STACK_ARG_SKIP 4
 #else
 #error "Unsupported architecture"
diff --git a/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc b/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc
index 392bcc5..535d540 100644
--- a/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc
+++ b/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc
@@ -15,8 +15,10 @@
  */
 
 #include "callee_save_frame.h"
+#include "common_throws.h"
 #include "dex_file-inl.h"
 #include "dex_instruction-inl.h"
+#include "entrypoints/entrypoint_utils.h"
 #include "interpreter/interpreter.h"
 #include "invoke_arg_array_builder.h"
 #include "mirror/art_method-inl.h"
@@ -26,6 +28,8 @@
 #include "object_utils.h"
 #include "runtime.h"
 
+
+
 namespace art {
 
 // Visits the arguments as saved to the stack by a Runtime::kRefAndArgs callee save frame.
@@ -218,10 +222,11 @@
 };
 
 // Visits arguments on the stack placing them into the shadow frame.
-class BuildShadowFrameVisitor : public QuickArgumentVisitor {
+class BuildQuickShadowFrameVisitor : public QuickArgumentVisitor {
  public:
-  BuildShadowFrameVisitor(mirror::ArtMethod** sp, bool is_static, const char* shorty,
-                          uint32_t shorty_len, ShadowFrame& sf, size_t first_arg_reg) :
+  BuildQuickShadowFrameVisitor(mirror::ArtMethod** sp,
+      bool is_static, const char* shorty,
+       uint32_t shorty_len, ShadowFrame& sf, size_t first_arg_reg) :
     QuickArgumentVisitor(sp, is_static, shorty, shorty_len), sf_(sf), cur_reg_(first_arg_reg) {}
 
   virtual void Visit() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
@@ -258,7 +263,7 @@
   ShadowFrame& sf_;
   size_t cur_reg_;
 
-  DISALLOW_COPY_AND_ASSIGN(BuildShadowFrameVisitor);
+  DISALLOW_COPY_AND_ASSIGN(BuildQuickShadowFrameVisitor);
 };
 
 extern "C" uint64_t artQuickToInterpreterBridge(mirror::ArtMethod* method, Thread* self,
@@ -280,7 +285,7 @@
     ShadowFrame* shadow_frame(ShadowFrame::Create(num_regs, NULL,  // No last shadow coming from quick.
                                                   method, 0, memory));
     size_t first_arg_reg = code_item->registers_size_ - code_item->ins_size_;
-    BuildShadowFrameVisitor shadow_frame_builder(sp, mh.IsStatic(), mh.GetShorty(),
+    BuildQuickShadowFrameVisitor shadow_frame_builder(sp, mh.IsStatic(), mh.GetShorty(),
                                                  mh.GetShortyLength(),
                                                  *shadow_frame, first_arg_reg);
     shadow_frame_builder.VisitArguments();