Out-of-line constant pool on Arm: Stage 1 - Free up r7 for use as constant pool point...
authorulan@chromium.org <ulan@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Mon, 23 Sep 2013 15:01:33 +0000 (15:01 +0000)
committerulan@chromium.org <ulan@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Mon, 23 Sep 2013 15:01:33 +0000 (15:01 +0000)
First stage of implementing an out-of-line constant pool on Arm.  This CL
frees up register r7 for use as a constant pool pointer in later stages.

BUG=
R=ulan@chromium.org

Review URL: https://chromiumcodereview.appspot.com/21063002

Patch from Ross McIlroy <rmcilroy@chromium.org>.

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@16898 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

14 files changed:
src/arm/assembler-arm.h
src/arm/builtins-arm.cc
src/arm/code-stubs-arm.cc
src/arm/code-stubs-arm.h
src/arm/codegen-arm.cc
src/arm/deoptimizer-arm.cc
src/arm/frames-arm.h
src/arm/full-codegen-arm.cc
src/arm/ic-arm.cc
src/arm/lithium-codegen-arm.cc
src/arm/macro-assembler-arm.cc
src/arm/macro-assembler-arm.h
src/arm/stub-cache-arm.cc
src/flag-definitions.h

index 13990219dd9437fc77c044eb672a90c8a925b516..d7b8f02504cd082ebbfcdcc23fb67c4c5e6f1299 100644 (file)
@@ -118,7 +118,8 @@ class CpuFeatures : public AllStatic {
 // Core register
 struct Register {
   static const int kNumRegisters = 16;
-  static const int kMaxNumAllocatableRegisters = 8;
+  static const int kMaxNumAllocatableRegisters =
+      FLAG_enable_ool_constant_pool ? 7 : 8;
   static const int kSizeInBytes = 4;
 
   inline static int NumAllocatableRegisters();
@@ -201,6 +202,7 @@ const Register r3  = { kRegister_r3_Code };
 const Register r4  = { kRegister_r4_Code };
 const Register r5  = { kRegister_r5_Code };
 const Register r6  = { kRegister_r6_Code };
+// Used as constant pool pointer register if FLAGS_enable_ool_constant_pool.
 const Register r7  = { kRegister_r7_Code };
 // Used as context register.
 const Register r8  = { kRegister_r8_Code };
index ec1b227565795e02363d5a63114747cdb31c9ef9..554adb3f0db71812ddfcc7eded3d40a99f4f52b1 100644 (file)
@@ -445,9 +445,8 @@ static void Generate_JSConstructStubHelper(MacroAssembler* masm,
       // r3: object size (in words)
       // r4: JSObject (not tagged)
       // r5: First in-object property of JSObject (not tagged)
-      __ add(r6, r4, Operand(r3, LSL, kPointerSizeLog2));  // End of object.
       ASSERT_EQ(3 * kPointerSize, JSObject::kHeaderSize);
-      __ LoadRoot(r7, Heap::kUndefinedValueRootIndex);
+      __ LoadRoot(r6, Heap::kUndefinedValueRootIndex);
       if (count_constructions) {
         __ ldr(r0, FieldMemOperand(r2, Map::kInstanceSizesOffset));
         __ Ubfx(r0, r0, Map::kPreAllocatedPropertyFieldsByte * kBitsPerByte,
@@ -455,14 +454,16 @@ static void Generate_JSConstructStubHelper(MacroAssembler* masm,
         __ add(r0, r5, Operand(r0, LSL, kPointerSizeLog2));
         // r0: offset of first field after pre-allocated fields
         if (FLAG_debug_code) {
-          __ cmp(r0, r6);
+          __ add(ip, r4, Operand(r3, LSL, kPointerSizeLog2));  // End of object.
+          __ cmp(r0, ip);
           __ Assert(le, kUnexpectedNumberOfPreAllocatedPropertyFields);
         }
-        __ InitializeFieldsWithFiller(r5, r0, r7);
+        __ InitializeFieldsWithFiller(r5, r0, r6);
         // To allow for truncation.
-        __ LoadRoot(r7, Heap::kOnePointerFillerMapRootIndex);
+        __ LoadRoot(r6, Heap::kOnePointerFillerMapRootIndex);
       }
-      __ InitializeFieldsWithFiller(r5, r6, r7);
+      __ add(r0, r4, Operand(r3, LSL, kPointerSizeLog2));  // End of object.
+      __ InitializeFieldsWithFiller(r5, r0, r6);
 
       // Add the object tag to make the JSObject real, so that we can continue
       // and jump into the continuation code at any time from now on. Any
@@ -527,16 +528,10 @@ static void Generate_JSConstructStubHelper(MacroAssembler* masm,
       __ add(r6, r2, Operand(r3, LSL, kPointerSizeLog2));  // End of object.
       ASSERT_EQ(2 * kPointerSize, FixedArray::kHeaderSize);
       { Label loop, entry;
-        if (count_constructions) {
-          __ LoadRoot(r7, Heap::kUndefinedValueRootIndex);
-        } else if (FLAG_debug_code) {
-          __ LoadRoot(r8, Heap::kUndefinedValueRootIndex);
-          __ cmp(r7, r8);
-          __ Assert(eq, kUndefinedValueNotLoaded);
-        }
+        __ LoadRoot(r0, Heap::kUndefinedValueRootIndex);
         __ b(&entry);
         __ bind(&loop);
-        __ str(r7, MemOperand(r2, kPointerSize, PostIndex));
+        __ str(r0, MemOperand(r2, kPointerSize, PostIndex));
         __ bind(&entry);
         __ cmp(r2, r6);
         __ b(lt, &loop);
@@ -700,7 +695,7 @@ static void Generate_JSEntryTrampolineHelper(MacroAssembler* masm,
   // r2: receiver
   // r3: argc
   // r4: argv
-  // r5-r7, cp may be clobbered
+  // r5-r6, r7 (if not FLAG_enable_ool_constant_pool) and cp may be clobbered
   ProfileEntryHookStub::MaybeCallEntryHook(masm);
 
   // Clear the context before we push it when entering the internal frame.
@@ -740,7 +735,9 @@ static void Generate_JSEntryTrampolineHelper(MacroAssembler* masm,
     __ LoadRoot(r4, Heap::kUndefinedValueRootIndex);
     __ mov(r5, Operand(r4));
     __ mov(r6, Operand(r4));
-    __ mov(r7, Operand(r4));
+    if (!FLAG_enable_ool_constant_pool) {
+      __ mov(r7, Operand(r4));
+    }
     if (kR9Available == 1) {
       __ mov(r9, Operand(r4));
     }
index 0335607754a984cf82795698df0d99aa950cc5ae..faad2787cb3d986ac892e07a0f02a5e8fbd23ed0 100644 (file)
@@ -825,8 +825,7 @@ static void EmitSmiNonsmiComparison(MacroAssembler* masm,
   // Convert lhs to a double in d7.
   __ SmiToDouble(d7, lhs);
   // Load the double from rhs, tagged HeapNumber r0, to d6.
-  __ sub(r7, rhs, Operand(kHeapObjectTag));
-  __ vldr(d6, r7, HeapNumber::kValueOffset);
+  __ vldr(d6, rhs, HeapNumber::kValueOffset - kHeapObjectTag);
 
   // We now have both loaded as doubles but we can skip the lhs nan check
   // since it's a smi.
@@ -851,8 +850,7 @@ static void EmitSmiNonsmiComparison(MacroAssembler* masm,
 
   // Rhs is a smi, lhs is a heap number.
   // Load the double from lhs, tagged HeapNumber r1, to d7.
-  __ sub(r7, lhs, Operand(kHeapObjectTag));
-  __ vldr(d7, r7, HeapNumber::kValueOffset);
+  __ vldr(d7, lhs, HeapNumber::kValueOffset - kHeapObjectTag);
   // Convert rhs to a double in d6              .
   __ SmiToDouble(d6, rhs);
   // Fall through to both_loaded_as_doubles.
@@ -920,10 +918,8 @@ static void EmitCheckForTwoHeapNumbers(MacroAssembler* masm,
 
   // Both are heap numbers.  Load them up then jump to the code we have
   // for that.
-  __ sub(r7, rhs, Operand(kHeapObjectTag));
-  __ vldr(d6, r7, HeapNumber::kValueOffset);
-  __ sub(r7, lhs, Operand(kHeapObjectTag));
-  __ vldr(d7, r7, HeapNumber::kValueOffset);
+  __ vldr(d6, rhs, HeapNumber::kValueOffset - kHeapObjectTag);
+  __ vldr(d7, lhs, HeapNumber::kValueOffset - kHeapObjectTag);
   __ jmp(both_loaded_as_doubles);
 }
 
@@ -1267,13 +1263,14 @@ void BinaryOpStub::GenerateTypeTransitionWithSavedArgs(
 
 
 void BinaryOpStub_GenerateSmiSmiOperation(MacroAssembler* masm,
-                                          Token::Value op) {
+                                          Token::Value op,
+                                          Register scratch1,
+                                          Register scratch2) {
   Register left = r1;
   Register right = r0;
-  Register scratch1 = r7;
-  Register scratch2 = r9;
 
   ASSERT(right.is(r0));
+  ASSERT(!AreAliased(left, right, scratch1, scratch2, ip));
   STATIC_ASSERT(kSmiTag == 0);
 
   Label not_smi_result;
@@ -1488,11 +1485,15 @@ void BinaryOpStub_GenerateFPOperation(MacroAssembler* masm,
                                       Label* gc_required,
                                       Label* miss,
                                       Token::Value op,
-                                      OverwriteMode mode) {
+                                      OverwriteMode mode,
+                                      Register scratch1,
+                                      Register scratch2,
+                                      Register scratch3,
+                                      Register scratch4) {
   Register left = r1;
   Register right = r0;
-  Register scratch1 = r6;
-  Register scratch2 = r7;
+  Register result = scratch3;
+  ASSERT(!AreAliased(left, right, scratch1, scratch2, scratch3, scratch4));
 
   ASSERT(smi_operands || (not_numbers != NULL));
   if (smi_operands) {
@@ -1506,7 +1507,7 @@ void BinaryOpStub_GenerateFPOperation(MacroAssembler* masm,
     __ JumpIfNotSmi(right, miss);
   }
 
-  Register heap_number_map = r9;
+  Register heap_number_map = scratch4;
   __ LoadRoot(heap_number_map, Heap::kHeapNumberMapRootIndex);
 
   switch (op) {
@@ -1516,7 +1517,6 @@ void BinaryOpStub_GenerateFPOperation(MacroAssembler* masm,
     case Token::DIV:
     case Token::MOD: {
       // Allocate new heap number for result.
-      Register result = r5;
       BinaryOpStub_GenerateHeapResultAllocation(
           masm, result, heap_number_map, scratch1, scratch2, gc_required, mode);
 
@@ -1635,7 +1635,6 @@ void BinaryOpStub_GenerateFPOperation(MacroAssembler* masm,
 
       // Allocate new heap number for result.
       __ bind(&result_not_a_smi);
-      Register result = r5;
       if (smi_operands) {
         __ AllocateHeapNumber(
             result, scratch1, scratch2, heap_number_map, gc_required);
@@ -1646,11 +1645,11 @@ void BinaryOpStub_GenerateFPOperation(MacroAssembler* masm,
       }
 
       // r2: Answer as signed int32.
-      // r5: Heap number to write answer into.
+      // result: Heap number to write answer into.
 
       // Nothing can go wrong now, so move the heap number to r0, which is the
       // result.
-      __ mov(r0, Operand(r5));
+      __ mov(r0, Operand(result));
 
       // Convert the int32 in r2 to the heap number in r0. r3 is corrupted. As
       // mentioned above SHR needs to always produce a positive result.
@@ -1681,26 +1680,31 @@ void BinaryOpStub_GenerateSmiCode(
     Label* gc_required,
     Token::Value op,
     BinaryOpStub::SmiCodeGenerateHeapNumberResults allow_heapnumber_results,
-    OverwriteMode mode) {
+    OverwriteMode mode,
+    Register scratch1,
+    Register scratch2,
+    Register scratch3,
+    Register scratch4) {
   Label not_smis;
 
   Register left = r1;
   Register right = r0;
-  Register scratch1 = r7;
+  ASSERT(!AreAliased(left, right, scratch1, scratch2, scratch3, scratch4));
 
   // Perform combined smi check on both operands.
   __ orr(scratch1, left, Operand(right));
   __ JumpIfNotSmi(scratch1, &not_smis);
 
   // If the smi-smi operation results in a smi return is generated.
-  BinaryOpStub_GenerateSmiSmiOperation(masm, op);
+  BinaryOpStub_GenerateSmiSmiOperation(masm, op, scratch1, scratch2);
 
   // If heap number results are possible generate the result in an allocated
   // heap number.
   if (allow_heapnumber_results == BinaryOpStub::ALLOW_HEAPNUMBER_RESULTS) {
     BinaryOpStub_GenerateFPOperation(
         masm, BinaryOpIC::UNINITIALIZED, BinaryOpIC::UNINITIALIZED, true,
-        use_runtime, gc_required, &not_smis, op, mode);
+        use_runtime, gc_required, &not_smis, op, mode, scratch2, scratch3,
+        scratch1, scratch4);
   }
   __ bind(&not_smis);
 }
@@ -1719,14 +1723,13 @@ void BinaryOpStub::GenerateSmiStub(MacroAssembler* masm) {
   if (result_type_ == BinaryOpIC::UNINITIALIZED ||
       result_type_ == BinaryOpIC::SMI) {
     // Only allow smi results.
-    BinaryOpStub_GenerateSmiCode(
-        masm, &call_runtime, NULL, op_, NO_HEAPNUMBER_RESULTS, mode_);
+    BinaryOpStub_GenerateSmiCode(masm, &call_runtime, NULL, op_,
+        NO_HEAPNUMBER_RESULTS, mode_, r5, r6, r4, r9);
   } else {
     // Allow heap number result and don't make a transition if a heap number
     // cannot be allocated.
-    BinaryOpStub_GenerateSmiCode(
-        masm, &call_runtime, &call_runtime, op_, ALLOW_HEAPNUMBER_RESULTS,
-        mode_);
+    BinaryOpStub_GenerateSmiCode(masm, &call_runtime, &call_runtime, op_,
+      ALLOW_HEAPNUMBER_RESULTS, mode_, r5, r6, r4, r9);
   }
 
   // Code falls through if the result is not returned as either a smi or heap
@@ -1780,8 +1783,9 @@ void BinaryOpStub::GenerateInt32Stub(MacroAssembler* masm) {
 
   Register left = r1;
   Register right = r0;
-  Register scratch1 = r7;
+  Register scratch1 = r4;
   Register scratch2 = r9;
+  Register scratch3 = r5;
   LowDwVfpRegister double_scratch = d0;
 
   Register heap_number_result = no_reg;
@@ -1798,7 +1802,7 @@ void BinaryOpStub::GenerateInt32Stub(MacroAssembler* masm) {
   Label skip;
   __ orr(scratch1, left, right);
   __ JumpIfNotSmi(scratch1, &skip);
-  BinaryOpStub_GenerateSmiSmiOperation(masm, op_);
+  BinaryOpStub_GenerateSmiSmiOperation(masm, op_, scratch2, scratch3);
   // Fall through if the result is not a smi.
   __ bind(&skip);
 
@@ -1892,12 +1896,6 @@ void BinaryOpStub::GenerateInt32Stub(MacroAssembler* masm) {
           __ b(ne, &transition);
         }
 
-        // We preserved r0 and r1 to be able to call runtime.
-        // Save the left value on the stack.
-        __ Push(r5, r4);
-
-        Label pop_and_call_runtime;
-
         // Allocate a heap number to store the result.
         heap_number_result = r5;
         BinaryOpStub_GenerateHeapResultAllocation(masm,
@@ -1905,20 +1903,15 @@ void BinaryOpStub::GenerateInt32Stub(MacroAssembler* masm) {
                                                   heap_number_map,
                                                   scratch1,
                                                   scratch2,
-                                                  &pop_and_call_runtime,
+                                                  &call_runtime,
                                                   mode_);
 
-        // Load the left value from the value saved on the stack.
-        __ Pop(r1, r0);
-
         // Call the C function to handle the double operation.
         CallCCodeForDoubleOperation(masm, op_, heap_number_result, scratch1);
         if (FLAG_debug_code) {
           __ stop("Unreachable code.");
         }
 
-        __ bind(&pop_and_call_runtime);
-        __ Drop(2);
         __ b(&call_runtime);
       }
 
@@ -2069,7 +2062,7 @@ void BinaryOpStub::GenerateNumberStub(MacroAssembler* masm) {
   Label call_runtime, transition;
   BinaryOpStub_GenerateFPOperation(
       masm, left_type_, right_type_, false,
-      &transition, &call_runtime, &transition, op_, mode_);
+      &transition, &call_runtime, &transition, op_, mode_, r6, r4, r5, r9);
 
   __ bind(&transition);
   GenerateTypeTransition(masm);
@@ -2088,11 +2081,13 @@ void BinaryOpStub::GenerateGeneric(MacroAssembler* masm) {
   Label call_runtime, call_string_add_or_runtime, transition;
 
   BinaryOpStub_GenerateSmiCode(
-      masm, &call_runtime, &call_runtime, op_, ALLOW_HEAPNUMBER_RESULTS, mode_);
+      masm, &call_runtime, &call_runtime, op_, ALLOW_HEAPNUMBER_RESULTS, mode_,
+      r5, r6, r4, r9);
 
   BinaryOpStub_GenerateFPOperation(
       masm, left_type_, right_type_, false,
-      &call_string_add_or_runtime, &call_runtime, &transition, op_, mode_);
+      &call_string_add_or_runtime, &call_runtime, &transition, op_, mode_, r6,
+      r4, r5, r9);
 
   __ bind(&transition);
   GenerateTypeTransition(masm);
@@ -2194,7 +2189,7 @@ void TranscendentalCacheStub::Generate(MacroAssembler* masm) {
   Label calculate;
   Label invalid_cache;
   const Register scratch0 = r9;
-  const Register scratch1 = r7;
+  Register scratch1 = no_reg;  // will be r4
   const Register cache_entry = r0;
   const bool tagged = (argument_type_ == TAGGED);
 
@@ -2274,6 +2269,9 @@ void TranscendentalCacheStub::Generate(MacroAssembler* masm) {
   __ cmp(r2, r4);
   __ cmp(r3, r5, eq);
   __ b(ne, &calculate);
+
+  scratch1 = r4;  // Start of scratch1 range.
+
   // Cache hit. Load result, cleanup and return.
   Counters* counters = masm->isolate()->counters();
   __ IncrementCounter(
@@ -2416,7 +2414,7 @@ void MathPowStub::Generate(MacroAssembler* masm) {
   const DwVfpRegister double_scratch = d0;
   const SwVfpRegister single_scratch = s0;
   const Register scratch = r9;
-  const Register scratch2 = r7;
+  const Register scratch2 = r4;
 
   Label call_runtime, done, int_exponent;
   if (exponent_type_ == ON_STACK) {
@@ -2926,14 +2924,14 @@ void JSEntryStub::GenerateBody(MacroAssembler* masm, bool is_construct) {
   // r3: argc
   // r4: argv
   Isolate* isolate = masm->isolate();
-  __ mov(r8, Operand(-1));  // Push a bad frame pointer to fail if it is used.
   int marker = is_construct ? StackFrame::ENTRY_CONSTRUCT : StackFrame::ENTRY;
-  __ mov(r7, Operand(Smi::FromInt(marker)));
+  __ mov(r8, Operand(Smi::FromInt(marker)));
   __ mov(r6, Operand(Smi::FromInt(marker)));
   __ mov(r5,
          Operand(ExternalReference(Isolate::kCEntryFPAddress, isolate)));
   __ ldr(r5, MemOperand(r5));
-  __ Push(r8, r7, r6, r5);
+  __ mov(ip, Operand(-1));  // Push a bad frame pointer to fail if it is used.
+  __ Push(ip, r8, r6, r5);
 
   // Set up frame pointer for the frame to be pushed.
   __ add(fp, sp, Operand(-EntryFrameConstants::kCallerFPOffset));
@@ -2979,7 +2977,7 @@ void JSEntryStub::GenerateBody(MacroAssembler* masm, bool is_construct) {
   // Invoke: Link this frame into the handler chain.  There's only one
   // handler block in this code object, so its index is 0.
   __ bind(&invoke);
-  // Must preserve r0-r4, r5-r7 are available.
+  // Must preserve r0-r4, r5-r6 are available.
   __ PushTryHandler(StackHandler::JS_ENTRY, 0);
   // If an exception not caught by another handler occurs, this handler
   // returns control to the code after the bl(&invoke) above, which
@@ -3586,31 +3584,36 @@ void ArgumentsAccessStub::GenerateNewNonStrictFast(MacroAssembler* masm) {
   __ ldr(r9, MemOperand(sp, 0 * kPointerSize));
   __ add(r9, r9, Operand(Smi::FromInt(Context::MIN_CONTEXT_SLOTS)));
   __ sub(r9, r9, Operand(r1));
-  __ LoadRoot(r7, Heap::kTheHoleValueRootIndex);
+  __ LoadRoot(r5, Heap::kTheHoleValueRootIndex);
   __ add(r3, r4, Operand(r6, LSL, 1));
   __ add(r3, r3, Operand(kParameterMapHeaderSize));
 
   // r6 = loop variable (tagged)
   // r1 = mapping index (tagged)
   // r3 = address of backing store (tagged)
-  // r4 = address of parameter map (tagged)
-  // r5 = temporary scratch (a.o., for address calculation)
-  // r7 = the hole value
+  // r4 = address of parameter map (tagged), which is also the address of new
+  //      object + Heap::kArgumentsObjectSize (tagged)
+  // r0 = temporary scratch (a.o., for address calculation)
+  // r5 = the hole value
   __ jmp(&parameters_test);
 
   __ bind(&parameters_loop);
   __ sub(r6, r6, Operand(Smi::FromInt(1)));
-  __ mov(r5, Operand(r6, LSL, 1));
-  __ add(r5, r5, Operand(kParameterMapHeaderSize - kHeapObjectTag));
-  __ str(r9, MemOperand(r4, r5));
-  __ sub(r5, r5, Operand(kParameterMapHeaderSize - FixedArray::kHeaderSize));
-  __ str(r7, MemOperand(r3, r5));
+  __ mov(r0, Operand(r6, LSL, 1));
+  __ add(r0, r0, Operand(kParameterMapHeaderSize - kHeapObjectTag));
+  __ str(r9, MemOperand(r4, r0));
+  __ sub(r0, r0, Operand(kParameterMapHeaderSize - FixedArray::kHeaderSize));
+  __ str(r5, MemOperand(r3, r0));
   __ add(r9, r9, Operand(Smi::FromInt(1)));
   __ bind(&parameters_test);
   __ cmp(r6, Operand(Smi::FromInt(0)));
   __ b(ne, &parameters_loop);
 
+  // Restore r0 = new object (tagged)
+  __ sub(r0, r4, Operand(Heap::kArgumentsObjectSize));
+
   __ bind(&skip_parameter_map);
+  // r0 = address of new object (tagged)
   // r2 = argument count (tagged)
   // r3 = address of backing store (tagged)
   // r5 = scratch
@@ -3641,6 +3644,7 @@ void ArgumentsAccessStub::GenerateNewNonStrictFast(MacroAssembler* masm) {
   __ Ret();
 
   // Do the runtime call to allocate the arguments object.
+  // r0 = address of new object (tagged)
   // r2 = argument count (tagged)
   __ bind(&runtime);
   __ str(r2, MemOperand(sp, 0 * kPointerSize));  // Patch argument count.
@@ -3769,7 +3773,7 @@ void RegExpExecStub::Generate(MacroAssembler* masm) {
   // therefore the content of these registers are safe to use after the call.
   Register subject = r4;
   Register regexp_data = r5;
-  Register last_match_info_elements = r6;
+  Register last_match_info_elements = no_reg;  // will be r6;
 
   // Ensure that a RegExp stack is allocated.
   Isolate* isolate = masm->isolate();
@@ -3902,19 +3906,19 @@ void RegExpExecStub::Generate(MacroAssembler* masm) {
   STATIC_ASSERT(kTwoByteStringTag == 0);
   __ and_(r0, r0, Operand(kStringEncodingMask));
   __ mov(r3, Operand(r0, ASR, 2), SetCC);
-  __ ldr(r7, FieldMemOperand(regexp_data, JSRegExp::kDataAsciiCodeOffset), ne);
-  __ ldr(r7, FieldMemOperand(regexp_data, JSRegExp::kDataUC16CodeOffset), eq);
+  __ ldr(r6, FieldMemOperand(regexp_data, JSRegExp::kDataAsciiCodeOffset), ne);
+  __ ldr(r6, FieldMemOperand(regexp_data, JSRegExp::kDataUC16CodeOffset), eq);
 
   // (E) Carry on.  String handling is done.
-  // r7: irregexp code
+  // r6: irregexp code
   // Check that the irregexp code has been generated for the actual string
   // encoding. If it has, the field contains a code object otherwise it contains
   // a smi (code flushing support).
-  __ JumpIfSmi(r7, &runtime);
+  __ JumpIfSmi(r6, &runtime);
 
   // r1: previous index
   // r3: encoding of subject string (1 if ASCII, 0 if two_byte);
-  // r7: code
+  // r6: code
   // subject: Subject string
   // regexp_data: RegExp data (FixedArray)
   // All checks done. Now push arguments for native regexp code.
@@ -3981,12 +3985,14 @@ void RegExpExecStub::Generate(MacroAssembler* masm) {
   __ mov(r0, subject);
 
   // Locate the code entry and call it.
-  __ add(r7, r7, Operand(Code::kHeaderSize - kHeapObjectTag));
+  __ add(r6, r6, Operand(Code::kHeaderSize - kHeapObjectTag));
   DirectCEntryStub stub;
-  stub.GenerateCall(masm, r7);
+  stub.GenerateCall(masm, r6);
 
   __ LeaveExitFrame(false, no_reg, true);
 
+  last_match_info_elements = r6;
+
   // r0: result
   // subject: subject string (callee saved)
   // regexp_data: RegExp data (callee saved)
@@ -4075,7 +4081,7 @@ void RegExpExecStub::Generate(MacroAssembler* masm) {
   __ RecordWriteField(last_match_info_elements,
                       RegExpImpl::kLastSubjectOffset,
                       subject,
-                      r7,
+                      r3,
                       kLRHasNotBeenSaved,
                       kDontSaveFPRegs);
   __ mov(subject, r2);
@@ -4085,7 +4091,7 @@ void RegExpExecStub::Generate(MacroAssembler* masm) {
   __ RecordWriteField(last_match_info_elements,
                       RegExpImpl::kLastInputOffset,
                       subject,
-                      r7,
+                      r3,
                       kLRHasNotBeenSaved,
                       kDontSaveFPRegs);
 
@@ -4652,7 +4658,6 @@ void StringHelper::GenerateCopyCharactersLong(MacroAssembler* masm,
                                               Register scratch2,
                                               Register scratch3,
                                               Register scratch4,
-                                              Register scratch5,
                                               int flags) {
   bool ascii = (flags & COPY_ASCII) != 0;
   bool dest_always_aligned = (flags & DEST_ALWAYS_ALIGNED) != 0;
@@ -4727,30 +4732,29 @@ void StringHelper::GenerateCopyCharactersLong(MacroAssembler* masm,
 
     __ bind(&loop);
     __ ldr(scratch3, MemOperand(src, 4, PostIndex));
-    __ sub(scratch5, limit, Operand(dest));
     __ orr(scratch1, scratch1, Operand(scratch3, LSL, left_shift));
     __ str(scratch1, MemOperand(dest, 4, PostIndex));
     __ mov(scratch1, Operand(scratch3, LSR, right_shift));
     // Loop if four or more bytes left to copy.
-    // Compare to eight, because we did the subtract before increasing dst.
-    __ sub(scratch5, scratch5, Operand(8), SetCC);
+    __ sub(scratch3, limit, Operand(dest));
+    __ sub(scratch3, scratch3, Operand(4), SetCC);
     __ b(ge, &loop);
   }
   // There is now between zero and three bytes left to copy (negative that
-  // number is in scratch5), and between one and three bytes already read into
+  // number is in scratch3), and between one and three bytes already read into
   // scratch1 (eight times that number in scratch4). We may have read past
   // the end of the string, but because objects are aligned, we have not read
   // past the end of the object.
   // Find the minimum of remaining characters to move and preloaded characters
   // and write those as bytes.
-  __ add(scratch5, scratch5, Operand(4), SetCC);
+  __ add(scratch3, scratch3, Operand(4), SetCC);
   __ b(eq, &done);
-  __ cmp(scratch4, Operand(scratch5, LSL, 3), ne);
+  __ cmp(scratch4, Operand(scratch3, LSL, 3), ne);
   // Move minimum of bytes read and bytes left to copy to scratch4.
-  __ mov(scratch5, Operand(scratch4, LSR, 3), LeaveCC, lt);
-  // Between one and three (value in scratch5) characters already read into
+  __ mov(scratch3, Operand(scratch4, LSR, 3), LeaveCC, lt);
+  // Between one and three (value in scratch3) characters already read into
   // scratch ready to write.
-  __ cmp(scratch5, Operand(2));
+  __ cmp(scratch3, Operand(2));
   __ strb(scratch1, MemOperand(dest, 1, PostIndex));
   __ mov(scratch1, Operand(scratch1, LSR, 8), LeaveCC, ge);
   __ strb(scratch1, MemOperand(dest, 1, PostIndex), ge);
@@ -5090,10 +5094,10 @@ void SubStringStub::Generate(MacroAssembler* masm) {
     STATIC_ASSERT((kStringEncodingMask & kTwoByteStringTag) == 0);
     __ tst(r1, Operand(kStringEncodingMask));
     __ b(eq, &two_byte_slice);
-    __ AllocateAsciiSlicedString(r0, r2, r6, r7, &runtime);
+    __ AllocateAsciiSlicedString(r0, r2, r6, r4, &runtime);
     __ jmp(&set_slice_header);
     __ bind(&two_byte_slice);
-    __ AllocateTwoByteSlicedString(r0, r2, r6, r7, &runtime);
+    __ AllocateTwoByteSlicedString(r0, r2, r6, r4, &runtime);
     __ bind(&set_slice_header);
     __ mov(r3, Operand(r3, LSL, 1));
     __ str(r5, FieldMemOperand(r0, SlicedString::kParentOffset));
@@ -5134,7 +5138,7 @@ void SubStringStub::Generate(MacroAssembler* masm) {
   __ b(eq, &two_byte_sequential);
 
   // Allocate and copy the resulting ASCII string.
-  __ AllocateAsciiString(r0, r2, r4, r6, r7, &runtime);
+  __ AllocateAsciiString(r0, r2, r4, r6, r1, &runtime);
 
   // Locate first character of substring to copy.
   __ add(r5, r5, r3);
@@ -5146,13 +5150,13 @@ void SubStringStub::Generate(MacroAssembler* masm) {
   // r2: result string length
   // r5: first character of substring to copy
   STATIC_ASSERT((SeqOneByteString::kHeaderSize & kObjectAlignmentMask) == 0);
-  StringHelper::GenerateCopyCharactersLong(masm, r1, r5, r2, r3, r4, r6, r7, r9,
+  StringHelper::GenerateCopyCharactersLong(masm, r1, r5, r2, r3, r4, r6, r9,
                                            COPY_ASCII | DEST_ALWAYS_ALIGNED);
   __ jmp(&return_r0);
 
   // Allocate and copy the resulting two-byte string.
   __ bind(&two_byte_sequential);
-  __ AllocateTwoByteString(r0, r2, r4, r6, r7, &runtime);
+  __ AllocateTwoByteString(r0, r2, r4, r6, r1, &runtime);
 
   // Locate first character of substring to copy.
   STATIC_ASSERT(kSmiTagSize == 1 && kSmiTag == 0);
@@ -5166,7 +5170,7 @@ void SubStringStub::Generate(MacroAssembler* masm) {
   // r5: first character of substring to copy.
   STATIC_ASSERT((SeqTwoByteString::kHeaderSize & kObjectAlignmentMask) == 0);
   StringHelper::GenerateCopyCharactersLong(
-      masm, r1, r5, r2, r3, r4, r6, r7, r9, DEST_ALWAYS_ALIGNED);
+      masm, r1, r5, r2, r3, r4, r6, r9, DEST_ALWAYS_ALIGNED);
 
   __ bind(&return_r0);
   Counters* counters = masm->isolate()->counters();
@@ -5432,7 +5436,7 @@ void StringAddStub::Generate(MacroAssembler* masm) {
     __ ldrb(r4, FieldMemOperand(r4, Map::kInstanceTypeOffset));
     __ ldrb(r5, FieldMemOperand(r5, Map::kInstanceTypeOffset));
   }
-  __ JumpIfBothInstanceTypesAreNotSequentialAscii(r4, r5, r6, r7,
+  __ JumpIfBothInstanceTypesAreNotSequentialAscii(r4, r5, r6, r3,
                                                   &call_runtime);
 
   // Get the two characters forming the sub string.
@@ -5443,7 +5447,7 @@ void StringAddStub::Generate(MacroAssembler* masm) {
   // just allocate a new one.
   Label make_two_character_string;
   StringHelper::GenerateTwoCharacterStringTableProbe(
-      masm, r2, r3, r6, r7, r4, r5, r9, &make_two_character_string);
+      masm, r2, r3, r6, r0, r4, r5, r9, &make_two_character_string);
   __ IncrementCounter(counters->string_add_native(), 1, r2, r3);
   __ add(sp, sp, Operand(2 * kPointerSize));
   __ Ret();
@@ -5488,7 +5492,7 @@ void StringAddStub::Generate(MacroAssembler* masm) {
 
   // Allocate an ASCII cons string.
   __ bind(&ascii_data);
-  __ AllocateAsciiConsString(r7, r6, r4, r5, &call_runtime);
+  __ AllocateAsciiConsString(r3, r6, r4, r5, &call_runtime);
   __ bind(&allocated);
   // Fill the fields of the cons string.
   Label skip_write_barrier, after_writing;
@@ -5499,15 +5503,15 @@ void StringAddStub::Generate(MacroAssembler* masm) {
   __ cmp(r4, Operand::Zero());
   __ b(eq, &skip_write_barrier);
 
-  __ str(r0, FieldMemOperand(r7, ConsString::kFirstOffset));
-  __ RecordWriteField(r7,
+  __ str(r0, FieldMemOperand(r3, ConsString::kFirstOffset));
+  __ RecordWriteField(r3,
                       ConsString::kFirstOffset,
                       r0,
                       r4,
                       kLRHasNotBeenSaved,
                       kDontSaveFPRegs);
-  __ str(r1, FieldMemOperand(r7, ConsString::kSecondOffset));
-  __ RecordWriteField(r7,
+  __ str(r1, FieldMemOperand(r3, ConsString::kSecondOffset));
+  __ RecordWriteField(r3,
                       ConsString::kSecondOffset,
                       r1,
                       r4,
@@ -5516,12 +5520,12 @@ void StringAddStub::Generate(MacroAssembler* masm) {
   __ jmp(&after_writing);
 
   __ bind(&skip_write_barrier);
-  __ str(r0, FieldMemOperand(r7, ConsString::kFirstOffset));
-  __ str(r1, FieldMemOperand(r7, ConsString::kSecondOffset));
+  __ str(r0, FieldMemOperand(r3, ConsString::kFirstOffset));
+  __ str(r1, FieldMemOperand(r3, ConsString::kSecondOffset));
 
   __ bind(&after_writing);
 
-  __ mov(r0, Operand(r7));
+  __ mov(r0, Operand(r3));
   __ IncrementCounter(counters->string_add_native(), 1, r2, r3);
   __ add(sp, sp, Operand(2 * kPointerSize));
   __ Ret();
@@ -5541,7 +5545,7 @@ void StringAddStub::Generate(MacroAssembler* masm) {
   __ b(eq, &ascii_data);
 
   // Allocate a two byte cons string.
-  __ AllocateTwoByteConsString(r7, r6, r4, r5, &call_runtime);
+  __ AllocateTwoByteConsString(r3, r6, r4, r5, &call_runtime);
   __ jmp(&allocated);
 
   // We cannot encounter sliced strings or cons strings here since:
@@ -5565,14 +5569,15 @@ void StringAddStub::Generate(MacroAssembler* masm) {
   }
 
   // Check whether both strings have same encoding
-  __ eor(r7, r4, Operand(r5));
-  __ tst(r7, Operand(kStringEncodingMask));
+  __ eor(ip, r4, Operand(r5));
+  ASSERT(__ ImmediateFitsAddrMode1Instruction(kStringEncodingMask));
+  __ tst(ip, Operand(kStringEncodingMask));
   __ b(ne, &call_runtime);
 
   STATIC_ASSERT(kSeqStringTag == 0);
   __ tst(r4, Operand(kStringRepresentationMask));
   STATIC_ASSERT(SeqOneByteString::kHeaderSize == SeqTwoByteString::kHeaderSize);
-  __ add(r7,
+  __ add(r6,
          r0,
          Operand(SeqOneByteString::kHeaderSize - kHeapObjectTag),
          LeaveCC,
@@ -5582,7 +5587,7 @@ void StringAddStub::Generate(MacroAssembler* masm) {
   STATIC_ASSERT(kShortExternalStringTag != 0);
   __ tst(r4, Operand(kShortExternalStringMask));
   __ b(ne, &call_runtime);
-  __ ldr(r7, FieldMemOperand(r0, ExternalString::kResourceDataOffset));
+  __ ldr(r6, FieldMemOperand(r0, ExternalString::kResourceDataOffset));
   __ bind(&first_prepared);
 
   STATIC_ASSERT(kSeqStringTag == 0);
@@ -5602,43 +5607,46 @@ void StringAddStub::Generate(MacroAssembler* masm) {
   __ bind(&second_prepared);
 
   Label non_ascii_string_add_flat_result;
-  // r7: first character of first string
+  // r6: first character of first string
   // r1: first character of second string
   // r2: length of first string.
   // r3: length of second string.
-  // r6: sum of lengths.
   // Both strings have the same encoding.
   STATIC_ASSERT(kTwoByteStringTag == 0);
   __ tst(r5, Operand(kStringEncodingMask));
   __ b(eq, &non_ascii_string_add_flat_result);
 
-  __ AllocateAsciiString(r0, r6, r4, r5, r9, &call_runtime);
-  __ add(r6, r0, Operand(SeqOneByteString::kHeaderSize - kHeapObjectTag));
+  __ add(r2, r2, Operand(r3));
+  __ AllocateAsciiString(r0, r2, r4, r5, r9, &call_runtime);
+  __ sub(r2, r2, Operand(r3));
+  __ add(r5, r0, Operand(SeqOneByteString::kHeaderSize - kHeapObjectTag));
   // r0: result string.
-  // r7: first character of first string.
+  // r6: first character of first string.
   // r1: first character of second string.
   // r2: length of first string.
   // r3: length of second string.
-  // r6: first character of result.
-  StringHelper::GenerateCopyCharacters(masm, r6, r7, r2, r4, true);
-  // r6: next character of result.
-  StringHelper::GenerateCopyCharacters(masm, r6, r1, r3, r4, true);
+  // r5: first character of result.
+  StringHelper::GenerateCopyCharacters(masm, r5, r6, r2, r4, true);
+  // r5: next character of result.
+  StringHelper::GenerateCopyCharacters(masm, r5, r1, r3, r4, true);
   __ IncrementCounter(counters->string_add_native(), 1, r2, r3);
   __ add(sp, sp, Operand(2 * kPointerSize));
   __ Ret();
 
   __ bind(&non_ascii_string_add_flat_result);
-  __ AllocateTwoByteString(r0, r6, r4, r5, r9, &call_runtime);
-  __ add(r6, r0, Operand(SeqTwoByteString::kHeaderSize - kHeapObjectTag));
+  __ add(r2, r2, Operand(r3));
+  __ AllocateTwoByteString(r0, r2, r4, r5, r9, &call_runtime);
+  __ sub(r2, r2, Operand(r3));
+  __ add(r5, r0, Operand(SeqTwoByteString::kHeaderSize - kHeapObjectTag));
   // r0: result string.
-  // r7: first character of first string.
+  // r6: first character of first string.
   // r1: first character of second string.
   // r2: length of first string.
   // r3: length of second string.
-  // r6: first character of result.
-  StringHelper::GenerateCopyCharacters(masm, r6, r7, r2, r4, false);
-  // r6: next character of result.
-  StringHelper::GenerateCopyCharacters(masm, r6, r1, r3, r4, false);
+  // r5: first character of result.
+  StringHelper::GenerateCopyCharacters(masm, r5, r6, r2, r4, false);
+  // r5: next character of result.
+  StringHelper::GenerateCopyCharacters(masm, r5, r1, r3, r4, false);
   __ IncrementCounter(counters->string_add_native(), 1, r2, r3);
   __ add(sp, sp, Operand(2 * kPointerSize));
   __ Ret();
@@ -6308,7 +6316,7 @@ struct AheadOfTimeWriteBarrierStubList {
 
 static const AheadOfTimeWriteBarrierStubList kAheadOfTime[] = {
   // Used in RegExpExecStub.
-  { REG(r6), REG(r4), REG(r7), EMIT_REMEMBERED_SET },
+  { REG(r6), REG(r4), REG(r3), EMIT_REMEMBERED_SET },
   // Used in CompileArrayPushCall.
   // Also used in StoreIC::GenerateNormal via GenerateDictionaryStore.
   // Also used in KeyedStoreIC::GenerateGeneric.
@@ -6335,8 +6343,8 @@ static const AheadOfTimeWriteBarrierStubList kAheadOfTime[] = {
   // FastNewClosureStub::Generate
   { REG(r2), REG(r4), REG(r1), EMIT_REMEMBERED_SET },
   // StringAddStub::Generate
-  { REG(r7), REG(r1), REG(r4), EMIT_REMEMBERED_SET },
-  { REG(r7), REG(r0), REG(r4), EMIT_REMEMBERED_SET },
+  { REG(r3), REG(r1), REG(r4), EMIT_REMEMBERED_SET },
+  { REG(r3), REG(r0), REG(r4), EMIT_REMEMBERED_SET },
   // Null termination.
   { REG(no_reg), REG(no_reg), REG(no_reg), EMIT_REMEMBERED_SET}
 };
index a404f0173981ef9795e2aa9ebdba429fda7b96c6..380a83bf8af206e24edca9996a7c6bb784fa7383 100644 (file)
@@ -106,7 +106,6 @@ class StringHelper : public AllStatic {
                                          Register scratch2,
                                          Register scratch3,
                                          Register scratch4,
-                                         Register scratch5,
                                          int flags);
 
 
index 5b80d6facc5ea8e4a0b2fb6fcf985a83bdbc1cba..fbd9f6388024d7562b9727c9e1650963e3de3d64 100644 (file)
@@ -444,15 +444,16 @@ void ElementsTransitionGenerator::GenerateSmiToDouble(
 
   __ push(lr);
   __ ldr(r5, FieldMemOperand(r4, FixedArray::kLengthOffset));
-  // r4: source FixedArray
   // r5: number of elements (smi-tagged)
 
   // Allocate new FixedDoubleArray.
   // Use lr as a temporary register.
   __ mov(lr, Operand(r5, LSL, 2));
   __ add(lr, lr, Operand(FixedDoubleArray::kHeaderSize));
-  __ Allocate(lr, r6, r7, r9, &gc_required, DOUBLE_ALIGNMENT);
+  __ Allocate(lr, r6, r4, r9, &gc_required, DOUBLE_ALIGNMENT);
   // r6: destination FixedDoubleArray, not tagged as heap object.
+  __ ldr(r4, FieldMemOperand(r2, JSObject::kElementsOffset));
+  // r4: source FixedArray.
 
   // Set destination FixedDoubleArray's length and map.
   __ LoadRoot(r9, Heap::kFixedDoubleArrayMapRootIndex);
@@ -483,15 +484,15 @@ void ElementsTransitionGenerator::GenerateSmiToDouble(
 
   // Prepare for conversion loop.
   __ add(r3, r4, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
-  __ add(r7, r6, Operand(FixedDoubleArray::kHeaderSize));
-  __ add(r6, r7, Operand(r5, LSL, 2));
+  __ add(r9, r6, Operand(FixedDoubleArray::kHeaderSize));
+  __ add(r6, r9, Operand(r5, LSL, 2));
   __ mov(r4, Operand(kHoleNanLower32));
   __ mov(r5, Operand(kHoleNanUpper32));
   // r3: begin of source FixedArray element fields, not tagged
   // r4: kHoleNanLower32
   // r5: kHoleNanUpper32
   // r6: end of destination FixedDoubleArray, not tagged
-  // r7: begin of FixedDoubleArray element fields, not tagged
+  // r9: begin of FixedDoubleArray element fields, not tagged
 
   __ b(&entry);
 
@@ -514,30 +515,30 @@ void ElementsTransitionGenerator::GenerateSmiToDouble(
 
   // Convert and copy elements.
   __ bind(&loop);
-  __ ldr(r9, MemOperand(r3, 4, PostIndex));
-  // r9: current element
-  __ UntagAndJumpIfNotSmi(r9, r9, &convert_hole);
+  __ ldr(lr, MemOperand(r3, 4, PostIndex));
+  // lr: current element
+  __ UntagAndJumpIfNotSmi(lr, lr, &convert_hole);
 
   // Normal smi, convert to double and store.
-  __ vmov(s0, r9);
+  __ vmov(s0, lr);
   __ vcvt_f64_s32(d0, s0);
-  __ vstr(d0, r7, 0);
-  __ add(r7, r7, Operand(8));
+  __ vstr(d0, r9, 0);
+  __ add(r9, r9, Operand(8));
   __ b(&entry);
 
   // Hole found, store the-hole NaN.
   __ bind(&convert_hole);
   if (FLAG_debug_code) {
     // Restore a "smi-untagged" heap object.
-    __ SmiTag(r9);
-    __ orr(r9, r9, Operand(1));
-    __ CompareRoot(r9, Heap::kTheHoleValueRootIndex);
+    __ SmiTag(lr);
+    __ orr(lr, lr, Operand(1));
+    __ CompareRoot(lr, Heap::kTheHoleValueRootIndex);
     __ Assert(eq, kObjectFoundInSmiOnlyArray);
   }
-  __ Strd(r4, r5, MemOperand(r7, 8, PostIndex));
+  __ Strd(r4, r5, MemOperand(r9, 8, PostIndex));
 
   __ bind(&entry);
-  __ cmp(r7, r6);
+  __ cmp(r9, r6);
   __ b(lt, &loop);
 
   __ pop(lr);
@@ -577,7 +578,7 @@ void ElementsTransitionGenerator::GenerateDoubleToObject(
   // Allocate new FixedArray.
   __ mov(r0, Operand(FixedDoubleArray::kHeaderSize));
   __ add(r0, r0, Operand(r5, LSL, 1));
-  __ Allocate(r0, r6, r7, r9, &gc_required, NO_ALLOCATION_FLAGS);
+  __ Allocate(r0, r6, r3, r9, &gc_required, NO_ALLOCATION_FLAGS);
   // r6: destination FixedArray, not tagged as heap object
   // Set destination FixedDoubleArray's length and map.
   __ LoadRoot(r9, Heap::kFixedArrayMapRootIndex);
@@ -589,14 +590,12 @@ void ElementsTransitionGenerator::GenerateDoubleToObject(
   __ add(r3, r6, Operand(FixedArray::kHeaderSize));
   __ add(r6, r6, Operand(kHeapObjectTag));
   __ add(r5, r3, Operand(r5, LSL, 1));
-  __ LoadRoot(r7, Heap::kTheHoleValueRootIndex);
   __ LoadRoot(r9, Heap::kHeapNumberMapRootIndex);
   // Using offsetted addresses in r4 to fully take advantage of post-indexing.
   // r3: begin of destination FixedArray element fields, not tagged
   // r4: begin of source FixedDoubleArray element fields, not tagged, +4
   // r5: end of destination FixedArray, not tagged
   // r6: destination FixedArray
-  // r7: the-hole pointer
   // r9: heap number map
   __ b(&entry);
 
@@ -608,7 +607,7 @@ void ElementsTransitionGenerator::GenerateDoubleToObject(
 
   __ bind(&loop);
   __ ldr(r1, MemOperand(r4, 8, PostIndex));
-  // lr: current element's upper 32 bit
+  // r1: current element's upper 32 bit
   // r4: address of next element's upper 32 bit
   __ cmp(r1, Operand(kHoleNanUpper32));
   __ b(eq, &convert_hole);
@@ -631,7 +630,8 @@ void ElementsTransitionGenerator::GenerateDoubleToObject(
 
   // Replace the-hole NaN with the-hole pointer.
   __ bind(&convert_hole);
-  __ str(r7, MemOperand(r3, 4, PostIndex));
+  __ LoadRoot(r0, Heap::kTheHoleValueRootIndex);
+  __ str(r0, MemOperand(r3, 4, PostIndex));
 
   __ bind(&entry);
   __ cmp(r3, r5);
index 9f8da50f9aed5232d4838dcb2960acdd7a729516..0ed84ff92e7fc20825a5e159aeb02746c692c32e 100644 (file)
@@ -268,8 +268,8 @@ void Deoptimizer::EntryGenerator::Generate() {
   __ bind(&inner_push_loop);
   __ sub(r3, r3, Operand(sizeof(uint32_t)));
   __ add(r6, r2, Operand(r3));
-  __ ldr(r7, MemOperand(r6, FrameDescription::frame_content_offset()));
-  __ push(r7);
+  __ ldr(r6, MemOperand(r6, FrameDescription::frame_content_offset()));
+  __ push(r6);
   __ bind(&inner_loop_header);
   __ cmp(r3, Operand::Zero());
   __ b(ne, &inner_push_loop);  // test for gt?
@@ -315,9 +315,9 @@ void Deoptimizer::EntryGenerator::Generate() {
   __ InitializeRootRegister();
 
   __ pop(ip);  // remove pc
-  __ pop(r7);  // get continuation, leave pc on stack
+  __ pop(ip);  // get continuation, leave pc on stack
   __ pop(lr);
-  __ Jump(r7);
+  __ Jump(ip);
   __ stop("Unreachable.");
 }
 
index d022b414b436685735f3926f2b67fa42662015de..64a718e89f71e49ac362d71aeb55741c265ecfa9 100644 (file)
@@ -64,7 +64,7 @@ const RegList kCalleeSaved =
   1 <<  4 |  //  r4 v1
   1 <<  5 |  //  r5 v2
   1 <<  6 |  //  r6 v3
-  1 <<  7 |  //  r7 v4
+  1 <<  7 |  //  r7 v4 (pp in JavaScript code)
   1 <<  8 |  //  r8 v5 (cp in JavaScript code)
   kR9Available <<  9 |  //  r9 v6
   1 << 10 |  // r10 v7
index 195fc8c5be7f6ae4bf5282ea6479755378ff5d9c..bab8a0087b18f421f5749c83df12d10d28249898 100644 (file)
@@ -3962,9 +3962,8 @@ void FullCodeGenerator::EmitGetCachedArrayIndex(CallRuntime* expr) {
 
 
 void FullCodeGenerator::EmitFastAsciiArrayJoin(CallRuntime* expr) {
-  Label bailout, done, one_char_separator, long_separator,
-      non_trivial_array, not_size_one_array, loop,
-      empty_separator_loop, one_char_separator_loop,
+  Label bailout, done, one_char_separator, long_separator, non_trivial_array,
+      not_size_one_array, loop, empty_separator_loop, one_char_separator_loop,
       one_char_separator_loop_entry, long_separator_loop;
   ZoneList<Expression*>* args = expr->arguments();
   ASSERT(args->length() == 2);
@@ -3982,19 +3981,18 @@ void FullCodeGenerator::EmitFastAsciiArrayJoin(CallRuntime* expr) {
   Register string = r4;
   Register element = r5;
   Register elements_end = r6;
-  Register scratch1 = r7;
-  Register scratch2 = r9;
+  Register scratch = r9;
 
   // Separator operand is on the stack.
   __ pop(separator);
 
   // Check that the array is a JSArray.
   __ JumpIfSmi(array, &bailout);
-  __ CompareObjectType(array, scratch1, scratch2, JS_ARRAY_TYPE);
+  __ CompareObjectType(array, scratch, array_length, JS_ARRAY_TYPE);
   __ b(ne, &bailout);
 
   // Check that the array has fast elements.
-  __ CheckFastElements(scratch1, scratch2, &bailout);
+  __ CheckFastElements(scratch, array_length, &bailout);
 
   // If the array has length zero, return the empty string.
   __ ldr(array_length, FieldMemOperand(array, JSArray::kLengthOffset));
@@ -4031,11 +4029,11 @@ void FullCodeGenerator::EmitFastAsciiArrayJoin(CallRuntime* expr) {
   __ bind(&loop);
   __ ldr(string, MemOperand(element, kPointerSize, PostIndex));
   __ JumpIfSmi(string, &bailout);
-  __ ldr(scratch1, FieldMemOperand(string, HeapObject::kMapOffset));
-  __ ldrb(scratch1, FieldMemOperand(scratch1, Map::kInstanceTypeOffset));
-  __ JumpIfInstanceTypeIsNotSequentialAscii(scratch1, scratch2, &bailout);
-  __ ldr(scratch1, FieldMemOperand(string, SeqOneByteString::kLengthOffset));
-  __ add(string_length, string_length, Operand(scratch1), SetCC);
+  __ ldr(scratch, FieldMemOperand(string, HeapObject::kMapOffset));
+  __ ldrb(scratch, FieldMemOperand(scratch, Map::kInstanceTypeOffset));
+  __ JumpIfInstanceTypeIsNotSequentialAscii(scratch, scratch, &bailout);
+  __ ldr(scratch, FieldMemOperand(string, SeqOneByteString::kLengthOffset));
+  __ add(string_length, string_length, Operand(scratch), SetCC);
   __ b(vs, &bailout);
   __ cmp(element, elements_end);
   __ b(lt, &loop);
@@ -4056,23 +4054,23 @@ void FullCodeGenerator::EmitFastAsciiArrayJoin(CallRuntime* expr) {
 
   // Check that the separator is a flat ASCII string.
   __ JumpIfSmi(separator, &bailout);
-  __ ldr(scratch1, FieldMemOperand(separator, HeapObject::kMapOffset));
-  __ ldrb(scratch1, FieldMemOperand(scratch1, Map::kInstanceTypeOffset));
-  __ JumpIfInstanceTypeIsNotSequentialAscii(scratch1, scratch2, &bailout);
+  __ ldr(scratch, FieldMemOperand(separator, HeapObject::kMapOffset));
+  __ ldrb(scratch, FieldMemOperand(scratch, Map::kInstanceTypeOffset));
+  __ JumpIfInstanceTypeIsNotSequentialAscii(scratch, scratch, &bailout);
 
   // Add (separator length times array_length) - separator length to the
   // string_length to get the length of the result string. array_length is not
   // smi but the other values are, so the result is a smi
-  __ ldr(scratch1, FieldMemOperand(separator, SeqOneByteString::kLengthOffset));
-  __ sub(string_length, string_length, Operand(scratch1));
-  __ smull(scratch2, ip, array_length, scratch1);
+  __ ldr(scratch, FieldMemOperand(separator, SeqOneByteString::kLengthOffset));
+  __ sub(string_length, string_length, Operand(scratch));
+  __ smull(scratch, ip, array_length, scratch);
   // Check for smi overflow. No overflow if higher 33 bits of 64-bit result are
   // zero.
   __ cmp(ip, Operand::Zero());
   __ b(ne, &bailout);
-  __ tst(scratch2, Operand(0x80000000));
+  __ tst(scratch, Operand(0x80000000));
   __ b(ne, &bailout);
-  __ add(string_length, string_length, Operand(scratch2), SetCC);
+  __ add(string_length, string_length, Operand(scratch), SetCC);
   __ b(vs, &bailout);
   __ SmiUntag(string_length);
 
@@ -4089,9 +4087,9 @@ void FullCodeGenerator::EmitFastAsciiArrayJoin(CallRuntime* expr) {
   //   array_length: Length of the array.
   __ AllocateAsciiString(result,
                          string_length,
-                         scratch1,
-                         scratch2,
-                         elements_end,
+                         scratch,
+                         string,  // used as scratch
+                         elements_end,  // used as scratch
                          &bailout);
   // Prepare for looping. Set up elements_end to end of the array. Set
   // result_pos to the position of the result where to write the first
@@ -4104,8 +4102,8 @@ void FullCodeGenerator::EmitFastAsciiArrayJoin(CallRuntime* expr) {
          Operand(SeqOneByteString::kHeaderSize - kHeapObjectTag));
 
   // Check the length of the separator.
-  __ ldr(scratch1, FieldMemOperand(separator, SeqOneByteString::kLengthOffset));
-  __ cmp(scratch1, Operand(Smi::FromInt(1)));
+  __ ldr(scratch, FieldMemOperand(separator, SeqOneByteString::kLengthOffset));
+  __ cmp(scratch, Operand(Smi::FromInt(1)));
   __ b(eq, &one_char_separator);
   __ b(gt, &long_separator);
 
@@ -4123,7 +4121,7 @@ void FullCodeGenerator::EmitFastAsciiArrayJoin(CallRuntime* expr) {
   __ add(string,
          string,
          Operand(SeqOneByteString::kHeaderSize - kHeapObjectTag));
-  __ CopyBytes(string, result_pos, string_length, scratch1);
+  __ CopyBytes(string, result_pos, string_length, scratch);
   __ cmp(element, elements_end);
   __ b(lt, &empty_separator_loop);  // End while (element < elements_end).
   ASSERT(result.is(r0));
@@ -4155,7 +4153,7 @@ void FullCodeGenerator::EmitFastAsciiArrayJoin(CallRuntime* expr) {
   __ add(string,
          string,
          Operand(SeqOneByteString::kHeaderSize - kHeapObjectTag));
-  __ CopyBytes(string, result_pos, string_length, scratch1);
+  __ CopyBytes(string, result_pos, string_length, scratch);
   __ cmp(element, elements_end);
   __ b(lt, &one_char_separator_loop);  // End while (element < elements_end).
   ASSERT(result.is(r0));
@@ -4176,7 +4174,7 @@ void FullCodeGenerator::EmitFastAsciiArrayJoin(CallRuntime* expr) {
   __ add(string,
          separator,
          Operand(SeqOneByteString::kHeaderSize - kHeapObjectTag));
-  __ CopyBytes(string, result_pos, string_length, scratch1);
+  __ CopyBytes(string, result_pos, string_length, scratch);
 
   __ bind(&long_separator);
   __ ldr(string, MemOperand(element, kPointerSize, PostIndex));
@@ -4185,7 +4183,7 @@ void FullCodeGenerator::EmitFastAsciiArrayJoin(CallRuntime* expr) {
   __ add(string,
          string,
          Operand(SeqOneByteString::kHeaderSize - kHeapObjectTag));
-  __ CopyBytes(string, result_pos, string_length, scratch1);
+  __ CopyBytes(string, result_pos, string_length, scratch);
   __ cmp(element, elements_end);
   __ b(lt, &long_separator_loop);  // End while (element < elements_end).
   ASSERT(result.is(r0));
index f15d4b11f843bd22e43d67c5a4048d73ac2b54da..b39a0edfb849de94f7184215867eb1adcf48f9a7 100644 (file)
@@ -1394,7 +1394,7 @@ void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm,
   Register receiver = r2;
   Register receiver_map = r3;
   Register elements_map = r6;
-  Register elements = r7;  // Elements array of the receiver.
+  Register elements = r9;  // Elements array of the receiver.
   // r4 and r5 are used as general scratch registers.
 
   // Check that the key is a smi.
index 2680c348d6255177386fdc7cd11611a4a3fff1d8..0c5b973d3821bef5347aa0813561f53318450edc 100644 (file)
@@ -3879,9 +3879,9 @@ void LCodeGen::DoPower(LPower* instr) {
   } else if (exponent_type.IsTagged()) {
     Label no_deopt;
     __ JumpIfSmi(r2, &no_deopt);
-    __ ldr(r7, FieldMemOperand(r2, HeapObject::kMapOffset));
+    __ ldr(r6, FieldMemOperand(r2, HeapObject::kMapOffset));
     __ LoadRoot(ip, Heap::kHeapNumberMapRootIndex);
-    __ cmp(r7, Operand(ip));
+    __ cmp(r6, Operand(ip));
     DeoptimizeIf(ne, instr->environment());
     __ bind(&no_deopt);
     MathPowStub stub(MathPowStub::TAGGED);
@@ -5386,24 +5386,24 @@ void LCodeGen::DoToFastProperties(LToFastProperties* instr) {
 void LCodeGen::DoRegExpLiteral(LRegExpLiteral* instr) {
   Label materialized;
   // Registers will be used as follows:
-  // r7 = literals array.
+  // r6 = literals array.
   // r1 = regexp literal.
   // r0 = regexp literal clone.
-  // r2 and r4-r6 are used as temporaries.
+  // r2-5 are used as temporaries.
   int literal_offset =
       FixedArray::OffsetOfElementAt(instr->hydrogen()->literal_index());
-  __ LoadHeapObject(r7, instr->hydrogen()->literals());
-  __ ldr(r1, FieldMemOperand(r7, literal_offset));
+  __ LoadHeapObject(r6, instr->hydrogen()->literals());
+  __ ldr(r1, FieldMemOperand(r6, literal_offset));
   __ LoadRoot(ip, Heap::kUndefinedValueRootIndex);
   __ cmp(r1, ip);
   __ b(ne, &materialized);
 
   // Create regexp literal using runtime function
   // Result will be in r0.
-  __ mov(r6, Operand(Smi::FromInt(instr->hydrogen()->literal_index())));
-  __ mov(r5, Operand(instr->hydrogen()->pattern()));
-  __ mov(r4, Operand(instr->hydrogen()->flags()));
-  __ Push(r7, r6, r5, r4);
+  __ mov(r5, Operand(Smi::FromInt(instr->hydrogen()->literal_index())));
+  __ mov(r4, Operand(instr->hydrogen()->pattern()));
+  __ mov(r3, Operand(instr->hydrogen()->flags()));
+  __ Push(r6, r5, r4, r3);
   CallRuntime(Runtime::kMaterializeRegExpLiteral, 4, instr);
   __ mov(r1, r0);
 
index eeabc053f5026603f4fc97b92a794dc4335155db..fd515218cb075295830946327624eb0114d4101e 100644 (file)
@@ -1337,7 +1337,7 @@ void MacroAssembler::PushTryHandler(StackHandler::Kind kind,
   STATIC_ASSERT(StackHandlerConstants::kContextOffset == 3 * kPointerSize);
   STATIC_ASSERT(StackHandlerConstants::kFPOffset == 4 * kPointerSize);
 
-  // For the JSEntry handler, we must preserve r0-r4, r5-r7 are available.
+  // For the JSEntry handler, we must preserve r0-r4, r5-r6 are available.
   // We will build up the handler from the bottom by pushing on the stack.
   // Set up the code object (r5) and the state (r6) for pushing.
   unsigned state =
@@ -1348,9 +1348,9 @@ void MacroAssembler::PushTryHandler(StackHandler::Kind kind,
 
   // Push the frame pointer, context, state, and code object.
   if (kind == StackHandler::JS_ENTRY) {
-    mov(r7, Operand(Smi::FromInt(0)));  // Indicates no context.
+    mov(cp, Operand(Smi::FromInt(0)));  // Indicates no context.
     mov(ip, Operand::Zero());  // NULL frame pointer.
-    stm(db_w, sp, r5.bit() | r6.bit() | r7.bit() | ip.bit());
+    stm(db_w, sp, r5.bit() | r6.bit() | cp.bit() | ip.bit());
   } else {
     stm(db_w, sp, r5.bit() | r6.bit() | cp.bit() | fp.bit());
   }
@@ -2305,13 +2305,15 @@ void MacroAssembler::CallApiFunctionAndReturn(
       ExternalReference::handle_scope_level_address(isolate()),
       next_address);
 
+  ASSERT(!thunk_last_arg.is(r3));
+
   // Allocate HandleScope in callee-save registers.
-  mov(r7, Operand(next_address));
-  ldr(r4, MemOperand(r7, kNextOffset));
-  ldr(r5, MemOperand(r7, kLimitOffset));
-  ldr(r6, MemOperand(r7, kLevelOffset));
+  mov(r9, Operand(next_address));
+  ldr(r4, MemOperand(r9, kNextOffset));
+  ldr(r5, MemOperand(r9, kLimitOffset));
+  ldr(r6, MemOperand(r9, kLevelOffset));
   add(r6, r6, Operand(1));
-  str(r6, MemOperand(r7, kLevelOffset));
+  str(r6, MemOperand(r9, kLevelOffset));
 
   if (FLAG_log_timer_events) {
     FrameScope frame(this, StackFrame::MANUAL);
@@ -2322,7 +2324,6 @@ void MacroAssembler::CallApiFunctionAndReturn(
     PopSafepointRegisters();
   }
 
-  ASSERT(!thunk_last_arg.is(r3));
   Label profiler_disabled;
   Label end_profiler_check;
   bool* is_profiling_flag =
@@ -2368,15 +2369,15 @@ void MacroAssembler::CallApiFunctionAndReturn(
   bind(&return_value_loaded);
   // No more valid handles (the result handle was the last one). Restore
   // previous handle scope.
-  str(r4, MemOperand(r7, kNextOffset));
+  str(r4, MemOperand(r9, kNextOffset));
   if (emit_debug_code()) {
-    ldr(r1, MemOperand(r7, kLevelOffset));
+    ldr(r1, MemOperand(r9, kLevelOffset));
     cmp(r1, r6);
     Check(eq, kUnexpectedLevelAfterReturnFromApiCall);
   }
   sub(r6, r6, Operand(1));
-  str(r6, MemOperand(r7, kLevelOffset));
-  ldr(ip, MemOperand(r7, kLimitOffset));
+  str(r6, MemOperand(r9, kLevelOffset));
+  ldr(ip, MemOperand(r9, kLimitOffset));
   cmp(r5, ip);
   b(ne, &delete_allocated_handles);
 
@@ -2409,7 +2410,7 @@ void MacroAssembler::CallApiFunctionAndReturn(
 
   // HandleScope limit has changed. Delete allocated extensions.
   bind(&delete_allocated_handles);
-  str(r5, MemOperand(r7, kLimitOffset));
+  str(r5, MemOperand(r9, kLimitOffset));
   mov(r4, r0);
   PrepareCallCFunction(1, r5);
   mov(r0, Operand(ExternalReference::isolate_address(isolate())));
index 6d08ab9bd1686b98e5d41a48a626b79d9a02aa61..6d5ba517f33b97810c135bbfb1481d19431b4601 100644 (file)
@@ -45,8 +45,9 @@ inline MemOperand FieldMemOperand(Register object, int offset) {
 
 
 // Give alias names to registers
-const Register cp = { 8 };  // JavaScript context pointer
-const Register kRootRegister = { 10 };  // Roots array pointer.
+const Register pp = { kRegister_r7_Code };  // Constant pool pointer.
+const Register cp = { kRegister_r8_Code };  // JavaScript context pointer.
+const Register kRootRegister = { kRegister_r10_Code };  // Roots array pointer.
 
 // Flags used for AllocateHeapNumber
 enum TaggingMode {
index 567eb632162f27d4cef6b1d3e2952bd9c81c3eec..6308b346eb935e338be26e11dd9f7950f93924dc 100644 (file)
@@ -874,8 +874,8 @@ static void GenerateFastApiDirectCall(MacroAssembler* masm,
   // Store call data.
   __ str(r6, MemOperand(sp, 3 * kPointerSize));
   // Store isolate.
-  __ mov(r7, Operand(ExternalReference::isolate_address(masm->isolate())));
-  __ str(r7, MemOperand(sp, 4 * kPointerSize));
+  __ mov(r5, Operand(ExternalReference::isolate_address(masm->isolate())));
+  __ str(r5, MemOperand(sp, 4 * kPointerSize));
   // Store ReturnValue default and ReturnValue.
   __ LoadRoot(r5, Heap::kUndefinedValueRootIndex);
   __ str(r5, MemOperand(sp, 5 * kPointerSize));
@@ -1855,15 +1855,15 @@ Handle<Code> CallStubCompiler::CompileArrayPushCall(
 
       if (FLAG_smi_only_arrays  && !FLAG_trace_elements_transitions) {
         Label fast_object, not_fast_object;
-        __ CheckFastObjectElements(r3, r7, &not_fast_object);
+        __ CheckFastObjectElements(r3, r9, &not_fast_object);
         __ jmp(&fast_object);
         // In case of fast smi-only, convert to fast object, otherwise bail out.
         __ bind(&not_fast_object);
-        __ CheckFastSmiElements(r3, r7, &call_builtin);
+        __ CheckFastSmiElements(r3, r9, &call_builtin);
 
-        __ ldr(r7, FieldMemOperand(r4, HeapObject::kMapOffset));
+        __ ldr(r9, FieldMemOperand(r4, HeapObject::kMapOffset));
         __ LoadRoot(ip, Heap::kHeapNumberMapRootIndex);
-        __ cmp(r7, ip);
+        __ cmp(r9, ip);
         __ b(eq, &call_builtin);
         // edx: receiver
         // r3: map
@@ -1871,7 +1871,7 @@ Handle<Code> CallStubCompiler::CompileArrayPushCall(
         __ LoadTransitionedArrayMapConditional(FAST_SMI_ELEMENTS,
                                                FAST_ELEMENTS,
                                                r3,
-                                               r7,
+                                               r9,
                                                &try_holey_map);
         __ mov(r2, receiver);
         ElementsTransitionGenerator::
@@ -1884,7 +1884,7 @@ Handle<Code> CallStubCompiler::CompileArrayPushCall(
         __ LoadTransitionedArrayMapConditional(FAST_HOLEY_SMI_ELEMENTS,
                                                FAST_HOLEY_ELEMENTS,
                                                r3,
-                                               r7,
+                                               r9,
                                                &call_builtin);
         __ mov(r2, receiver);
         ElementsTransitionGenerator::
@@ -1917,7 +1917,6 @@ Handle<Code> CallStubCompiler::CompileArrayPushCall(
 
       __ bind(&attempt_to_grow_elements);
       // r0: array's length + 1.
-      // r4: elements' length.
 
       if (!FLAG_inline_new) {
         __ b(&call_builtin);
@@ -1928,8 +1927,8 @@ Handle<Code> CallStubCompiler::CompileArrayPushCall(
       // the new element is non-Smi. For now, delegate to the builtin.
       Label no_fast_elements_check;
       __ JumpIfSmi(r2, &no_fast_elements_check);
-      __ ldr(r7, FieldMemOperand(receiver, HeapObject::kMapOffset));
-      __ CheckFastObjectElements(r7, r7, &call_builtin);
+      __ ldr(r9, FieldMemOperand(receiver, HeapObject::kMapOffset));
+      __ CheckFastObjectElements(r9, r9, &call_builtin);
       __ bind(&no_fast_elements_check);
 
       ExternalReference new_space_allocation_top =
@@ -1941,8 +1940,8 @@ Handle<Code> CallStubCompiler::CompileArrayPushCall(
       // Load top and check if it is the end of elements.
       __ add(end_elements, elements, Operand::PointerOffsetFromSmiKey(r0));
       __ add(end_elements, end_elements, Operand(kEndElementsOffset));
-      __ mov(r7, Operand(new_space_allocation_top));
-      __ ldr(r3, MemOperand(r7));
+      __ mov(r4, Operand(new_space_allocation_top));
+      __ ldr(r3, MemOperand(r4));
       __ cmp(end_elements, r3);
       __ b(ne, &call_builtin);
 
@@ -1954,7 +1953,7 @@ Handle<Code> CallStubCompiler::CompileArrayPushCall(
 
       // We fit and could grow elements.
       // Update new_space_allocation_top.
-      __ str(r3, MemOperand(r7));
+      __ str(r3, MemOperand(r4));
       // Push the argument.
       __ str(r2, MemOperand(end_elements));
       // Fill the rest with holes.
@@ -1965,6 +1964,7 @@ Handle<Code> CallStubCompiler::CompileArrayPushCall(
 
       // Update elements' and array's sizes.
       __ str(r0, FieldMemOperand(receiver, JSArray::kLengthOffset));
+      __ ldr(r4, FieldMemOperand(elements, FixedArray::kLengthOffset));
       __ add(r4, r4, Operand(Smi::FromInt(kAllocationDelta)));
       __ str(r4, FieldMemOperand(elements, FixedArray::kLengthOffset));
 
index 2c012511c46eb3d4319bc6f47eeebe714de35320..e3f856518233eff94a3d526506ad8942e2b39307 100644 (file)
@@ -826,6 +826,16 @@ DEFINE_implication(print_all_code, trace_codegen)
 #endif
 #endif
 
+//
+// Read-only flags
+//
+#undef FLAG
+#define FLAG FLAG_READONLY
+
+// assembler-arm.h
+DEFINE_bool(enable_ool_constant_pool, false,
+            "enable use of out-of-line constant pools (ARM only)")
+
 // Cleanup...
 #undef FLAG_FULL
 #undef FLAG_READONLY