Support for exception throwing from JNI.

This change modifies the exception throwing JNI unit test to be
realistic and implements the missing exception throwing pieces on X86.
It also corrects some issues on ARM including methods with arguments
LJII (such as compareAndSwapInt).

Change-Id: I375f6efe2edeebb8007d7aa12c10b49742a8f119
diff --git a/src/assembler_x86.cc b/src/assembler_x86.cc
index 892bf76..e126d88 100644
--- a/src/assembler_x86.cc
+++ b/src/assembler_x86.cc
@@ -1658,8 +1658,10 @@
   // TODO: place reference map on call
 }
 
-void X86Assembler::Call(FrameOffset base, Offset offset, ManagedRegister) {
-  UNIMPLEMENTED(FATAL);
+void X86Assembler::Call(FrameOffset base, Offset offset, ManagedRegister mscratch) {
+  Register scratch = mscratch.AsX86().AsCpuRegister();
+  movl(scratch, Address(ESP, base));
+  call(Address(scratch, offset));
 }
 
 void X86Assembler::Call(ThreadOffset offset, ManagedRegister mscratch) {
@@ -1713,7 +1715,6 @@
   buffer_.EnqueueSlowPath(slow);
   fs()->cmpl(Address::Absolute(Thread::ExceptionOffset()), Immediate(0));
   j(kNotEqual, slow->Entry());
-  Bind(slow->Continuation());
 }
 
 void X86ExceptionSlowPath::Emit(Assembler *sasm) {
@@ -1721,14 +1722,11 @@
 #define __ sp_asm->
   __ Bind(&entry_);
   // NB the return value is dead
-  // Pass top of stack as argument
-  __ pushl(ESP);
-  __ fs()->call(Address::Absolute(Thread::ExceptionEntryPointOffset()));
-  // TODO: this call should never return as it should make a long jump to
-  // the appropriate catch block
-  // Release argument
-  __ addl(ESP, Immediate(kPointerSize));
-  __ jmp(&continuation_);
+  // Pass exception as argument in EAX
+  __ fs()->movl(EAX, Address::Absolute(Thread::ExceptionOffset()));
+  __ fs()->call(Address::Absolute(OFFSETOF_MEMBER(Thread, pDeliverException)));
+  // this call should never return
+  __ int3();
 #undef __
 }