Update V8 to r7427: Initial merge by git

As required by WebKit r82507

Change-Id: I7ae83ef3f689356043b4929255b7c1dd31d8c5df
diff --git a/src/x64/macro-assembler-x64.h b/src/x64/macro-assembler-x64.h
index 7a7f1a2..1ee0fe0 100644
--- a/src/x64/macro-assembler-x64.h
+++ b/src/x64/macro-assembler-x64.h
@@ -48,7 +48,7 @@
 // a spare register). The register isn't callee save, and not used by the
 // function calling convention.
 static const Register kScratchRegister = { 10 };      // r10.
-static const Register kSmiConstantRegister = { 15 };  // r15 (callee save).
+static const Register kSmiConstantRegister = { 12 };  // r12 (callee save).
 static const Register kRootRegister = { 13 };         // r13 (callee save).
 // Value of smi in kSmiConstantRegister.
 static const int kSmiConstantRegisterValue = 1;
@@ -61,7 +61,7 @@
 
 // Forward declaration.
 class JumpTarget;
-class PostCallGenerator;
+class CallWrapper;
 
 struct SmiIndex {
   SmiIndex(Register index_register, ScaleFactor scale)
@@ -76,7 +76,49 @@
  public:
   MacroAssembler(void* buffer, int size);
 
+  // Prevent the use of the RootArray during the lifetime of this
+  // scope object.
+  class NoRootArrayScope BASE_EMBEDDED {
+   public:
+    explicit NoRootArrayScope(MacroAssembler* assembler)
+        : variable_(&assembler->root_array_available_),
+          old_value_(assembler->root_array_available_) {
+      assembler->root_array_available_ = false;
+    }
+    ~NoRootArrayScope() {
+      *variable_ = old_value_;
+    }
+   private:
+    bool* variable_;
+    bool old_value_;
+  };
+
+  // Operand pointing to an external reference.
+  // May emit code to set up the scratch register. The operand is
+  // only guaranteed to be correct as long as the scratch register
+  // isn't changed.
+  // If the operand is used more than once, use a scratch register
+  // that is guaranteed not to be clobbered.
+  Operand ExternalOperand(ExternalReference reference,
+                          Register scratch = kScratchRegister);
+  // Loads and stores the value of an external reference.
+  // Special case code for load and store to take advantage of
+  // load_rax/store_rax if possible/necessary.
+  // For other operations, just use:
+  //   Operand operand = ExternalOperand(extref);
+  //   operation(operand, ..);
+  void Load(Register destination, ExternalReference source);
+  void Store(ExternalReference destination, Register source);
+  // Loads the address of the external reference into the destination
+  // register.
+  void LoadAddress(Register destination, ExternalReference source);
+  // Returns the size of the code generated by LoadAddress.
+  // Used by CallSize(ExternalReference) to find the size of a call.
+  int LoadAddressSize(ExternalReference source);
+
+  // Operations on roots in the root-array.
   void LoadRoot(Register destination, Heap::RootListIndex index);
+  void StoreRoot(Register source, Heap::RootListIndex index);
   // Load a root value where the index (or part of it) is variable.
   // The variable_offset register is added to the fixed_offset value
   // to get the index into the root-array.
@@ -86,7 +128,6 @@
   void CompareRoot(Register with, Heap::RootListIndex index);
   void CompareRoot(const Operand& with, Heap::RootListIndex index);
   void PushRoot(Heap::RootListIndex index);
-  void StoreRoot(Register source, Heap::RootListIndex index);
 
   // ---------------------------------------------------------------------------
   // GC Support
@@ -186,7 +227,8 @@
   void LoadFromSafepointRegisterSlot(Register dst, Register src);
 
   void InitializeRootRegister() {
-    ExternalReference roots_address = ExternalReference::roots_address();
+    ExternalReference roots_address =
+        ExternalReference::roots_address(isolate());
     movq(kRootRegister, roots_address);
     addq(kRootRegister, Immediate(kRootRegisterBias));
   }
@@ -199,32 +241,32 @@
                   const ParameterCount& expected,
                   const ParameterCount& actual,
                   InvokeFlag flag,
-                  PostCallGenerator* post_call_generator = NULL);
+                  CallWrapper* call_wrapper = NULL);
 
   void InvokeCode(Handle<Code> code,
                   const ParameterCount& expected,
                   const ParameterCount& actual,
                   RelocInfo::Mode rmode,
                   InvokeFlag flag,
-                  PostCallGenerator* post_call_generator = NULL);
+                  CallWrapper* call_wrapper = NULL);
 
   // Invoke the JavaScript function in the given register. Changes the
   // current context to the context in the function before invoking.
   void InvokeFunction(Register function,
                       const ParameterCount& actual,
                       InvokeFlag flag,
-                      PostCallGenerator* post_call_generator = NULL);
+                      CallWrapper* call_wrapper = NULL);
 
   void InvokeFunction(JSFunction* function,
                       const ParameterCount& actual,
                       InvokeFlag flag,
-                      PostCallGenerator* post_call_generator = NULL);
+                      CallWrapper* call_wrapper = NULL);
 
   // Invoke specified builtin JavaScript function. Adds an entry to
   // the unresolved list if the name does not resolve.
   void InvokeBuiltin(Builtins::JavaScript id,
                      InvokeFlag flag,
-                     PostCallGenerator* post_call_generator = NULL);
+                     CallWrapper* call_wrapper = NULL);
 
   // Store the function for the given builtin in the target register.
   void GetBuiltinFunction(Register target, Builtins::JavaScript id);
