Remember to update the write barrier when storing into
authorkasperl@chromium.org <kasperl@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Tue, 2 Feb 2010 07:58:09 +0000 (07:58 +0000)
committerkasperl@chromium.org <kasperl@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Tue, 2 Feb 2010 07:58:09 +0000 (07:58 +0000)
the context in the full compiler.

Clobber all input registers in the RecordWrite code
when the debug-code flag is set.
Review URL: http://codereview.chromium.org/569008

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

src/arm/full-codegen-arm.cc
src/arm/macro-assembler-arm.cc
src/full-codegen.cc
src/ia32/full-codegen-ia32.cc
src/ia32/macro-assembler-ia32.cc
src/x64/full-codegen-x64.cc
src/x64/macro-assembler-x64.cc

index 386d201ac02a088f2ef7be0836ce539c3db15645..9f240dd82c9b211e316b3f32bfb46f0a18efc997 100644 (file)
@@ -95,8 +95,14 @@ void FullCodeGenerator::Generate(FunctionLiteral* fun, Mode mode) {
                                    (num_parameters - 1 - i) * kPointerSize;
           // Load parameter from stack.
           __ ldr(r0, MemOperand(fp, parameter_offset));
-          // Store it in the context
-          __ str(r0, MemOperand(cp, Context::SlotOffset(slot->index())));
+          // Store it in the context.
+          __ mov(r1, Operand(Context::SlotOffset(slot->index())));
+          __ str(r0, MemOperand(cp, r1));
+          // Update the write barrier. This clobbers all involved
+          // registers, so we have use a third register to avoid
+          // clobbering cp.
+          __ mov(r2, Operand(cp));
+          __ RecordWrite(r2, r1, r0);
         }
       }
     }
@@ -113,7 +119,7 @@ void FullCodeGenerator::Generate(FunctionLiteral* fun, Mode mode) {
       }
       // Receiver is just before the parameters on the caller's stack.
       __ add(r2, fp, Operand(StandardFrameConstants::kCallerSPOffset +
-                                 fun->num_parameters() * kPointerSize));
+                             fun->num_parameters() * kPointerSize));
       __ mov(r1, Operand(Smi::FromInt(fun->num_parameters())));
       __ stm(db_w, sp, r3.bit() | r2.bit() | r1.bit());
 
index 6cbd6a57f3fe05ed566de43efcdde7106d119647..b39404e7f91a560ee896097853523a4523b95fc1 100644 (file)
@@ -277,6 +277,14 @@ void MacroAssembler::RecordWrite(Register object, Register offset,
   str(scratch, MemOperand(object));
 
   bind(&done);
+
+  // Clobber all input registers when running with the debug-code flag
+  // turned on to provoke errors.
+  if (FLAG_debug_code) {
+    mov(object, Operand(bit_cast<int32_t>(kZapValue)));
+    mov(offset, Operand(bit_cast<int32_t>(kZapValue)));
+    mov(scratch, Operand(bit_cast<int32_t>(kZapValue)));
+  }
 }
 
 
index 4a1a7d37c0ea8aa5c2d9079b5fc7c99873df2eb4..29a445256cb36431c50e75f1a166232d5a2cbf1f 100644 (file)
@@ -54,18 +54,6 @@ namespace internal {
 
 void FullCodeGenSyntaxChecker::Check(FunctionLiteral* fun) {
   Scope* scope = fun->scope();
-
-  if (scope->num_heap_slots() > 0) {
-    // We support functions with a local context if they do not have
-    // parameters that need to be copied into the context.
-    for (int i = 0, len = scope->num_parameters(); i < len; i++) {
-      Slot* slot = scope->parameter(i)->slot();
-      if (slot != NULL && slot->type() == Slot::CONTEXT) {
-        BAILOUT("Function has context-allocated parameters.");
-      }
-    }
-  }
-
   VisitDeclarations(scope->declarations());
   CHECK_BAILOUT;
 
index ba03eafe935d80bd4441f701087458a88361bfc1..9f9ac56cc10c78a6069364996e1015dfd289f0a6 100644 (file)
@@ -95,8 +95,14 @@ void FullCodeGenerator::Generate(FunctionLiteral* fun, Mode mode) {
                                      (num_parameters - 1 - i) * kPointerSize;
           // Load parameter from stack.
           __ mov(eax, Operand(ebp, parameter_offset));
-          // Store it in the context
-          __ mov(Operand(esi, Context::SlotOffset(slot->index())), eax);
+          // Store it in the context.
+          int context_offset = Context::SlotOffset(slot->index());
+          __ mov(Operand(esi, context_offset), eax);
+          // Update the write barrier. This clobbers all involved
+          // registers, so we have use a third register to avoid
+          // clobbering esi.
+          __ mov(ecx, esi);
+          __ RecordWrite(ecx, context_offset, eax, ebx);
         }
       }
     }