@@ -278,8 +320,9 @@
                                            int power);
 
 
-  // Simple comparison of smis.
-  void SmiCompare(Register dst, Register src);
+  // Simple comparison of smis.  Both sides must be known smis to use these,
+  // otherwise use Cmp.
+  void SmiCompare(Register smi1, Register smi2);
   void SmiCompare(Register dst, Smi* src);
   void SmiCompare(Register dst, const Operand& src);
   void SmiCompare(const Operand& dst, Register src);
@@ -427,6 +470,11 @@
               Register src1,
               Register src2,
               LabelType* on_not_smi_result);
+  template <typename LabelType>
+  void SmiAdd(Register dst,
+              Register src1,
+              const Operand& src2,
+              LabelType* on_not_smi_result);
 
   void SmiAdd(Register dst,
               Register src1,
@@ -547,6 +595,10 @@
   // Converts a positive smi to a negative index.
   SmiIndex SmiToNegativeIndex(Register dst, Register src, int shift);
 
+  // Add the value of a smi in memory to an int32 register.
+  // Sets flags as a normal add.
+  void AddSmiField(Register dst, const Operand& src);
+
   // Basic Smi operations.
   void Move(Register dst, Smi* source) {
     LoadSmiConstant(dst, source);
@@ -609,6 +661,8 @@
   void Move(const Operand& dst, Handle<Object> source);
   void Cmp(Register dst, Handle<Object> source);
   void Cmp(const Operand& dst, Handle<Object> source);
+  void Cmp(Register dst, Smi* src);
+  void Cmp(const Operand& dst, Smi* src);
   void Push(Handle<Object> source);
 
   // Emit code to discard a non-negative number of pointer-sized elements
@@ -626,6 +680,24 @@
   void Call(ExternalReference ext);
   void Call(Handle<Code> code_object, RelocInfo::Mode rmode);
 
+  // The size of the code generated for different call instructions.
+  int CallSize(Address destination, RelocInfo::Mode rmode) {
+    return kCallInstructionLength;
+  }
+  int CallSize(ExternalReference ext);
+  int CallSize(Handle<Code> code_object) {
+    // Code calls use 32-bit relative addressing.
+    return kShortCallInstructionLength;
+  }
+  int CallSize(Register target) {
+    // Opcode: REX_opt FF /2 m64
+    return (target.high_bit() != 0) ? 3 : 2;
+  }
+  int CallSize(const Operand& target) {
+    // Opcode: REX_opt FF /2 m64
+    return (target.requires_rex() ? 2 : 1) + target.operand_size();
+  }
+
   // Emit call to the code we are currently generating.
   void CallSelf() {
     Handle<Code> self(reinterpret_cast<Code**>(CodeObject().location()));
@@ -682,6 +754,7 @@
 
   // Abort execution if argument is not a smi. Used in debug code.
   void AbortIfNotSmi(Register object);
+  void AbortIfNotSmi(const Operand& object);
 
   // Abort execution if argument is a string. Used in debug code.
   void AbortIfNotString(Register object);
@@ -864,7 +937,7 @@
   void StubReturn(int argc);
 
   // Call a runtime routine.
-  void CallRuntime(Runtime::Function* f, int num_arguments);
+  void CallRuntime(const Runtime::Function* f, int num_arguments);
 
   // Call a runtime function and save the value of XMM registers.
   void CallRuntimeSaveDoubles(Runtime::FunctionId id);
@@ -872,7 +945,7 @@
   // Call a runtime function, returning the CodeStub object called.
   // Try to generate the stub code if necessary.  Do not perform a GC
   // but instead return a retry after GC failure.
-  MUST_USE_RESULT MaybeObject* TryCallRuntime(Runtime::Function* f,
+  MUST_USE_RESULT MaybeObject* TryCallRuntime(const Runtime::Function* f,
                                               int num_arguments);
 
   // Convenience function: Same as above, but takes the fid instead.
@@ -921,7 +994,7 @@
 
   // Calls an API function. Allocates HandleScope, extracts
   // returned value from handle and propagates exceptions.
-  // Clobbers r12, r14, rbx and caller-save registers. Restores context.
+  // Clobbers r14, r15, rbx and caller-save registers. Restores context.
   // On return removes stack_space * kPointerSize (GCed).
   MUST_USE_RESULT MaybeObject* TryCallApiFunctionAndReturn(
       ApiFunction* function, int stack_space);
@@ -958,6 +1031,18 @@
 
   Handle<Object> CodeObject() { return code_object_; }
 
+  // Copy length bytes from source to destination.
+  // Uses scratch register internally (if you have a low-eight register
+  // free, do use it, otherwise kScratchRegister will be used).
+  // The min_length is a minimum limit on the value that length will have.
+  // The algorithm has some special cases that might be omitted if the string
+  // is known to always be long.
+  void CopyBytes(Register destination,
+                 Register source,
+                 Register length,
+                 int min_length = 0,
+                 Register scratch = kScratchRegister);
+
 
   // ---------------------------------------------------------------------------
   // StatsCounter support
@@ -993,12 +1078,13 @@
 
  private:
   // Order general registers are pushed by Pushad.
-  // rax, rcx, rdx, rbx, rsi, rdi, r8, r9, r11, r12, r14.
+  // rax, rcx, rdx, rbx, rsi, rdi, r8, r9, r11, r14, r15.
   static int kSafepointPushRegisterIndices[Register::kNumRegisters];
   static const int kNumSafepointSavedRegisters = 11;
 
   bool generating_stub_;
   bool allow_stub_calls_;
+  bool root_array_available_;
 
   // Returns a register holding the smi value. The register MUST NOT be
   // modified. It may be the "smi 1 constant" register.
@@ -1018,7 +1104,7 @@
                       Register code_register,
                       LabelType* done,
                       InvokeFlag flag,
-                      PostCallGenerator* post_call_generator);
+                      CallWrapper* call_wrapper);
 
   // Activation support.
   void EnterFrame(StackFrame::Type type);
@@ -1084,13 +1170,17 @@
 
 
 // Helper class for generating code or data associated with the code
-// right after a call instruction. As an example this can be used to
+// right before or after a call instruction. As an example this can be used to
 // generate safepoint data after calls for crankshaft.
-class PostCallGenerator {
+class CallWrapper {
  public:
-  PostCallGenerator() { }
-  virtual ~PostCallGenerator() { }
-  virtual void Generate() = 0;
+  CallWrapper() { }
+  virtual ~CallWrapper() { }
+  // Called just before emitting a call. Argument is the size of the generated
+  // call code.
+  virtual void BeforeCall(int call_size) = 0;
+  // Called just after emitting a call, i.e., at the return site for the call.
+  virtual void AfterCall() = 0;
 };
 
 
@@ -1204,6 +1294,26 @@
 
 
 template <typename LabelType>
+void MacroAssembler::SmiAdd(Register dst,
+                            Register src1,
+                            const Operand& src2,
+                            LabelType* on_not_smi_result) {
+  ASSERT_NOT_NULL(on_not_smi_result);
+  if (dst.is(src1)) {
+    movq(kScratchRegister, src1);
+    addq(kScratchRegister, src2);
+    j(overflow, on_not_smi_result);
+    movq(dst, kScratchRegister);
+  } else {
+    ASSERT(!src2.AddressUsesRegister(dst));
+    movq(dst, src1);
+    addq(dst, src2);
+    j(overflow, on_not_smi_result);
+  }
+}
+
+
+template <typename LabelType>
 void MacroAssembler::SmiSub(Register dst,
                             Register src1,
                             Register src2,
@@ -1769,26 +1879,26 @@
     // case the size of the new space is different between the snapshot maker
     // and the running system.
     if (scratch.is(object)) {
-      movq(kScratchRegister, ExternalReference::new_space_mask());
+      movq(kScratchRegister, ExternalReference::new_space_mask(isolate()));
       and_(scratch, kScratchRegister);
     } else {
-      movq(scratch, ExternalReference::new_space_mask());
+      movq(scratch, ExternalReference::new_space_mask(isolate()));
       and_(scratch, object);
     }
-    movq(kScratchRegister, ExternalReference::new_space_start());
+    movq(kScratchRegister, ExternalReference::new_space_start(isolate()));
     cmpq(scratch, kScratchRegister);
     j(cc, branch);
   } else {
-    ASSERT(is_int32(static_cast<int64_t>(Heap::NewSpaceMask())));
+    ASSERT(is_int32(static_cast<int64_t>(HEAP->NewSpaceMask())));
     intptr_t new_space_start =
-        reinterpret_cast<intptr_t>(Heap::NewSpaceStart());
+        reinterpret_cast<intptr_t>(HEAP->NewSpaceStart());
     movq(kScratchRegister, -new_space_start, RelocInfo::NONE);
     if (scratch.is(object)) {
       addq(scratch, kScratchRegister);
     } else {
       lea(scratch, Operand(object, kScratchRegister, times_1, 0));
     }
-    and_(scratch, Immediate(static_cast<int32_t>(Heap::NewSpaceMask())));
+    and_(scratch, Immediate(static_cast<int32_t>(HEAP->NewSpaceMask())));
     j(cc, branch);
   }
 }
@@ -1801,7 +1911,7 @@
                                     Register code_register,
                                     LabelType* done,
                                     InvokeFlag flag,
-                                    PostCallGenerator* post_call_generator) {
+                                    CallWrapper* call_wrapper) {
   bool definitely_matches = false;
   NearLabel invoke;
   if (expected.is_immediate()) {
@@ -1841,8 +1951,7 @@
   }
 
   if (!definitely_matches) {
-    Handle<Code> adaptor =
-        Handle<Code>(Builtins::builtin(Builtins::ArgumentsAdaptorTrampoline));
+    Handle<Code> adaptor = isolate()->builtins()->ArgumentsAdaptorTrampoline();
     if (!code_constant.is_null()) {
       movq(rdx, code_constant, RelocInfo::EMBEDDED_OBJECT);
       addq(rdx, Immediate(Code::kHeaderSize - kHeapObjectTag));
@@ -1851,8 +1960,9 @@
     }
 
     if (flag == CALL_FUNCTION) {
+      if (call_wrapper != NULL) call_wrapper->BeforeCall(CallSize(adaptor));
       Call(adaptor, RelocInfo::CODE_TARGET);
-      if (post_call_generator != NULL) post_call_generator->Generate();
+      if (call_wrapper != NULL) call_wrapper->AfterCall();
       jmp(done);
     } else {
       Jump(adaptor, RelocInfo::CODE_TARGET);