@@ -112,7 +118,7 @@ void FullCodeGenerator::Generate(FunctionLiteral* fun, Mode mode) {
       }
       // Receiver is just before the parameters on the caller's stack.
       __ lea(edx, Operand(ebp, StandardFrameConstants::kCallerSPOffset +
-                                   fun->num_parameters() * kPointerSize));
+                          fun->num_parameters() * kPointerSize));
       __ push(edx);
       __ push(Immediate(Smi::FromInt(fun->num_parameters())));
       // Arguments to ArgumentsAccessStub:
index 07622bba186bdd6074e75fee3595ce6c0d4e0a7a..19a380b029bd8055a5db70b68b52be382b35e4f1 100644 (file)
@@ -215,6 +215,14 @@ void MacroAssembler::RecordWrite(Register object, int offset,
   }
 
   bind(&done);
+
+  // Clobber all input registers when running with the debug-code flag
+  // turned on to provoke errors.
+  if (FLAG_debug_code) {
+    mov(object, Immediate(bit_cast<int32_t>(kZapValue)));
+    mov(value, Immediate(bit_cast<int32_t>(kZapValue)));
+    mov(scratch, Immediate(bit_cast<int32_t>(kZapValue)));
+  }
 }
 
 
index 60069bdde03dbc41c961c35d01583e8009bf0f51..688bfba7c86ad08790188c847d456b369f406fc9 100644 (file)
@@ -95,8 +95,14 @@ void FullCodeGenerator::Generate(FunctionLiteral* fun, Mode mode) {
                                      (num_parameters - 1 - i) * kPointerSize;
           // Load parameter from stack.
           __ movq(rax, Operand(rbp, parameter_offset));
-          // Store it in the context
-          __ movq(Operand(rsi, Context::SlotOffset(slot->index())), rax);
+          // Store it in the context.
+          int context_offset = Context::SlotOffset(slot->index());
+          __ movq(Operand(rsi, context_offset), rax);
+          // Update the write barrier. This clobbers all involved
+          // registers, so we have use a third register to avoid
+          // clobbering rsi.
+          __ movq(rcx, rsi);
+          __ RecordWrite(rcx, context_offset, rax, rbx);
         }
       }
     }
@@ -114,7 +120,7 @@ void FullCodeGenerator::Generate(FunctionLiteral* fun, Mode mode) {
       }
       // The receiver is just before the parameters on the caller's stack.
       __ lea(rdx, Operand(rbp, StandardFrameConstants::kCallerSPOffset +
-                                   fun->num_parameters() * kPointerSize));
+                          fun->num_parameters() * kPointerSize));
       __ push(rdx);
       __ Push(Smi::FromInt(fun->num_parameters()));
       // Arguments to ArgumentsAccessStub:
index 0bb8118532a50528d2f7d1306c8a4ec8684f862a..96b45e8427f2b33c6b9663bfa3bbe7626c02b13c 100644 (file)
@@ -191,6 +191,17 @@ void MacroAssembler::RecordWrite(Register object,
 
   RecordWriteNonSmi(object, offset, value, smi_index);
   bind(&done);
+
+  // Clobber all input registers when running with the debug-code flag
+  // turned on to provoke errors. This clobbering repeats the
+  // clobbering done inside RecordWriteNonSmi but it's necessary to
+  // avoid having the fast case for smis leave the registers
+  // unchanged.
+  if (FLAG_debug_code) {
+    movq(object, bit_cast<int64_t>(kZapValue), RelocInfo::NONE);
+    movq(value, bit_cast<int64_t>(kZapValue), RelocInfo::NONE);
+    movq(smi_index, bit_cast<int64_t>(kZapValue), RelocInfo::NONE);
+  }
 }
 
 
@@ -199,6 +210,14 @@ void MacroAssembler::RecordWriteNonSmi(Register object,
                                        Register scratch,
                                        Register smi_index) {
   Label done;
+
+  if (FLAG_debug_code) {
+    Label okay;
+    JumpIfNotSmi(object, &okay);
+    Abort("MacroAssembler::RecordWriteNonSmi cannot deal with smis");
+    bind(&okay);
+  }
+
   // Test that the object address is not in the new space.  We cannot
   // set remembered set bits in the new space.
   movq(scratch, object);
@@ -248,6 +267,14 @@ void MacroAssembler::RecordWriteNonSmi(Register object,
   }
 
   bind(&done);
+
+  // Clobber all input registers when running with the debug-code flag
+  // turned on to provoke errors.
+  if (FLAG_debug_code) {
+    movq(object, bit_cast<int64_t>(kZapValue), RelocInfo::NONE);
+    movq(scratch, bit_cast<int64_t>(kZapValue), RelocInfo::NONE);
+    movq(smi_index, bit_cast<int64_t>(kZapValue), RelocInfo::NONE);
+  }
 }